* Re: [PATCH 2/8] param: use ops in struct kernel_param, rather than get and set fns directly
From: Takashi Iwai @ 2009-11-01 10:26 UTC (permalink / raw)
To: Rusty Russell
Cc: linux-kernel, David S. Miller, Ville Syrjala, Dmitry Torokhov,
Alessandro Rubini, Michal Januszewski, Trond Myklebust,
J. Bruce Fields, Neil Brown, linux-input, linux-fbdev-devel,
linux-nfs, netdev
In-Reply-To: <200910302143.40268.rusty@rustcorp.com.au>
At Fri, 30 Oct 2009 21:43:39 +1030,
Rusty Russell wrote:
>
> On Fri, 30 Oct 2009 08:48:12 pm Takashi Iwai wrote:
> > At Fri, 23 Oct 2009 00:51:28 +1030,
> > Rusty Russell wrote:
> > >
> > > This is more kernel-ish, saves some space, and also allows us to
> > > expand the ops without breaking all the callers who are happy for the
> > > new members to be NULL.
> > >
> > > The few places which defined their own param types are changed to the
> > > new scheme.
> > >
> > > Since we're touching them anyway, we change get and set to take a
> > > const struct kernel_param (which they were, and will be again).
> > >
> > > To reduce churn, module_param_call creates the ops struct so the callers
> > > don't have to change (and casts the functions to reduce warnings).
> > > The modern version which takes an ops struct is called module_param_cb.
> >
> > This is nice, as it also reduces the size of struct kernel_param, so
> > each parameter uses less footprint (who cares, though?) :)
> >
> > But, just wondering whether we still need to export get/set
> > functions. They can be called from ops now, so if any, it can be
> > defined even as an inlinefunction or a macro.
>
> My thought too, so I tried that, but many are still used like so:
>
> module_param_call(foo, set_foo, param_get_uint, NULL, 0644);
>
> They can all be replaced in time with something like:
> static int param_get_foo(char *buffer, const struct kernel_param *kp)
> {
> return param_ops_uint.get(buffer, kp);
> }
>
> But it'll take a transition period.
Fair enough. And, maybe these get/set should be defined as an ops
explicitly so that it can be used for multiple parameters. But we
can do cleanups later, of course :)
Oh, in case you need,
Reviewed-by: Takashi Iwai <tiwai@suse.de>
for all new patches.
Thanks!
Takashi
^ permalink raw reply
* Re: [net-next-2.6 PATCH RFC] TCPCT part 1d: generate Responder Cookie
From: William Allen Simpson @ 2009-11-01 13:01 UTC (permalink / raw)
To: Linux Kernel Developers; +Cc: Linux Kernel Network Developers
In-Reply-To: <4AEAC763.4070200@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]
Since October 4th, I've repeatedly asked publicly for assistance with these
Linux-specific memory locking constructs and cryptography. I've also sent
private messages. No help has been forthcoming. None. Nada.
At this point, I've spent weeks re-spinning code that I'd understood was
approved a year ago. The whole project should have been finished by now!
So, I'll try a larger audience. Could somebody take a look at my usage of
read and write locking?
NB, I'm trying to port some 15-year-old fairly simple and straightforward
(single cpu) code from the KA9Q cooperative multitasking platform.
I've examined existing code used for syncookies and TCP MD5 authenticators.
Neither meets my needs, as this secret is updated every few minutes. Both
have very different approaches. They are rarely used. My code will be
used on the order of tens of thousands of connections per second.
Moreover, it seems to my naive eye that the syncookie per cpu code simply
doesn't work properly. The workspace is allocated per cpu, but the cpu
could change during the extensive SHA1 computations. Bug?
Therefore, I'm approaching this as simply as possible. I'm particularly
concerned about the initialization and cache state of memory pointers.
Does the locking handle this? Or is there more to be done?
[-- Attachment #2: TCPCT+1d.patch --]
[-- Type: text/plain, Size: 7050 bytes --]
diff --git a/include/linux/cryptohash.h b/include/linux/cryptohash.h
index c118b2a..ec78a4b 100644
--- a/include/linux/cryptohash.h
+++ b/include/linux/cryptohash.h
@@ -2,6 +2,7 @@
#define __CRYPTOHASH_H
#define SHA_DIGEST_WORDS 5
+#define SHA_MESSAGE_BYTES (512 /*bits*/ / 8)
#define SHA_WORKSPACE_WORDS 80
void sha_init(__u32 *buf);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 51b7426..f669c43 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1526,12 +1526,18 @@ static inline int tcp_s_data_size(const struct tcp_sock *tp)
: 0;
}
+/* Using SHA1 for now, define some constants.
+ */
+#define COOKIE_DIGEST_WORDS (SHA_DIGEST_WORDS)
+#define COOKIE_MESSAGE_WORDS (SHA_MESSAGE_BYTES / 4)
+#define COOKIE_WORKSPACE_WORDS (COOKIE_DIGEST_WORDS + COOKIE_MESSAGE_WORDS)
+
/* As tcp_request_sock has already been extended in other places, the
* only remaining method is to pass stack values along as function
* parameters. These parameters are not needed after sending SYNACK.
*/
struct tcp_extend_values {
- u8 cookie_bakery[TCP_COOKIE_MAX];
+ u32 cookie_bakery[COOKIE_WORKSPACE_WORDS];
u8 cookie_plus;
u8 cookie_in_always:1,
cookie_out_never:1;
@@ -1542,6 +1548,8 @@ static inline struct tcp_extend_values *tcp_xv(const struct request_values *rvp)
return (struct tcp_extend_values *)rvp;
}
+extern int tcp_cookie_generator(struct tcp_extend_values *xvp);
+
extern void tcp_v4_init(void);
extern void tcp_init(void);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 12409df..160b077 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -264,6 +264,7 @@
#include <linux/cache.h>
#include <linux/err.h>
#include <linux/crypto.h>
+#include <linux/time.h>
#include <net/icmp.h>
#include <net/tcp.h>
@@ -2933,6 +2934,146 @@ EXPORT_SYMBOL(tcp_md5_hash_key);
#endif
+/**
+ * Each Responder maintains up to two secret values concurrently for
+ * efficient secret rollover. Each secret value has 4 states:
+ *
+ * Generating.
+ * Generates new Responder-Cookies, but not yet used for primary
+ * verification. This is a short-term state, typically lasting only
+ * one round trip time (RTT).
+ *
+ * Primary.
+ * Used both for generation and primary verification.
+ *
+ * Retiring.
+ * Used for verification, until the first failure that can be
+ * verified by the newer Generating secret. At that time, this
+ * cookie's state is changed to Secondary, and the Generating
+ * cookie's state is changed to Primary. This is a short-term state,
+ * typically lasting only one round trip time (RTT).
+ *
+ * Secondary.
+ * Used for secondary verification, after primary verification
+ * failures. This state lasts no more than twice the Maximum Segment
+ * Lifetime (2MSL). Then, the secret is discarded.
+ */
+struct tcp_cookie_secret {
+ /* The secret is divided into two parts. The digest part is the
+ * equivalent of previously hashing a secret and saving the state,
+ * and serves as an initialization vector (IV). The message part
+ * serves as the trailing secret.
+ */
+ u32 secrets[COOKIE_WORKSPACE_WORDS];
+ unsigned long expires;
+};
+
+#define TCP_SECRET_1MSL (HZ * TCP_PAWS_MSL)
+#define TCP_SECRET_2MSL (HZ * TCP_PAWS_MSL * 2)
+#define TCP_SECRET_LIFE (HZ * 600)
+
+static struct tcp_cookie_secret tcp_secret_one;
+static struct tcp_cookie_secret tcp_secret_two;
+
+static struct tcp_cookie_secret *tcp_secret_generating;
+static struct tcp_cookie_secret *tcp_secret_primary;
+static struct tcp_cookie_secret *tcp_secret_retiring;
+static struct tcp_cookie_secret *tcp_secret_secondary;
+
+static DEFINE_RWLOCK(tcp_secret_locker);
+
+/* Fill cookie_bakery with current generator, updating as needed.
+ * Returns: 0 for success.
+ */
+int tcp_cookie_generator(struct tcp_extend_values *xvp)
+{
+ u32 secrets[COOKIE_WORKSPACE_WORDS];
+ unsigned long jiffy = jiffies;
+
+ if (unlikely(NULL == tcp_secret_primary)) {
+ struct timespec tv;
+
+ getnstimeofday(&tv);
+ get_random_bytes(secrets, sizeof(secrets));
+
+ /* The first time, paranoia assumes that the randomization
+ * function isn't as strong. But this secret initialization
+ * is delayed until the last possible moment (packet arrival).
+ * Although that time is observable, it is unpredictably
+ * variable. Mash in the most volatile clock bits available,
+ * and expire the secret extra quickly.
+ */
+ secrets[COOKIE_DIGEST_WORDS+0] ^= (u32)tv.tv_nsec;
+
+ write_lock(&tcp_secret_locker);
+ if (NULL != tcp_secret_primary) {
+ /* initializated by another */
+ memcpy(&xvp->cookie_bakery[0],
+ &tcp_secret_primary->secrets[0],
+ sizeof(tcp_secret_primary->secrets));
+ } else {
+ /* still needs initialization */
+ memcpy(&xvp->cookie_bakery[0],
+ &secrets[0],
+ sizeof(secrets));
+ memcpy(&tcp_secret_one.secrets[0],
+ &secrets[0],
+ sizeof(secrets));
+ memcpy(&tcp_secret_two.secrets[0],
+ &secrets[0],
+ sizeof(secrets));
+
+ tcp_secret_one.expires = jiffy + TCP_SECRET_1MSL;
+ tcp_secret_primary = &tcp_secret_one;
+
+ tcp_secret_two.expires = 0; /* past due */
+ tcp_secret_secondary = &tcp_secret_two;
+ }
+ write_unlock(&tcp_secret_locker);
+ } else if (unlikely(time_after(jiffy, tcp_secret_primary->expires))) {
+ get_random_bytes(secrets, sizeof(secrets));
+
+ write_lock(&tcp_secret_locker);
+ if (!time_after(jiffy, tcp_secret_primary->expires)) {
+ /* refreshed by another */
+ memcpy(&xvp->cookie_bakery[0],
+ &tcp_secret_generating->secrets[0],
+ sizeof(tcp_secret_generating->secrets));
+ } else {
+ /* still needs refreshing */
+ memcpy(&xvp->cookie_bakery[0],
+ &secrets[0],
+ sizeof(secrets));
+ memcpy(&tcp_secret_secondary->secrets[0],
+ &secrets[0],
+ sizeof(secrets));
+
+ tcp_secret_secondary->expires = jiffy
+ + TCP_SECRET_LIFE;
+ tcp_secret_generating = tcp_secret_secondary;
+
+ tcp_secret_primary->expires = jiffy
+ + TCP_SECRET_2MSL;
+ tcp_secret_retiring = tcp_secret_primary;
+ }
+ write_unlock(&tcp_secret_locker);
+ } else {
+ read_lock(&tcp_secret_locker);
+ if (unlikely(NULL != tcp_secret_generating)) {
+ memcpy(&xvp->cookie_bakery[0],
+ &tcp_secret_generating->secrets[0],
+ sizeof(tcp_secret_generating->secrets));
+ } else {
+ memcpy(&xvp->cookie_bakery[0],
+ &tcp_secret_primary->secrets[0],
+ sizeof(tcp_secret_primary->secrets));
+ }
+ read_unlock(&tcp_secret_locker);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(tcp_cookie_generator);
+
void tcp_done(struct sock *sk)
{
if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
@@ -3060,6 +3201,11 @@ void __init tcp_init(void)
tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);
tcp_register_congestion_control(&tcp_reno);
+
+ tcp_secret_generating = NULL;
+ tcp_secret_primary = NULL;
+ tcp_secret_retiring = NULL;
+ tcp_secret_secondary = NULL;
}
EXPORT_SYMBOL(tcp_close);
^ permalink raw reply related
* Re: [RFC] multiqueue changes
From: Jarek Poplawski @ 2009-11-01 13:20 UTC (permalink / raw)
To: Michael Chan
Cc: Patrick McHardy, Eric Dumazet, David S. Miller, Linux Netdev List
In-Reply-To: <1257009952.9706.30.camel@HP1>
On Sat, Oct 31, 2009 at 10:25:52AM -0700, Michael Chan wrote:
>
> On Fri, 2009-10-30 at 03:00 -0700, Jarek Poplawski wrote:
> > On Thu, Oct 29, 2009 at 11:12:39PM +0100, Patrick McHardy wrote:
...
> > > I currently can't see any purpose in decreasing num_tx_queues after
> > > registration instead of real_num_tx_queues.
> >
> > I agree, but since Eric's example shows some drivers do it (almost)
> > like this, I'd prefer authors/maintainers answer this question.
> >
>
> We need the netdev and the private structure at the beginning of
> ->probe() to store values as we probe the device. Later on in
> ->probe(), we'll know whether the device supports MSI-X and multiqueue.
> If we successfully enable MSI-X in ->ndo_open(), tx multiqueue will be
> used.
>
> So if we can separate the allocation of the netdev and the private
> structure from the tx queues, we can allocate and set the exact number
> of num_tx_queues in ->ndo_open().
There is a question if we can predict in ->probe() MSI-X should be
successfully enabled in ->ndo_open() for probed hardware. If so,
then it could go e.g. like this:
->probe()
...
dev = alloc_etherdev_mq(sizeof(*bp), 1)
...
if (MSI-X_available && device_supports_MSI-X_and_multiqueue)
realloc_netdev_mq(dev, TX_MAX_RINGS)
register_netdev(dev)
->ndo_open()
if (!enabled_MSI-X)
/* something gone wrong but it's an exception */
dev->real_num_tx_queues = 1
Otherwise, (re)allocation in ->ndo_open() would need to answer some
questions about reinitializing scheduler vs preserving qdisc stats
between opens.
Jarek P.
^ permalink raw reply
* Re: [PATCH] r8169: partial support and phy init for the 8168d
From: Ben Hutchings @ 2009-11-01 16:24 UTC (permalink / raw)
To: Francois Romieu; +Cc: David S. Miller, netdev, Edward Hsu
In-Reply-To: <20091007224420.GA20170@electric-eye.fr.zoreil.com>
[-- Attachment #1: Type: text/plain, Size: 1226 bytes --]
On Thu, 2009-10-08 at 00:44 +0200, Francois Romieu wrote:
> Extracted from Realtek's 8.012.00 r8168 driver.
There is a problem with this change:
[...]
> static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
> {
[...]
> + static struct phy_reg phy_reg_init_2[] = {
> + { 0x1f, 0x0005 },
> + { 0x05, 0xffc2 },
> + { 0x1f, 0x0005 },
I interpret the following sequence of register writes as:
> + { 0x05, 0x8000 },
> + { 0x06, 0xf8f9 },
> + { 0x06, 0xfaef },
> + { 0x06, 0x59ee },
[...]
Write memory sequentially from 0x8000,
> + { 0x05, 0x83d4 },
> + { 0x06, 0x8000 },
> + { 0x05, 0x83d8 },
> + { 0x06, 0x8051 },
[...]
Change two vectors to point into what was just written.
I believe this is patching machine code in the PHY. And we do not have
source for that code, so it cannot possibly be distributed under GPL.
Please replace this with use of request_firmware() and submit the blob
to linux-firmware.git instead.
The same goes for phy_reg_init_1 in rtl8168d_2_hw_phy_config().
Ben.
--
Ben Hutchings
The generation of random numbers is too important to be left to chance.
- Robert Coveyou
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* [PATCH 1/3] sysfs directory scaling: rbtree for dirent name lookups
From: Benjamin LaHaise @ 2009-11-01 16:31 UTC (permalink / raw)
To: Eric Dumazet, Greg Kroah-Hartman
Cc: Eric W. Biederman, Octavian Purdila, netdev, Cosmin Ratiu,
linux-kernel
Use an rbtree in sysfs_dirent to speed up file lookup times
Systems with large numbers (tens of thousands and more) of network
interfaces stress the sysfs code in ways that make the linear search for
a name match take far too long. Avoid this by using an rbtree.
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 5fad489..30c3fc5 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -44,6 +44,7 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
{
struct sysfs_dirent *parent_sd = sd->s_parent;
struct sysfs_dirent **pos;
+ struct rb_node **new, *parent;
BUG_ON(sd->s_sibling);
@@ -57,6 +58,27 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
}
sd->s_sibling = *pos;
*pos = sd;
+
+ // rb tree insert
+ new = &(parent_sd->s_dir.child_rb_root.rb_node);
+ parent = NULL;
+
+ while (*new) {
+ struct sysfs_dirent *this =
+ container_of(*new, struct sysfs_dirent, s_rb_node);
+ int result = strcmp(sd->s_name, this->s_name);
+
+ parent = *new;
+ if (result < 0)
+ new = &((*new)->rb_left);
+ else if (result > 0)
+ new = &((*new)->rb_right);
+ else
+ BUG();
+ }
+
+ rb_link_node(&sd->s_rb_node, parent, new);
+ rb_insert_color(&sd->s_rb_node, &parent_sd->s_dir.child_rb_root);
}
/**
@@ -81,6 +103,8 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
break;
}
}
+
+ rb_erase(&sd->s_rb_node, &sd->s_parent->s_dir.child_rb_root);
}
/**
@@ -331,6 +355,9 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
sd->s_mode = mode;
sd->s_flags = type;
+ if (type == SYSFS_DIR)
+ sd->s_dir.child_rb_root = RB_ROOT;
+
return sd;
err_out2:
@@ -630,11 +657,20 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
const unsigned char *name)
{
- struct sysfs_dirent *sd;
-
- for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling)
- if (!strcmp(sd->s_name, name))
- return sd;
+ struct rb_node *node = parent_sd->s_dir.child_rb_root.rb_node;
+
+ while (node) {
+ struct sysfs_dirent *data =
+ container_of(node, struct sysfs_dirent, s_rb_node);
+ int result;
+ result = strcmp(name, data->s_name);
+ if (result < 0)
+ node = node->rb_left;
+ else if (result > 0)
+ node = node->rb_right;
+ else
+ return data;
+ }
return NULL;
}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index af4c4e7..600109c 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -9,6 +9,7 @@
*/
#include <linux/fs.h>
+#include <linux/rbtree.h>
struct sysfs_open_dirent;
@@ -17,6 +18,7 @@ struct sysfs_elem_dir {
struct kobject *kobj;
/* children list starts here and goes through sd->s_sibling */
struct sysfs_dirent *children;
+ struct rb_root child_rb_root;
};
struct sysfs_elem_symlink {
@@ -52,6 +54,7 @@ struct sysfs_dirent {
atomic_t s_active;
struct sysfs_dirent *s_parent;
struct sysfs_dirent *s_sibling;
+ struct rb_node s_rb_node;
const char *s_name;
union {
^ permalink raw reply related
* [PATCH 2/3] sysfs directory scaling: doubly linked list for dirents
From: Benjamin LaHaise @ 2009-11-01 16:32 UTC (permalink / raw)
To: Eric Dumazet, Greg Kroah-Hartman
Cc: Eric W. Biederman, Octavian Purdila, netdev, Cosmin Ratiu,
linux-kernel
In-Reply-To: <20091101163130.GA7911@kvack.org>
When adding/removing large numbers of entries from sysfs directories, one
hot spot is in the link and unlink operations of sysfs. When linking a
new sysfs_dirent into the tree, operation can be significantly sped up by
starting at the end of the list rather than the beginning. Unlink is
improved by using a doubly linked list.
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
diff -u b/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- b/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -43,11 +43,18 @@
static void sysfs_link_sibling(struct sysfs_dirent *sd)
{
struct sysfs_dirent *parent_sd = sd->s_parent;
- struct sysfs_dirent **pos;
+ struct sysfs_dirent **pos, *prev = NULL;
struct rb_node **new, *parent;
BUG_ON(sd->s_sibling);
+ if (parent_sd->s_dir.children_tail &&
+ parent_sd->s_dir.children_tail->s_ino < sd->s_ino) {
+ prev = parent_sd->s_dir.children_tail;
+ pos = &prev->s_sibling;
+ goto got_it;
+ }
+
/* Store directory entries in order by ino. This allows
* readdir to properly restart without having to add a
* cursor into the s_dir.children list.
@@ -55,8 +62,13 @@
for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) {
if (sd->s_ino < (*pos)->s_ino)
break;
+ prev = *pos;
}
+got_it:
+ if (prev == parent_sd->s_dir.children_tail)
+ parent_sd->s_dir.children_tail = sd;
sd->s_sibling = *pos;
+ sd->s_sibling_prev = prev;
*pos = sd;
// rb tree insert
@@ -93,17 +105,20 @@
*/
static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
{
- struct sysfs_dirent **pos;
-
- for (pos = &sd->s_parent->s_dir.children; *pos;
- pos = &(*pos)->s_sibling) {
- if (*pos == sd) {
- *pos = sd->s_sibling;
- sd->s_sibling = NULL;
- break;
- }
- }
+ struct sysfs_dirent **pos, *prev = NULL;
+ prev = sd->s_sibling_prev;
+ if (prev)
+ pos = &prev->s_sibling;
+ else
+ pos = &sd->s_parent->s_dir.children;
+ if (sd == sd->s_parent->s_dir.children_tail)
+ sd->s_parent->s_dir.children_tail = prev;
+ *pos = sd->s_sibling;
+ if (sd->s_sibling)
+ sd->s_sibling->s_sibling_prev = prev;
+
+ sd->s_sibling_prev = NULL;
rb_erase(&sd->s_rb_node, &sd->s_parent->s_dir.child_rb_root);
}
diff -u b/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- b/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -17,7 +17,9 @@
struct sysfs_elem_dir {
struct kobject *kobj;
/* children list starts here and goes through sd->s_sibling */
+
struct sysfs_dirent *children;
+ struct sysfs_dirent *children_tail;
struct rb_root child_rb_root;
};
@@ -54,6 +56,7 @@
atomic_t s_active;
struct sysfs_dirent *s_parent;
struct sysfs_dirent *s_sibling;
+ struct sysfs_dirent *s_sibling_prev;
struct rb_node s_rb_node;
const char *s_name;
^ permalink raw reply
* [PATCH 2/3] sysfs directory scaling: count number of children dirs
From: Benjamin LaHaise @ 2009-11-01 16:33 UTC (permalink / raw)
To: Eric Dumazet, Greg Kroah-Hartman
Cc: Eric W. Biederman, Octavian Purdila, netdev, Cosmin Ratiu,
linux-kernel
In-Reply-To: <20091101163230.GB7911@kvack.org>
sysfs_count_nlink() is a bottleneck during mass bring up of network
interfaces. Eliminate this problem by tracking the number of directories.
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
diff -u b/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- b/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -70,6 +70,7 @@
sd->s_sibling = *pos;
sd->s_sibling_prev = prev;
*pos = sd;
+ parent_sd->s_nr_children_dir += (sysfs_type(sd) == SYSFS_DIR);
// rb tree insert
new = &(parent_sd->s_dir.child_rb_root.rb_node);
@@ -118,6 +119,7 @@
if (sd->s_sibling)
sd->s_sibling->s_sibling_prev = prev;
+ sd->s_parent->s_nr_children_dir -= (sysfs_type(sd) == SYSFS_DIR);
sd->s_sibling_prev = NULL;
rb_erase(&sd->s_rb_node, &sd->s_parent->s_dir.child_rb_root);
}
diff -u b/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- b/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -71,6 +71,8 @@
ino_t s_ino;
umode_t s_mode;
struct sysfs_inode_attrs *s_iattr;
+
+ int s_nr_children_dir;
};
#define SD_DEACTIVATED_BIAS INT_MIN
only in patch2:
unchanged:
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -191,14 +191,7 @@ static struct lock_class_key sysfs_inode_imutex_key;
static int sysfs_count_nlink(struct sysfs_dirent *sd)
{
- struct sysfs_dirent *child;
- int nr = 0;
-
- for (child = sd->s_dir.children; child; child = child->s_sibling)
- if (sysfs_type(child) == SYSFS_DIR)
- nr++;
-
- return nr + 2;
+ return sd->s_nr_children_dir + 2;
}
static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
^ permalink raw reply
* Re: [PATCH net-next-2.6] Driver for the Microchip MCP251x SPI CAN controllers
From: Paul Thomas @ 2009-11-01 16:40 UTC (permalink / raw)
To: Wolfgang Grandegger
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Christian Pellegrin, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4AED5589.3090106-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Yes, I will be testing ready to work on this hopefully on Monday or
Tuesday. Is this the correct git tree to patch against?
http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=summary
Should I just pull the latest?
thanks,
Paul
^ permalink raw reply
* Re: [PATCH net-next-2.6] Driver for the Microchip MCP251x SPI CAN controllers
From: Wolfgang Grandegger @ 2009-11-01 16:44 UTC (permalink / raw)
To: Paul Thomas
Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
Christian Pellegrin, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <c785bba30911010840m2ad73abawf8434f42337a26d3-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Paul Thomas wrote:
> Yes, I will be testing ready to work on this hopefully on Monday or
> Tuesday. Is this the correct git tree to patch against?
> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=summary
Yes:
git clone \
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
> Should I just pull the latest?
Yes.
Wolfgang.
^ permalink raw reply
* Re: [net-next-2.6 PATCH RFC] TCPCT part 1d: generate Responder Cookie
From: Eric Dumazet @ 2009-11-01 18:03 UTC (permalink / raw)
To: William Allen Simpson
Cc: Linux Kernel Developers, Linux Kernel Network Developers
In-Reply-To: <4AED86AD.6010906@gmail.com>
William Allen Simpson a écrit :
> Since October 4th, I've repeatedly asked publicly for assistance with these
> Linux-specific memory locking constructs and cryptography. I've also sent
> private messages. No help has been forthcoming. None. Nada.
>
> At this point, I've spent weeks re-spinning code that I'd understood was
> approved a year ago. The whole project should have been finished by now!
Your messages on netdev are two weeks old, not one year, and came during
LKS. Many developpers were busy in Japan.
>
> So, I'll try a larger audience. Could somebody take a look at my usage of
> read and write locking?
>
> NB, I'm trying to port some 15-year-old fairly simple and straightforward
> (single cpu) code from the KA9Q cooperative multitasking platform.
>
> I've examined existing code used for syncookies and TCP MD5 authenticators.
> Neither meets my needs, as this secret is updated every few minutes. Both
> have very different approaches. They are rarely used. My code will be
> used on the order of tens of thousands of connections per second.
>
> Moreover, it seems to my naive eye that the syncookie per cpu code simply
> doesn't work properly. The workspace is allocated per cpu, but the cpu
> could change during the extensive SHA1 computations. Bug?
>
> Therefore, I'm approaching this as simply as possible. I'm particularly
> concerned about the initialization and cache state of memory pointers.
>
> Does the locking handle this? Or is there more to be done?
>
This patch looks fine, but I dont see how this new function is used.
Some points :
1) We are working hard to remove rwlocks from network stack, so please dont
add a new one. You probably can use a seqlock or RCU, or a server handling
10.000 connections request per second on many NIC will hit this rwlock.
2)
} else if (unlikely(time_after(jiffy, tcp_secret_primary->expires))) {
get_random_bytes(secrets, sizeof(secrets));
write_lock(&tcp_secret_locker);
It would be better to first get the lock, then get random_bytes, in order
not wasting entropy.
3) If you change secret ever 600 seconds, it might be better to use a timer
so that you dont have to check expiration and this logic at each SYN packet.
(Disociate the lookup (read-only, done many time per second) from the updates
(trigerred by a timer every 600 secs))
(Not counting you'll probably need to use a similar lookup algo for the ACK
packet coming from client)
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Bartlomiej Zolnierkiewicz @ 2009-11-01 19:04 UTC (permalink / raw)
To: John W. Linville
Cc: Jarek Poplawski, Johannes Berg, Pekka Enberg, David Miller,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20091030150223.GA2586-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
On Friday 30 October 2009 16:02:24 John W. Linville wrote:
> Ever since Bartlomiej decided to tear himself away from
> drivers/staging, he has been nothing but negative -- petty, whining,
I think that you should ping Greg about this since somebody impersonating
for me is sending him patches. Last week alone over 20 such patches were
merged -- who knows what this person might be planning.. ;)
Probably the following patch was the source of confusion:
http://patchwork.kernel.org/patch/55076/
It just aligns my personal interests w/ ongoing work done by other people,
hch is working on mac80211 via driver and Greg has announced some time ago
that he was going to work on proper rtl819x support.
--
Bartlomiej Zolnierkiewicz
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [net-next-2.6 PATCH v4 1/3] TCPCT part 1a: add request_values parameter for sending SYNACK
From: Eric Dumazet @ 2009-11-01 19:13 UTC (permalink / raw)
To: William Allen Simpson; +Cc: Linux Kernel Network Developers
In-Reply-To: <4AE6E474.9060704@gmail.com>
William Allen Simpson a écrit :
> Add optional function parameters associated with sending SYNACK.
> These parameters are not needed after sending SYNACK, and are not
> used for retransmission. Avoids extending struct tcp_request_sock,
> and avoids allocating kernel memory.
>
> Also affects DCCP as it uses common struct request_sock_ops,
> but this parameter is currently reserved for future use.
>
> Signed-off-by: William.Allen.Simpson@gmail.com
> ---
> include/net/request_sock.h | 8 +++++++-
> include/net/tcp.h | 1 +
> net/dccp/ipv4.c | 5 +++--
> net/dccp/ipv6.c | 5 +++--
> net/dccp/minisocks.c | 2 +-
> net/ipv4/inet_connection_sock.c | 2 +-
> net/ipv4/tcp_ipv4.c | 11 +++++++----
> net/ipv4/tcp_minisocks.c | 2 +-
> net/ipv4/tcp_output.c | 1 +
> net/ipv6/tcp_ipv6.c | 14 +++++++-------
> 10 files changed, 32 insertions(+), 19 deletions(-)
>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
^ permalink raw reply
* Re: [net-next-2.6 PATCH v4 2/3] TCPCT part 1b: sysctl_tcp_cookie_size, socket option TCP_COOKIE_TRANSACTIONS, functions
From: Eric Dumazet @ 2009-11-01 19:13 UTC (permalink / raw)
To: William Allen Simpson; +Cc: Linux Kernel Network Developers
In-Reply-To: <4AE6E529.706@gmail.com>
William Allen Simpson a écrit :
> Define sysctl (tcp_cookie_size) to turn on and off the cookie option
> default globally, instead of a compiled configuration option.
>
> Define per socket option (TCP_COOKIE_TRANSACTIONS) for setting constant
> data values, retrieving variable cookie values, and other facilities.
>
> Redefine two TCP header functions to accept TCP header pointer.
> When subtracting, return signed int to allow error checking.
>
> Move inline tcp_clear_options() unchanged from net/tcp.h to linux/tcp.h,
> near its corresponding struct tcp_options_received (prior to changes).
>
> This is a straightforward re-implementation of an earlier (year-old)
> patch that no longer applies cleanly, with permission of the original
> author (Adam Langley). The patch was previously reviewed:
>
> http://thread.gmane.org/gmane.linux.network/102586
>
> These functions will also be used in subsequent patches that implement
> additional features.
>
> Signed-off-by: William.Allen.Simpson@gmail.com
> ---
> Documentation/networking/ip-sysctl.txt | 8 +++++
> include/linux/tcp.h | 47
> +++++++++++++++++++++++++++++++-
> include/net/tcp.h | 6 +---
> net/ipv4/sysctl_net_ipv4.c | 8 +++++
> net/ipv4/tcp_output.c | 8 +++++
> 5 files changed, 71 insertions(+), 6 deletions(-)
>
+#define TCP_EXTEND_TIMESTAMP (1 << 4) /* Initiate 64-bit timestamps */
What is this for ?
^ permalink raw reply
* Re: [net-next-2.6 PATCH v4 3/3] TCPCT part 1c: initial SYN exchange with SYNACK data
From: Eric Dumazet @ 2009-11-01 19:19 UTC (permalink / raw)
To: William Allen Simpson; +Cc: Linux Kernel Network Developers
In-Reply-To: <4AE6E7C0.2050408@gmail.com>
William Allen Simpson a écrit :
> This is a significantly revised implementation of an earlier (year-old)
> patch that no longer applies cleanly, with permission of the original
> author (Adam Langley). That patch was previously reviewed:
>
> http://thread.gmane.org/gmane.linux.network/102586
>
> The principle difference is using a TCP option to carry the cookie nonce,
> instead of a user configured offset in the data. This is more flexible and
> less subject to user configuration error. Such a cookie option has been
> suggested for many years, and is also useful without SYN data, allowing
> several related concepts to use the same extension option.
>
> "Re: SYN floods (was: does history repeat itself?)", September 9, 1996.
> http://www.merit.net/mail.archives/nanog/1996-09/msg00235.html
>
> "Re: what a new TCP header might look like", May 12, 1998.
> ftp://ftp.isi.edu/end2end/end2end-interest-1998.mail
>
> Data structures are carefully composed to require minimal additions.
> For example, the struct tcp_options_received cookie_plus variable fits
> between existing 16-bit and 8-bit variables, requiring no additional
> space (taking alignment into consideration). There are no additions to
> tcp_request_sock, and only 1 pointer and 1 flag byte in tcp_sock.
>
> Allocations have been rearranged to avoid requiring GFP_ATOMIC, with
> only one unavoidable exception in tcp_create_openreq_child(), where the
> tcp_sock itself is created GFP_ATOMIC.
>
> These functions will also be used in subsequent patches that implement
> additional features.
>
> Requires:
> TCPCT part 1a: add request_values parameter for sending SYNACK
> TCPCT part 1b: sysctl_tcp_cookie_size, socket option
> TCP_COOKIE_TRANSACTIONS, functions
>
> Signed-off-by: William.Allen.Simpson@gmail.com
> ---
> include/linux/tcp.h | 34 ++++++-
> include/net/tcp.h | 67 +++++++++++++-
> net/ipv4/syncookies.c | 5 +-
> net/ipv4/tcp.c | 128 +++++++++++++++++++++++++-
> net/ipv4/tcp_input.c | 84 +++++++++++++++--
> net/ipv4/tcp_ipv4.c | 62 +++++++++++--
> net/ipv4/tcp_minisocks.c | 43 +++++++--
> net/ipv4/tcp_output.c | 227
> +++++++++++++++++++++++++++++++++++++++++++---
> net/ipv6/syncookies.c | 5 +-
> net/ipv6/tcp_ipv6.c | 47 +++++++++-
> 10 files changed, 639 insertions(+), 63 deletions(-)
>
This part is really hard to review, and might be splitted ?
cleanups could be done in a cleanup patch only
Examples:
- tmp_opt.mss_clamp = 536;
- tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss;
+ tmp_opt.mss_clamp = TCP_MIN_RCVMSS;
+ tmp_opt.user_mss = tp->rx_opt.user_mss;
- tp->mss_cache = 536;
+ tp->mss_cache = TCP_MIN_RCVMSS;
Also your tests are reversed, if you look at the existing coding style.
Example :
+ /* TCP Cookie Transactions */
+ if (0 < sysctl_tcp_cookie_size) {
+ /* Default, cookies without s_data. */
+ tp->cookie_values =
+ kzalloc(sizeof(*tp->cookie_values),
+ sk->sk_allocation);
+ if (NULL != tp->cookie_values)
+ kref_init(&tp->cookie_values->kref);
+ }
should be ->
+ /* TCP Cookie Transactions */
+ if (sysctl_tcp_cookie_size > 0) {
+ /* Default, cookies without s_data. */
+ tp->cookie_values =
+ kzalloc(sizeof(*tp->cookie_values),
+ sk->sk_allocation);
+ if (tp->cookie_values != NULL)
+ kref_init(&tp->cookie_values->kref);
+ }
^ permalink raw reply
* Re: Subject: [PATCH 1/6] bna: Brocade 10Gb Ethernet device driver
From: Stephen Hemminger @ 2009-11-01 19:19 UTC (permalink / raw)
To: Rasesh Mody; +Cc: netdev, adapter_linux_open_src_team
In-Reply-To: <200911010503.nA153Elp019063@blc-10-10.brocade.com>
Too many configuration optons?
On Sat, 31 Oct 2009 22:03:14 -0700
Rasesh Mody <rmody@brocade.com> wrote:
> +
> +#ifdef BNAD_NO_IP_ALIGN
> +#define BNAD_NET_IP_ALIGN 0
> +#else
> +#define BNAD_NET_IP_ALIGN NET_IP_ALIGN
> +#endif
>
Why is this device special?
> +
> +
> +#define BNAD_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2)
> +
Module parameters mean the hardware or the developer could not
decide how to do it right. Please reduce or eliminate most of these.
> +static uint bnad_msix = 1;
> +module_param(bnad_msix, uint, 0444);
> +MODULE_PARM_DESC(bnad_msix, "Enable MSI-X");
If msi-X is available use it, if not then don't. User can handle
this globally with kernel command line option.
> +uint bnad_small_large_rxbufs = 1;
> +module_param(bnad_small_large_rxbufs, uint, 0444);
> +MODULE_PARM_DESC(bnad_small_large_rxbufs, "Enable small/large buffer receive");
Do or do not, please no config option. The ideal case is:
normal MTU == skb
jumbo MTU = skb with fragmenets
> +static uint bnad_rxqsets_used;
> +module_param(bnad_rxqsets_used, uint, 0444);
> +MODULE_PARM_DESC(bnad_rxqsets_used, "Number of RxQ sets to be used");
> +
> +static uint bnad_ipid_mode;
> +module_param(bnad_ipid_mode, uint, 0444);
> +MODULE_PARM_DESC(bnad_ipid_mode, "0 - Use IP ID 0x0000 - 0x7FFF for LSO; "
> + "1 - Use full range of IP ID for LSO");
Gack!
> +uint bnad_txq_depth = BNAD_ENTRIES_PER_TXQ;
> +module_param(bnad_txq_depth, uint, 0444);
> +MODULE_PARM_DESC(bnad_txq_depth, "Maximum number of entries per TxQ");
Should be ethtool configuration not module parameters
> +uint bnad_rxq_depth = BNAD_ENTRIES_PER_RXQ;
> +module_param(bnad_rxq_depth, uint, 0444);
> +MODULE_PARM_DESC(bnad_rxq_depth, "Maximum number of entries per RxQ");
> +
> +static uint bnad_vlan_strip = 1;
> +module_param(bnad_vlan_strip, uint, 0444);
> +MODULE_PARM_DESC(bnad_vlan_strip, "Let the hardware strip off VLAN header");
Just do VLAN acceleration.
> +static uint bnad_log_level = LOG_WARN_LEVEL;
> +module_param(bnad_log_level, uint, 0644);
> +MODULE_PARM_DESC(bnad_log_level, "Log level");
Use ethtool msg_level for this
> +static uint bnad_ioc_auto_recover = 1;
> +module_param(bnad_ioc_auto_recover, uint, 0644);
> +MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable auto recovery");
Why is this configurable?
--
^ permalink raw reply
* Re: Subject: [PATCH 2/6] bna: Brocade 10Gb Ethernet device driver
From: Stephen Hemminger @ 2009-11-01 19:23 UTC (permalink / raw)
To: Rasesh Mody; +Cc: netdev, adapter_linux_open_src_team
In-Reply-To: <200911010503.nA153ESA019066@blc-10-10.brocade.com>
On Sat, 31 Oct 2009 22:03:14 -0700
Rasesh Mody <rmody@brocade.com> wrote:
> +
> +void
> +bfa_timer_init(struct bfa_timer_mod_s *mod)
> +{
> + INIT_LIST_HEAD(&mod->timer_q);
> +}
Why wrap this, you are only calling it once?
> +void
> +bfa_timer_beat(struct bfa_timer_mod_s *mod)
> +{
> + struct list_head *qh = &mod->timer_q;
> + struct list_head *qe, *qe_next;
> + struct bfa_timer_s *elem;
> + struct list_head timedout_q;
> +
> + INIT_LIST_HEAD(&timedout_q);
> +
> + qe = bfa_q_next(qh);
> +
> + while (qe != qh) {
> + qe_next = bfa_q_next(qe);
> +
> + elem = (struct bfa_timer_s *) qe;
> + if (elem->timeout <= BFA_TIMER_FREQ) {
> + elem->timeout = 0;
> + list_del(&elem->qe);
> + list_add_tail(&elem->qe, &timedout_q);
> + } else {
> + elem->timeout -= BFA_TIMER_FREQ;
> + }
> +
> + qe = qe_next; /* go to next elem */
> + }
Why not make list_for_each_entry()?
> + /*
> + * Pop all the timeout entries
> + */
> + while (!list_empty(&timedout_q)) {
> + bfa_q_deq(&timedout_q, &elem);
> + elem->timercb(elem->arg);
> + }
> +}
> +
> +/**
> + * Should be called with lock protection
> + */
> +void
> +bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
> + void (*timercb) (void *), void *arg, unsigned int timeout)
> +{
> +
> + bfa_assert(timercb != NULL);
> + bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer));
> +
> + timer->timeout = timeout;
> + timer->timercb = timercb;
> + timer->arg = arg;
> +
> + list_add_tail(&timer->qe, &mod->timer_q);
> +}
Isn't this the same as timer_setup()?
> +/**
> + * Should be called with lock protection
> + */
> +void
> +bfa_timer_stop(struct bfa_timer_s *timer)
> +{
> + bfa_assert(!list_empty(&timer->qe));
> +
> + list_del(&timer->qe);
> +}
Gratuitous wrapping?
--
^ permalink raw reply
* Re: Subject: [PATCH 2/6] bna: Brocade 10Gb Ethernet device driver
From: Stephen Hemminger @ 2009-11-01 19:25 UTC (permalink / raw)
To: Rasesh Mody; +Cc: netdev, adapter_linux_open_src_team
In-Reply-To: <200911010503.nA153ESA019066@blc-10-10.brocade.com>
On Sat, 31 Oct 2009 22:03:14 -0700
Rasesh Mody <rmody@brocade.com> wrote:
> +/**
> + * bna_rxf_config_clear()
> + *
> + * For RxF "rxf_id", it clear its configuration and indicates to the
> + * statistics collector to stop collecting statistics for this
> + * Rx-Function.
> + *
> + * @param[in] dev - pointer to BNA device structure
> + * @param[in] rxf_id - rx-function ID.
> + *
> + * @return BNA_OK - successful
> + * @return BNA_FAIL - failed on sanity checks.
> + */
This and other docbook style comments do not match code,
and will produce warnings if ever run through docbook
--
^ permalink raw reply
* Re: Subject: [PATCH 1/6] bna: Brocade 10Gb Ethernet device driver
From: Stephen Hemminger @ 2009-11-01 19:25 UTC (permalink / raw)
To: Joe Perches
Cc: Rasesh Mody, netdev, adapter_linux_open_src_team,
Greg Kroah-Hartman
In-Reply-To: <1257053039.1917.147.camel@Joe-Laptop.home>
On Sat, 31 Oct 2009 22:23:59 -0700
Joe Perches <joe@perches.com> wrote:
> There are an awful lot of non linux standard
> uses in this code set.
>
> Perhaps staging would be a good place to start?
>
Yup, it looks like a Windows driver port
^ permalink raw reply
* [PATCH] r8169: remove firmware for RTL8169D PHY
From: Ben Hutchings @ 2009-11-01 22:48 UTC (permalink / raw)
To: Francois Romieu, Edward Hsu; +Cc: David S. Miller, netdev
[-- Attachment #1: Type: text/plain, Size: 19020 bytes --]
The recently added support for RTL8169D chips included some machine
code without accompanying source code. Replace this with use of the
firmware loader.
Compile-tested only.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Here's my attempt at the driver change. I leave it to you to work out
licencing of the firmware blob.
Ben.
drivers/net/Kconfig | 1 +
drivers/net/r8169.c | 719 ++++-----------------------------------------------
2 files changed, 47 insertions(+), 673 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e19ca4b..4395c1e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2170,6 +2170,7 @@ config R8169
depends on PCI
select CRC32
select MII
+ select FW_LOADER
---help---
Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 8ceecd0..c331fc3 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -23,6 +23,7 @@
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1359,6 +1360,23 @@ static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len)
}
}
+struct phy_reg_le {
+ __le16 reg;
+ __le16 val;
+};
+
+static void rtl_phy_write_fw(void __iomem *ioaddr, const struct firmware *fw)
+{
+ const struct phy_reg_le *regs = (const struct phy_reg_le *)fw->data;
+ size_t len = fw->size / sizeof(*regs);
+
+ while (len-- > 0) {
+ mdio_write(ioaddr, le16_to_cpu(regs->reg),
+ le16_to_cpu(regs->val));
+ regs++;
+ }
+}
+
static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
{
struct phy_reg phy_reg_init[] = {
@@ -1691,7 +1709,7 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
rtl8168c_3_hw_phy_config(ioaddr);
}
-static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
+static int rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
{
static struct phy_reg phy_reg_init_0[] = {
{ 0x1f, 0x0001 },
@@ -1719,361 +1737,13 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
{ 0x05, 0x8332 },
{ 0x06, 0x5561 }
};
- static struct phy_reg phy_reg_init_2[] = {
- { 0x1f, 0x0005 },
- { 0x05, 0xffc2 },
- { 0x1f, 0x0005 },
- { 0x05, 0x8000 },
- { 0x06, 0xf8f9 },
- { 0x06, 0xfaef },
- { 0x06, 0x59ee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x00e0 },
- { 0x06, 0xf87c },
- { 0x06, 0xe1f8 },
- { 0x06, 0x7d59 },
- { 0x06, 0x0fef },
- { 0x06, 0x0139 },
- { 0x06, 0x029e },
- { 0x06, 0x06ef },
- { 0x06, 0x1039 },
- { 0x06, 0x089f },
- { 0x06, 0x2aee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x01e0 },
- { 0x06, 0xf87c },
- { 0x06, 0xe1f8 },
- { 0x06, 0x7d58 },
- { 0x06, 0x409e },
- { 0x06, 0x0f39 },
- { 0x06, 0x46aa },
- { 0x06, 0x0bbf },
- { 0x06, 0x8290 },
- { 0x06, 0xd682 },
- { 0x06, 0x9802 },
- { 0x06, 0x014f },
- { 0x06, 0xae09 },
- { 0x06, 0xbf82 },
- { 0x06, 0x98d6 },
- { 0x06, 0x82a0 },
- { 0x06, 0x0201 },
- { 0x06, 0x4fef },
- { 0x06, 0x95fe },
- { 0x06, 0xfdfc },
- { 0x06, 0x05f8 },
- { 0x06, 0xf9fa },
- { 0x06, 0xeef8 },
- { 0x06, 0xea00 },
- { 0x06, 0xeef8 },
- { 0x06, 0xeb00 },
- { 0x06, 0xe2f8 },
- { 0x06, 0x7ce3 },
- { 0x06, 0xf87d },
- { 0x06, 0xa511 },
- { 0x06, 0x1112 },
- { 0x06, 0xd240 },
- { 0x06, 0xd644 },
- { 0x06, 0x4402 },
- { 0x06, 0x8217 },
- { 0x06, 0xd2a0 },
- { 0x06, 0xd6aa },
- { 0x06, 0xaa02 },
- { 0x06, 0x8217 },
- { 0x06, 0xae0f },
- { 0x06, 0xa544 },
- { 0x06, 0x4402 },
- { 0x06, 0xae4d },
- { 0x06, 0xa5aa },
- { 0x06, 0xaa02 },
- { 0x06, 0xae47 },
- { 0x06, 0xaf82 },
- { 0x06, 0x13ee },
- { 0x06, 0x834e },
- { 0x06, 0x00ee },
- { 0x06, 0x834d },
- { 0x06, 0x0fee },
- { 0x06, 0x834c },
- { 0x06, 0x0fee },
- { 0x06, 0x834f },
- { 0x06, 0x00ee },
- { 0x06, 0x8351 },
- { 0x06, 0x00ee },
- { 0x06, 0x834a },
- { 0x06, 0xffee },
- { 0x06, 0x834b },
- { 0x06, 0xffe0 },
- { 0x06, 0x8330 },
- { 0x06, 0xe183 },
- { 0x06, 0x3158 },
- { 0x06, 0xfee4 },
- { 0x06, 0xf88a },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8be0 },
- { 0x06, 0x8332 },
- { 0x06, 0xe183 },
- { 0x06, 0x3359 },
- { 0x06, 0x0fe2 },
- { 0x06, 0x834d },
- { 0x06, 0x0c24 },
- { 0x06, 0x5af0 },
- { 0x06, 0x1e12 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ce5 },
- { 0x06, 0xf88d },
- { 0x06, 0xaf82 },
- { 0x06, 0x13e0 },
- { 0x06, 0x834f },
- { 0x06, 0x10e4 },
- { 0x06, 0x834f },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x009f },
- { 0x06, 0x0ae0 },
- { 0x06, 0x834f },
- { 0x06, 0xa010 },
- { 0x06, 0xa5ee },
- { 0x06, 0x834e },
- { 0x06, 0x01e0 },
- { 0x06, 0x834e },
- { 0x06, 0x7805 },
- { 0x06, 0x9e9a },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x049e },
- { 0x06, 0x10e0 },
- { 0x06, 0x834e },
- { 0x06, 0x7803 },
- { 0x06, 0x9e0f },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x019e },
- { 0x06, 0x05ae },
- { 0x06, 0x0caf },
- { 0x06, 0x81f8 },
- { 0x06, 0xaf81 },
- { 0x06, 0xa3af },
- { 0x06, 0x81dc },
- { 0x06, 0xaf82 },
- { 0x06, 0x13ee },
- { 0x06, 0x8348 },
- { 0x06, 0x00ee },
- { 0x06, 0x8349 },
- { 0x06, 0x00e0 },
- { 0x06, 0x8351 },
- { 0x06, 0x10e4 },
- { 0x06, 0x8351 },
- { 0x06, 0x5801 },
- { 0x06, 0x9fea },
- { 0x06, 0xd000 },
- { 0x06, 0xd180 },
- { 0x06, 0x1f66 },
- { 0x06, 0xe2f8 },
- { 0x06, 0xeae3 },
- { 0x06, 0xf8eb },
- { 0x06, 0x5af8 },
- { 0x06, 0x1e20 },
- { 0x06, 0xe6f8 },
- { 0x06, 0xeae5 },
- { 0x06, 0xf8eb },
- { 0x06, 0xd302 },
- { 0x06, 0xb3fe },
- { 0x06, 0xe2f8 },
- { 0x06, 0x7cef },
- { 0x06, 0x325b },
- { 0x06, 0x80e3 },
- { 0x06, 0xf87d },
- { 0x06, 0x9e03 },
- { 0x06, 0x7dff },
- { 0x06, 0xff0d },
- { 0x06, 0x581c },
- { 0x06, 0x551a },
- { 0x06, 0x6511 },
- { 0x06, 0xa190 },
- { 0x06, 0xd3e2 },
- { 0x06, 0x8348 },
- { 0x06, 0xe383 },
- { 0x06, 0x491b },
- { 0x06, 0x56ab },
- { 0x06, 0x08ef },
- { 0x06, 0x56e6 },
- { 0x06, 0x8348 },
- { 0x06, 0xe783 },
- { 0x06, 0x4910 },
- { 0x06, 0xd180 },
- { 0x06, 0x1f66 },
- { 0x06, 0xa004 },
- { 0x06, 0xb9e2 },
- { 0x06, 0x8348 },
- { 0x06, 0xe383 },
- { 0x06, 0x49ef },
- { 0x06, 0x65e2 },
- { 0x06, 0x834a },
- { 0x06, 0xe383 },
- { 0x06, 0x4b1b },
- { 0x06, 0x56aa },
- { 0x06, 0x0eef },
- { 0x06, 0x56e6 },
- { 0x06, 0x834a },
- { 0x06, 0xe783 },
- { 0x06, 0x4be2 },
- { 0x06, 0x834d },
- { 0x06, 0xe683 },
- { 0x06, 0x4ce0 },
- { 0x06, 0x834d },
- { 0x06, 0xa000 },
- { 0x06, 0x0caf },
- { 0x06, 0x81dc },
- { 0x06, 0xe083 },
- { 0x06, 0x4d10 },
- { 0x06, 0xe483 },
- { 0x06, 0x4dae },
- { 0x06, 0x0480 },
- { 0x06, 0xe483 },
- { 0x06, 0x4de0 },
- { 0x06, 0x834e },
- { 0x06, 0x7803 },
- { 0x06, 0x9e0b },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x049e },
- { 0x06, 0x04ee },
- { 0x06, 0x834e },
- { 0x06, 0x02e0 },
- { 0x06, 0x8332 },
- { 0x06, 0xe183 },
- { 0x06, 0x3359 },
- { 0x06, 0x0fe2 },
- { 0x06, 0x834d },
- { 0x06, 0x0c24 },
- { 0x06, 0x5af0 },
- { 0x06, 0x1e12 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ce5 },
- { 0x06, 0xf88d },
- { 0x06, 0xe083 },
- { 0x06, 0x30e1 },
- { 0x06, 0x8331 },
- { 0x06, 0x6801 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ae5 },
- { 0x06, 0xf88b },
- { 0x06, 0xae37 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e03 },
- { 0x06, 0xe083 },
- { 0x06, 0x4ce1 },
- { 0x06, 0x834d },
- { 0x06, 0x1b01 },
- { 0x06, 0x9e04 },
- { 0x06, 0xaaa1 },
- { 0x06, 0xaea8 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e04 },
- { 0x06, 0xee83 },
- { 0x06, 0x4f00 },
- { 0x06, 0xaeab },
- { 0x06, 0xe083 },
- { 0x06, 0x4f78 },
- { 0x06, 0x039f },
- { 0x06, 0x14ee },
- { 0x06, 0x834e },
- { 0x06, 0x05d2 },
- { 0x06, 0x40d6 },
- { 0x06, 0x5554 },
- { 0x06, 0x0282 },
- { 0x06, 0x17d2 },
- { 0x06, 0xa0d6 },
- { 0x06, 0xba00 },
- { 0x06, 0x0282 },
- { 0x06, 0x17fe },
- { 0x06, 0xfdfc },
- { 0x06, 0x05f8 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x60e1 },
- { 0x06, 0xf861 },
- { 0x06, 0x6802 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x60e5 },
- { 0x06, 0xf861 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x48e1 },
- { 0x06, 0xf849 },
- { 0x06, 0x580f },
- { 0x06, 0x1e02 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0xd000 },
- { 0x06, 0x0282 },
- { 0x06, 0x5bbf },
- { 0x06, 0x8350 },
- { 0x06, 0xef46 },
- { 0x06, 0xdc19 },
- { 0x06, 0xddd0 },
- { 0x06, 0x0102 },
- { 0x06, 0x825b },
- { 0x06, 0x0282 },
- { 0x06, 0x77e0 },
- { 0x06, 0xf860 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x6158 },
- { 0x06, 0xfde4 },
- { 0x06, 0xf860 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x61fc },
- { 0x06, 0x04f9 },
- { 0x06, 0xfafb },
- { 0x06, 0xc6bf },
- { 0x06, 0xf840 },
- { 0x06, 0xbe83 },
- { 0x06, 0x50a0 },
- { 0x06, 0x0101 },
- { 0x06, 0x071b },
- { 0x06, 0x89cf },
- { 0x06, 0xd208 },
- { 0x06, 0xebdb },
- { 0x06, 0x19b2 },
- { 0x06, 0xfbff },
- { 0x06, 0xfefd },
- { 0x06, 0x04f8 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x48e1 },
- { 0x06, 0xf849 },
- { 0x06, 0x6808 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0x58f7 },
- { 0x06, 0xe4f8 },
- { 0x06, 0x48e5 },
- { 0x06, 0xf849 },
- { 0x06, 0xfc04 },
- { 0x06, 0x4d20 },
- { 0x06, 0x0002 },
- { 0x06, 0x4e22 },
- { 0x06, 0x0002 },
- { 0x06, 0x4ddf },
- { 0x06, 0xff01 },
- { 0x06, 0x4edd },
- { 0x06, 0xff01 },
- { 0x05, 0x83d4 },
- { 0x06, 0x8000 },
- { 0x05, 0x83d8 },
- { 0x06, 0x8051 },
- { 0x02, 0x6010 },
- { 0x03, 0xdc00 },
- { 0x05, 0xfff6 },
- { 0x06, 0x00fc },
- { 0x1f, 0x0000 },
+ void __iomem *ioaddr = tp->mmio_addr;
+ const struct firmware *fw;
+ int rc;
- { 0x1f, 0x0000 },
- { 0x0d, 0xf880 },
- { 0x1f, 0x0000 }
- };
+ rc = request_firmware(&fw, "rtl8168d-1.fw", &tp->pci_dev->dev);
+ if (rc)
+ return rc;
rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
@@ -2131,10 +1801,15 @@ static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
- rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
+ rtl_phy_write_fw(ioaddr, fw);
+
+ release_firmware(fw);
+ return 0;
}
-static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
+MODULE_FIRMWARE("rtl8168d-1.fw");
+
+static int rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
{
static struct phy_reg phy_reg_init_0[] = {
{ 0x1f, 0x0001 },
@@ -2161,318 +1836,13 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
{ 0x05, 0x8332 },
{ 0x06, 0x5561 }
};
- static struct phy_reg phy_reg_init_1[] = {
- { 0x1f, 0x0005 },
- { 0x05, 0xffc2 },
- { 0x1f, 0x0005 },
- { 0x05, 0x8000 },
- { 0x06, 0xf8f9 },
- { 0x06, 0xfaee },
- { 0x06, 0xf8ea },
- { 0x06, 0x00ee },
- { 0x06, 0xf8eb },
- { 0x06, 0x00e2 },
- { 0x06, 0xf87c },
- { 0x06, 0xe3f8 },
- { 0x06, 0x7da5 },
- { 0x06, 0x1111 },
- { 0x06, 0x12d2 },
- { 0x06, 0x40d6 },
- { 0x06, 0x4444 },
- { 0x06, 0x0281 },
- { 0x06, 0xc6d2 },
- { 0x06, 0xa0d6 },
- { 0x06, 0xaaaa },
- { 0x06, 0x0281 },
- { 0x06, 0xc6ae },
- { 0x06, 0x0fa5 },
- { 0x06, 0x4444 },
- { 0x06, 0x02ae },
- { 0x06, 0x4da5 },
- { 0x06, 0xaaaa },
- { 0x06, 0x02ae },
- { 0x06, 0x47af },
- { 0x06, 0x81c2 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e00 },
- { 0x06, 0xee83 },
- { 0x06, 0x4d0f },
- { 0x06, 0xee83 },
- { 0x06, 0x4c0f },
- { 0x06, 0xee83 },
- { 0x06, 0x4f00 },
- { 0x06, 0xee83 },
- { 0x06, 0x5100 },
- { 0x06, 0xee83 },
- { 0x06, 0x4aff },
- { 0x06, 0xee83 },
- { 0x06, 0x4bff },
- { 0x06, 0xe083 },
- { 0x06, 0x30e1 },
- { 0x06, 0x8331 },
- { 0x06, 0x58fe },
- { 0x06, 0xe4f8 },
- { 0x06, 0x8ae5 },
- { 0x06, 0xf88b },
- { 0x06, 0xe083 },
- { 0x06, 0x32e1 },
- { 0x06, 0x8333 },
- { 0x06, 0x590f },
- { 0x06, 0xe283 },
- { 0x06, 0x4d0c },
- { 0x06, 0x245a },
- { 0x06, 0xf01e },
- { 0x06, 0x12e4 },
- { 0x06, 0xf88c },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8daf },
- { 0x06, 0x81c2 },
- { 0x06, 0xe083 },
- { 0x06, 0x4f10 },
- { 0x06, 0xe483 },
- { 0x06, 0x4fe0 },
- { 0x06, 0x834e },
- { 0x06, 0x7800 },
- { 0x06, 0x9f0a },
- { 0x06, 0xe083 },
- { 0x06, 0x4fa0 },
- { 0x06, 0x10a5 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e01 },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x059e },
- { 0x06, 0x9ae0 },
- { 0x06, 0x834e },
- { 0x06, 0x7804 },
- { 0x06, 0x9e10 },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x039e },
- { 0x06, 0x0fe0 },
- { 0x06, 0x834e },
- { 0x06, 0x7801 },
- { 0x06, 0x9e05 },
- { 0x06, 0xae0c },
- { 0x06, 0xaf81 },
- { 0x06, 0xa7af },
- { 0x06, 0x8152 },
- { 0x06, 0xaf81 },
- { 0x06, 0x8baf },
- { 0x06, 0x81c2 },
- { 0x06, 0xee83 },
- { 0x06, 0x4800 },
- { 0x06, 0xee83 },
- { 0x06, 0x4900 },
- { 0x06, 0xe083 },
- { 0x06, 0x5110 },
- { 0x06, 0xe483 },
- { 0x06, 0x5158 },
- { 0x06, 0x019f },
- { 0x06, 0xead0 },
- { 0x06, 0x00d1 },
- { 0x06, 0x801f },
- { 0x06, 0x66e2 },
- { 0x06, 0xf8ea },
- { 0x06, 0xe3f8 },
- { 0x06, 0xeb5a },
- { 0x06, 0xf81e },
- { 0x06, 0x20e6 },
- { 0x06, 0xf8ea },
- { 0x06, 0xe5f8 },
- { 0x06, 0xebd3 },
- { 0x06, 0x02b3 },
- { 0x06, 0xfee2 },
- { 0x06, 0xf87c },
- { 0x06, 0xef32 },
- { 0x06, 0x5b80 },
- { 0x06, 0xe3f8 },
- { 0x06, 0x7d9e },
- { 0x06, 0x037d },
- { 0x06, 0xffff },
- { 0x06, 0x0d58 },
- { 0x06, 0x1c55 },
- { 0x06, 0x1a65 },
- { 0x06, 0x11a1 },
- { 0x06, 0x90d3 },
- { 0x06, 0xe283 },
- { 0x06, 0x48e3 },
- { 0x06, 0x8349 },
- { 0x06, 0x1b56 },
- { 0x06, 0xab08 },
- { 0x06, 0xef56 },
- { 0x06, 0xe683 },
- { 0x06, 0x48e7 },
- { 0x06, 0x8349 },
- { 0x06, 0x10d1 },
- { 0x06, 0x801f },
- { 0x06, 0x66a0 },
- { 0x06, 0x04b9 },
- { 0x06, 0xe283 },
- { 0x06, 0x48e3 },
- { 0x06, 0x8349 },
- { 0x06, 0xef65 },
- { 0x06, 0xe283 },
- { 0x06, 0x4ae3 },
- { 0x06, 0x834b },
- { 0x06, 0x1b56 },
- { 0x06, 0xaa0e },
- { 0x06, 0xef56 },
- { 0x06, 0xe683 },
- { 0x06, 0x4ae7 },
- { 0x06, 0x834b },
- { 0x06, 0xe283 },
- { 0x06, 0x4de6 },
- { 0x06, 0x834c },
- { 0x06, 0xe083 },
- { 0x06, 0x4da0 },
- { 0x06, 0x000c },
- { 0x06, 0xaf81 },
- { 0x06, 0x8be0 },
- { 0x06, 0x834d },
- { 0x06, 0x10e4 },
- { 0x06, 0x834d },
- { 0x06, 0xae04 },
- { 0x06, 0x80e4 },
- { 0x06, 0x834d },
- { 0x06, 0xe083 },
- { 0x06, 0x4e78 },
- { 0x06, 0x039e },
- { 0x06, 0x0be0 },
- { 0x06, 0x834e },
- { 0x06, 0x7804 },
- { 0x06, 0x9e04 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e02 },
- { 0x06, 0xe083 },
- { 0x06, 0x32e1 },
- { 0x06, 0x8333 },
- { 0x06, 0x590f },
- { 0x06, 0xe283 },
- { 0x06, 0x4d0c },
- { 0x06, 0x245a },
- { 0x06, 0xf01e },
- { 0x06, 0x12e4 },
- { 0x06, 0xf88c },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8de0 },
- { 0x06, 0x8330 },
- { 0x06, 0xe183 },
- { 0x06, 0x3168 },
- { 0x06, 0x01e4 },
- { 0x06, 0xf88a },
- { 0x06, 0xe5f8 },
- { 0x06, 0x8bae },
- { 0x06, 0x37ee },
- { 0x06, 0x834e },
- { 0x06, 0x03e0 },
- { 0x06, 0x834c },
- { 0x06, 0xe183 },
- { 0x06, 0x4d1b },
- { 0x06, 0x019e },
- { 0x06, 0x04aa },
- { 0x06, 0xa1ae },
- { 0x06, 0xa8ee },
- { 0x06, 0x834e },
- { 0x06, 0x04ee },
- { 0x06, 0x834f },
- { 0x06, 0x00ae },
- { 0x06, 0xabe0 },
- { 0x06, 0x834f },
- { 0x06, 0x7803 },
- { 0x06, 0x9f14 },
- { 0x06, 0xee83 },
- { 0x06, 0x4e05 },
- { 0x06, 0xd240 },
- { 0x06, 0xd655 },
- { 0x06, 0x5402 },
- { 0x06, 0x81c6 },
- { 0x06, 0xd2a0 },
- { 0x06, 0xd6ba },
- { 0x06, 0x0002 },
- { 0x06, 0x81c6 },
- { 0x06, 0xfefd },
- { 0x06, 0xfc05 },
- { 0x06, 0xf8e0 },
- { 0x06, 0xf860 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x6168 },
- { 0x06, 0x02e4 },
- { 0x06, 0xf860 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x61e0 },
- { 0x06, 0xf848 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x4958 },
- { 0x06, 0x0f1e },
- { 0x06, 0x02e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x49d0 },
- { 0x06, 0x0002 },
- { 0x06, 0x820a },
- { 0x06, 0xbf83 },
- { 0x06, 0x50ef },
- { 0x06, 0x46dc },
- { 0x06, 0x19dd },
- { 0x06, 0xd001 },
- { 0x06, 0x0282 },
- { 0x06, 0x0a02 },
- { 0x06, 0x8226 },
- { 0x06, 0xe0f8 },
- { 0x06, 0x60e1 },
- { 0x06, 0xf861 },
- { 0x06, 0x58fd },
- { 0x06, 0xe4f8 },
- { 0x06, 0x60e5 },
- { 0x06, 0xf861 },
- { 0x06, 0xfc04 },
- { 0x06, 0xf9fa },
- { 0x06, 0xfbc6 },
- { 0x06, 0xbff8 },
- { 0x06, 0x40be },
- { 0x06, 0x8350 },
- { 0x06, 0xa001 },
- { 0x06, 0x0107 },
- { 0x06, 0x1b89 },
- { 0x06, 0xcfd2 },
- { 0x06, 0x08eb },
- { 0x06, 0xdb19 },
- { 0x06, 0xb2fb },
- { 0x06, 0xfffe },
- { 0x06, 0xfd04 },
- { 0x06, 0xf8e0 },
- { 0x06, 0xf848 },
- { 0x06, 0xe1f8 },
- { 0x06, 0x4968 },
- { 0x06, 0x08e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x4958 },
- { 0x06, 0xf7e4 },
- { 0x06, 0xf848 },
- { 0x06, 0xe5f8 },
- { 0x06, 0x49fc },
- { 0x06, 0x044d },
- { 0x06, 0x2000 },
- { 0x06, 0x024e },
- { 0x06, 0x2200 },
- { 0x06, 0x024d },
- { 0x06, 0xdfff },
- { 0x06, 0x014e },
- { 0x06, 0xddff },
- { 0x06, 0x0100 },
- { 0x05, 0x83d8 },
- { 0x06, 0x8000 },
- { 0x03, 0xdc00 },
- { 0x05, 0xfff6 },
- { 0x06, 0x00fc },
- { 0x1f, 0x0000 },
+ void __iomem *ioaddr = tp->mmio_addr;
+ const struct firmware *fw;
+ int rc;
- { 0x1f, 0x0000 },
- { 0x0d, 0xf880 },
- { 0x1f, 0x0000 }
- };
+ rc = request_firmware(&fw, "rtl8168d-2.fw", &tp->pci_dev->dev);
+ if (rc)
+ return rc;
rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
@@ -2526,9 +1896,14 @@ static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
mdio_write(ioaddr, 0x1f, 0x0002);
mdio_patch(ioaddr, 0x0f, 0x0017);
- rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
+ rtl_phy_write_fw(ioaddr, fw);
+
+ release_firmware(fw);
+ return 0;
}
+MODULE_FIRMWARE("rtl8168d-2.fw");
+
static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
{
struct phy_reg phy_reg_init[] = {
@@ -2664,11 +2039,9 @@ static int rtl_hw_phy_config(struct net_device *dev)
rtl8168cp_2_hw_phy_config(ioaddr);
break;
case RTL_GIGA_MAC_VER_25:
- rtl8168d_1_hw_phy_config(ioaddr);
- break;
+ return rtl8168d_1_hw_phy_config(tp);
case RTL_GIGA_MAC_VER_26:
- rtl8168d_2_hw_phy_config(ioaddr);
- break;
+ return rtl8168d_2_hw_phy_config(tp);
case RTL_GIGA_MAC_VER_27:
rtl8168d_3_hw_phy_config(ioaddr);
break;
--
1.6.5.2
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply related
* [PATCH 1/2] r8169: allow rtl_hw_phy_config() and rtl8169_init_phy() to return error codes
From: Ben Hutchings @ 2009-11-01 22:51 UTC (permalink / raw)
To: Francois Romieu, Edward Hsu; +Cc: David S. Miller, netdev
In-Reply-To: <1257115687.3136.337.camel@localhost>
[-- Attachment #1: Type: text/plain, Size: 2247 bytes --]
This is preparation for loading PHY firmware, which may fail.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
This one belongs before the other. Sorry about sending them in the
wrong order.
Ben.
drivers/net/r8169.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f98ef52..8ceecd0 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2607,7 +2607,7 @@ static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl_hw_phy_config(struct net_device *dev)
+static int rtl_hw_phy_config(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
@@ -2676,6 +2676,8 @@ static void rtl_hw_phy_config(struct net_device *dev)
default:
break;
}
+
+ return 0;
}
static void rtl8169_phy_timer(unsigned long __opaque)
@@ -2780,11 +2782,14 @@ static void rtl8169_phy_reset(struct net_device *dev,
printk(KERN_ERR "%s: PHY reset failed.\n", dev->name);
}
-static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
+static int rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
+ int rc;
- rtl_hw_phy_config(dev);
+ rc = rtl_hw_phy_config(dev);
+ if (rc)
+ return rc;
if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
@@ -2813,6 +2818,8 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+
+ return 0;
}
static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
@@ -3199,7 +3206,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq);
}
- rtl8169_init_phy(dev, tp);
+ rc = rtl8169_init_phy(dev, tp);
+ if (rc)
+ goto err_out_msi_5;
/*
* Pretend we are using VLANs; This bypasses a nasty bug where
--
1.6.5.2
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply related
* Re: [PATCH] e1000: the power down when running ifdown command
From: Naohiro Ooiwa @ 2009-11-02 1:28 UTC (permalink / raw)
To: Stephen Hemminger
Cc: jeffrey.t.kirsher, jesse.brandeburg, peter.p.waskiewicz.jr,
john.ronciak, davem, Andrew Morton, netdev, svaidy, e1000-devel
In-Reply-To: <20091031105838.0d4b59a2@nehalam>
Stephen Hemminger wrote:
> On Sat, 31 Oct 2009 18:39:52 +0900
> Naohiro Ooiwa <nooiwa@miraclelinux.com> wrote:
>
>> Hi All
>>
>> I resend my patch.
>> Sorry, my previous mail lacked an explanation.
>>
>>
>> The e1000 driver doesn't let the power down when running ifdown command.
>> So, I set to the D3hot state of a PCI device at the end of e1000_close().
>>
>> With this modification, e1000 driver reduces power by ifdown.
>> It's about 6 watts when I measured a total power of one server machine
>> in my environment.
>>
>> I tested this patch. The result is good enough to me.
>>
>> Could you please check my patch ?
>> If I should have other considerations, please tell me.
>>
Hi Stephen
Thank you so much for your reply.
> Does this work with Wake On Lan?
Yes, it works WOL.
But I worry that my test is enough.
They are following:
- simple data transmission after ifdown;ifup.
- enable wol, ifup network device, system shutdown, and make sure wol work.
- enable wol, ifdown network device, system shutdown, and make sure wol work.
- while [ 0 ] ; do ifdown eth0 ; ifup eth0 ; done
- while [ 0 ] ; do modprobe e1000 ; rmmod e1000 ; done
> @@ -1265,6 +1287,7 @@ static int e1000_open(struct net_device *netdev)
> goto err_setup_rx;
>
> e1000_power_up_phy(adapter);
> + e1000_reset(adapter);
>
> adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
> if ((hw->mng_cookie.status &
This code fix problem that e1000 driver doesn't work to auto-negotiation
once in a while.
Maybe, the cause is that set state to D0 just before it.
I found it by repeat of ifup and ifdown.
If you find out other points and any necessary tests from my patch,
please tell me. I will make sure them.
Thanks you.
Naohiro Ooiwa
^ permalink raw reply
* [PPATCH net-next-2.6] ipv4: inetdev_by_index() switch to RCU
From: Eric Dumazet @ 2009-11-02 5:23 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List
Use dev_get_by_index_rcu() instead of __dev_get_by_index() and
dev_base_lock rwlock
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5df2f6a..ccccaae 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -405,11 +405,12 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex)
{
struct net_device *dev;
struct in_device *in_dev = NULL;
- read_lock(&dev_base_lock);
- dev = __dev_get_by_index(net, ifindex);
+
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(net, ifindex);
if (dev)
in_dev = in_dev_get(dev);
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
return in_dev;
}
^ permalink raw reply related
* [PATCH net-next-2.6] icmp: icmp_send() can avoid a dev_put()
From: Eric Dumazet @ 2009-11-02 5:31 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List
We can avoid touching device refcount in icmp_send(),
using dev_get_by_index_rcu()
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 84adb57..fe11f60 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -501,15 +501,16 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
if (!(rt->rt_flags & RTCF_LOCAL)) {
struct net_device *dev = NULL;
+ rcu_read_lock();
if (rt->fl.iif &&
net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
- dev = dev_get_by_index(net, rt->fl.iif);
+ dev = dev_get_by_index_rcu(net, rt->fl.iif);
- if (dev) {
+ if (dev)
saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
- dev_put(dev);
- } else
+ else
saddr = 0;
+ rcu_read_unlock();
}
tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
^ permalink raw reply related
* [PATCH net-next-2.6] net: RCU locking for simple ioctl()
From: Eric Dumazet @ 2009-11-02 5:42 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List
All ioctls() implemented by dev_ifsioc_locked() :
SIOCGIFFLAGS, SIOCGIFMETRIC, SIOCGIFMTU, SIOCGIFHWADDR,
SIOCGIFSLAVE, SIOCGIFMAP, SIOCGIFINDEX & SIOCGIFTXQLEN
can use RCU lock instead of dev_base_lock rwlock
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/core/dev.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index f54d8b8..c0f27ad 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4315,12 +4315,12 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
EXPORT_SYMBOL(dev_set_mac_address);
/*
- * Perform the SIOCxIFxxx calls, inside read_lock(dev_base_lock)
+ * Perform the SIOCxIFxxx calls, inside rcu_read_lock()
*/
static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd)
{
int err;
- struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
+ struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);
if (!dev)
return -ENODEV;
@@ -4552,9 +4552,9 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
case SIOCGIFINDEX:
case SIOCGIFTXQLEN:
dev_load(net, ifr.ifr_name);
- read_lock(&dev_base_lock);
+ rcu_read_lock();
ret = dev_ifsioc_locked(net, &ifr, cmd);
- read_unlock(&dev_base_lock);
+ rcu_read_unlock();
if (!ret) {
if (colon)
*colon = ':';
^ permalink raw reply related
* [PATCH net-next-2.6] ifb: RCU locking avoids touching dev refcount
From: Eric Dumazet @ 2009-11-02 5:45 UTC (permalink / raw)
To: David S. Miller, Linux Netdev List
Avoids touching dev refcount in hotpath
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
drivers/net/ifb.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 030913f..69c2566 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -98,13 +98,15 @@ static void ri_tasklet(unsigned long dev)
stats->tx_packets++;
stats->tx_bytes +=skb->len;
- skb->dev = dev_get_by_index(&init_net, skb->iif);
+ rcu_read_lock();
+ skb->dev = dev_get_by_index_rcu(&init_net, skb->iif);
if (!skb->dev) {
+ rcu_read_unlock();
dev_kfree_skb(skb);
stats->tx_dropped++;
break;
}
- dev_put(skb->dev);
+ rcu_read_unlock();
skb->iif = _dev->ifindex;
if (from & AT_EGRESS) {
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox