* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: Gerrit Renker @ 2006-06-12 7:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev, kaber, jmorris
In-Reply-To: <20060611.231300.95505265.davem@davemloft.net>
The code below implements the discussed solution of decrementing
InDatagrams if a datagram fails the checksum within udp_recvmsg().
I have given it a quick test / build and checked the outcome against
previous results: I now obtained correct counter values, i.e. the application
counted exactly InDatagrams datagrams, whereas with the same settings before
this was not the case (datagrams with checksum errors were counted both as
InErrors and as InDatagrams).
Will add this patch to http://bugzilla.kernel.org/show_bug.cgi?id=6660
where this problem is also described. Patches under 2.6.16 with no complaints.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
include/net/snmp.h | 2 ++
include/net/udp.h | 1 +
net/ipv4/udp.c | 1 +
3 files changed, 4 insertions(+)
diff -Nurp a/include/net/snmp.h b/include/net/snmp.h
--- a/include/net/snmp.h 2006-06-05 21:52:55.000000000 +0100
+++ b/include/net/snmp.h 2006-06-12 07:38:11.000000000 +0100
@@ -137,6 +137,8 @@ struct linux_mib {
(per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++)
#define SNMP_DEC_STATS(mib, field) \
(per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--)
+#define SNMP_DEC_STATS_BH(mib, field) \
+ (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]--)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
diff -Nurp a/include/net/udp.h b/include/net/udp.h
--- a/include/net/udp.h 2006-06-06 18:04:36.000000000 +0100
+++ b/include/net/udp.h 2006-06-12 07:39:29.000000000 +0100
@@ -78,6 +78,7 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_st
#define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
#define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
#define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field)
+#define UDP_DEC_STATS_BH(field) SNMP_DEC_STATS_BH(udp_statistics, field)
/* /proc */
struct udp_seq_afinfo {
diff -Nurp a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c 2006-06-07 20:44:13.000000000 +0100
+++ b/net/ipv4/udp.c 2006-06-12 07:40:02.000000000 +0100
@@ -846,6 +846,7 @@ out:
csum_copy_err:
UDP_INC_STATS_BH(UDP_MIB_INERRORS);
+ UDP_DEC_STATS_BH(UDP_MIB_INDATAGRAMS);
skb_kill_datagram(sk, skb, flags);
^ permalink raw reply
* Re: [patch] undo AF_UNIX _bh locking changes and split lock-type instead
From: David Miller @ 2006-06-12 7:18 UTC (permalink / raw)
To: herbert
Cc: akpm, Valdis.Kletnieks, jirislaby, netdev, linux-kernel, stefanr,
mingo, linux1394-devel, mingo, arjan
In-Reply-To: <20060612070356.GA1273@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Mon, 12 Jun 2006 17:03:56 +1000
> On Mon, Jun 12, 2006 at 08:57:01AM +0200, Ingo Molnar wrote:
> >
> > regarding your point wrt. path of integration - it is pretty much the
> > only practical way to do this centrally as part of the lock validator
> > patches, but to collect ACKs from subsystem maintainers in the process.
> > So if you like it i'd like to have your ACK but this patch depends on
> > the other lock validator patches (and only makes sense together with
> > them), so they should temporarily stay in the lock validator queue.
> > Hopefully this wont be a state that lasts too long and once the
> > validator is upstream, all patches of course go via the subsystem
> > submission rules.
>
> Obviously as long as Dave is happy with it then it's fine. However,
> it's probably a good idea to cc netdev for relevant patches so that
> they get a wider review. If you've already sent this one there then
> I apologise for missing it :)
Yes, this is fine with me.
^ permalink raw reply
* Re: [patch] undo AF_UNIX _bh locking changes and split lock-type instead
From: Herbert Xu @ 2006-06-12 7:03 UTC (permalink / raw)
To: Ingo Molnar
Cc: Andrew Morton, linux1394-devel, Valdis.Kletnieks, Jiri Slaby,
netdev, linux-kernel, mingo, Stefan Richter, David S. Miller,
arjan
In-Reply-To: <20060612065701.GA24213@elte.hu>
On Mon, Jun 12, 2006 at 08:57:01AM +0200, Ingo Molnar wrote:
>
> regarding your point wrt. path of integration - it is pretty much the
> only practical way to do this centrally as part of the lock validator
> patches, but to collect ACKs from subsystem maintainers in the process.
> So if you like it i'd like to have your ACK but this patch depends on
> the other lock validator patches (and only makes sense together with
> them), so they should temporarily stay in the lock validator queue.
> Hopefully this wont be a state that lasts too long and once the
> validator is upstream, all patches of course go via the subsystem
> submission rules.
Obviously as long as Dave is happy with it then it's fine. However,
it's probably a good idea to cc netdev for relevant patches so that
they get a wider review. If you've already sent this one there then
I apologise for missing it :)
> (the #ifdef LOCKDEP should probably be converted to some sort of
> lockdep_split_lock_key(&sk->sk_receive_queue.lock) op - i'll do that
> later)
Cool.
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [patch] undo AF_UNIX _bh locking changes and split lock-type instead
From: Ingo Molnar @ 2006-06-12 6:57 UTC (permalink / raw)
To: Herbert Xu
Cc: Andrew Morton, linux1394-devel, Valdis.Kletnieks, Jiri Slaby,
netdev, linux-kernel, mingo, Stefan Richter, David S. Miller,
arjan
In-Reply-To: <20060612064122.GA1101@gondor.apana.org.au>
* Herbert Xu <herbert@gondor.apana.org.au> wrote:
> > Maybe it's enough to introduce a separate key for AF_UNIX alone (and
> > still having all other protocols share the locking rules for
> > sk_receive_queue.lock) , by reinitializing its spinlock after
> > sock_init_data()?
>
> This could work. AF_UNIX is probably the only family that does not
> interact with hardware.
ok, great. The patch below does the trick on my box.
regarding your point wrt. path of integration - it is pretty much the
only practical way to do this centrally as part of the lock validator
patches, but to collect ACKs from subsystem maintainers in the process.
So if you like it i'd like to have your ACK but this patch depends on
the other lock validator patches (and only makes sense together with
them), so they should temporarily stay in the lock validator queue.
Hopefully this wont be a state that lasts too long and once the
validator is upstream, all patches of course go via the subsystem
submission rules.
(the #ifdef LOCKDEP should probably be converted to some sort of
lockdep_split_lock_key(&sk->sk_receive_queue.lock) op - i'll do that
later)
Ingo
------
Subject: undo AF_UNIX _bh locking changes and split lock-type instead
From: Ingo Molnar <mingo@elte.hu>
this cleans up lock-validator-special-locking-af_unix.patch: instead
of adding _bh locking to AF_UNIX, this patch splits their
sk_receive_queue.lock type from the other networking skb-queue locks.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
net/unix/af_unix.c | 17 +++++++++++++----
net/unix/garbage.c | 8 ++++----
2 files changed, 17 insertions(+), 8 deletions(-)
Index: linux/net/unix/af_unix.c
===================================================================
--- linux.orig/net/unix/af_unix.c
+++ linux/net/unix/af_unix.c
@@ -557,6 +557,15 @@ static struct sock * unix_create1(struct
atomic_inc(&unix_nr_socks);
sock_init_data(sock,sk);
+#ifdef CONFIG_LOCKDEP
+ /*
+ * AF_UNIX sockets do not interact with hardware, hence they
+ * dont trigger interrupts - so it's safe for them to have
+ * bh-unsafe locking for their sk_receive_queue.lock. Split off
+ * this special lock-type by reinitializing the spinlock.
+ */
+ spin_lock_init(&sk->sk_receive_queue.lock);
+#endif
sk->sk_write_space = unix_write_space;
sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen;
@@ -1073,12 +1082,12 @@ restart:
unix_state_wunlock(sk);
/* take ten and and send info to listening sock */
- spin_lock_bh(&other->sk_receive_queue.lock);
+ spin_lock(&other->sk_receive_queue.lock);
__skb_queue_tail(&other->sk_receive_queue, skb);
/* Undo artificially decreased inflight after embrion
* is installed to listening socket. */
atomic_inc(&newu->inflight);
- spin_unlock_bh(&other->sk_receive_queue.lock);
+ spin_unlock(&other->sk_receive_queue.lock);
unix_state_runlock(other);
other->sk_data_ready(other, 0);
sock_put(other);
@@ -1843,7 +1852,7 @@ static int unix_ioctl(struct socket *soc
break;
}
- spin_lock_bh(&sk->sk_receive_queue.lock);
+ spin_lock(&sk->sk_receive_queue.lock);
if (sk->sk_type == SOCK_STREAM ||
sk->sk_type == SOCK_SEQPACKET) {
skb_queue_walk(&sk->sk_receive_queue, skb)
@@ -1853,7 +1862,7 @@ static int unix_ioctl(struct socket *soc
if (skb)
amount=skb->len;
}
- spin_unlock_bh(&sk->sk_receive_queue.lock);
+ spin_unlock(&sk->sk_receive_queue.lock);
err = put_user(amount, (int __user *)arg);
break;
}
Index: linux/net/unix/garbage.c
===================================================================
--- linux.orig/net/unix/garbage.c
+++ linux/net/unix/garbage.c
@@ -235,7 +235,7 @@ void unix_gc(void)
struct sock *x = pop_stack();
struct sock *sk;
- spin_lock_bh(&x->sk_receive_queue.lock);
+ spin_lock(&x->sk_receive_queue.lock);
skb = skb_peek(&x->sk_receive_queue);
/*
@@ -270,7 +270,7 @@ void unix_gc(void)
maybe_unmark_and_push(skb->sk);
skb=skb->next;
}
- spin_unlock_bh(&x->sk_receive_queue.lock);
+ spin_unlock(&x->sk_receive_queue.lock);
sock_put(x);
}
@@ -283,7 +283,7 @@ void unix_gc(void)
if (u->gc_tree == GC_ORPHAN) {
struct sk_buff *nextsk;
- spin_lock_bh(&s->sk_receive_queue.lock);
+ spin_lock(&s->sk_receive_queue.lock);
skb = skb_peek(&s->sk_receive_queue);
while (skb &&
skb != (struct sk_buff *)&s->sk_receive_queue) {
@@ -298,7 +298,7 @@ void unix_gc(void)
}
skb = nextsk;
}
- spin_unlock_bh(&s->sk_receive_queue.lock);
+ spin_unlock(&s->sk_receive_queue.lock);
}
u->gc_tree = GC_ORPHAN;
}
^ permalink raw reply
* Re: 2.6.17-rc5-mm3-lockdep -
From: David Miller @ 2006-06-12 6:50 UTC (permalink / raw)
To: mingo
Cc: herbert, stefanr, Valdis.Kletnieks, jirislaby, akpm, arjan, mingo,
linux-kernel, linux1394-devel, netdev
In-Reply-To: <20060612063807.GA23939@elte.hu>
From: Ingo Molnar <mingo@elte.hu>
Date: Mon, 12 Jun 2006 08:38:07 +0200
> yeah. I'll investigate - it's quite likely that sk_receive_queue.lock
> will have to get per-address family locking rules - right?
That's right.
> Maybe it's enough to introduce a separate key for AF_UNIX alone (and
> still having all other protocols share the locking rules for
> sk_receive_queue.lock) , by reinitializing its spinlock after
> sock_init_data()?
AF_NETLINK and/or AF_PACKET might be in a similar situation
as AF_UNIX.
^ permalink raw reply
* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: David Miller @ 2006-06-12 6:49 UTC (permalink / raw)
To: herbert; +Cc: gerrit, netdev, kaber, jmorris
In-Reply-To: <E1FpfkX-0000EL-00@gondolin.me.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Mon, 12 Jun 2006 16:18:09 +1000
> David Miller <davem@davemloft.net> wrote:
> >
> > Probably a better way to handle this is to correct the
> > INDATAGRAMS value by decrementing it when we notice that
> > the checksum is incorrect in a deferred manner.
>
> I think sunrpc should instead increment the appropriate counters directly
> as otherwise checksum errors won't be recorded correctly for sunrpc packets.
Yeah. Good point. But how much protocol internals do we want to
slide into the ->data_ready() callbacks of such layers? That's ugly
and something we should try to avoid.
^ permalink raw reply
* Re: 2.6.17-rc5-mm3-lockdep -
From: Herbert Xu @ 2006-06-12 6:41 UTC (permalink / raw)
To: Ingo Molnar
Cc: Andrew Morton, linux1394-devel, Valdis.Kletnieks, Jiri Slaby,
netdev, linux-kernel, mingo, Stefan Richter, David S. Miller,
arjan
In-Reply-To: <20060612063807.GA23939@elte.hu>
On Mon, Jun 12, 2006 at 08:38:07AM +0200, Ingo Molnar wrote:
>
> yeah. I'll investigate - it's quite likely that sk_receive_queue.lock
> will have to get per-address family locking rules - right?
Yes that's the issue.
> Maybe it's enough to introduce a separate key for AF_UNIX alone (and
> still having all other protocols share the locking rules for
> sk_receive_queue.lock) , by reinitializing its spinlock after
> sock_init_data()?
This could work. AF_UNIX is probably the only family that does not
interact with hardware.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: 2.6.17-rc5-mm3-lockdep -
From: Ingo Molnar @ 2006-06-12 6:38 UTC (permalink / raw)
To: Herbert Xu
Cc: Andrew Morton, linux1394-devel, Valdis.Kletnieks, Jiri Slaby,
netdev, linux-kernel, mingo, Stefan Richter, David S. Miller,
arjan
In-Reply-To: <20060607071208.GA1951@gondor.apana.org.au>
* Herbert Xu <herbert@gondor.apana.org.au> wrote:
> On Tue, Jun 06, 2006 at 04:39:21PM +0000, Stefan Richter wrote:
> >
> > BTW, the locking in -mm's net/unix/af_unix.c::unix_stream_connect()
> > differs a bit from stock unix_stream_connect(). I see spin_lock_bh() in
> > 2.6.17-rc5-mm3 where 2.6.17-rc5 has spin_lock().
>
> Hi Ingo:
>
> Looks like this change was introduced by the validator patch. Any
> idea why this was done? AF_UNIX is a user-space-driven socket so there
> shouldn't be any need for BH to be disabled there.
yeah. I'll investigate - it's quite likely that sk_receive_queue.lock
will have to get per-address family locking rules - right?
Maybe it's enough to introduce a separate key for AF_UNIX alone (and
still having all other protocols share the locking rules for
sk_receive_queue.lock) , by reinitializing its spinlock after
sock_init_data()?
Ingo
^ permalink raw reply
* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Faidon Liambotis @ 2006-06-11 22:49 UTC (permalink / raw)
To: Dave Jones; +Cc: netdev
In-Reply-To: <20060611224054.GB13139@redhat.com>
On Sun, Jun 11, 2006 at 06:40:54PM -0400, Dave Jones wrote:
> Ah-ha, I had tested the wrong card.
> I also have a Sitecom card, which matches this ident you remove in your patch..
>
> PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
>
<snip>
>
> So with your patch, this card will become totally useless to me.
I think you should forward this bug to the HostAP maintainer. This
should be either be fixed in the driver or the driver should stop
claiming that it supports this card.
I merely found the duplicate IDs and removed them from Orinoco. I don't
have neither the hardware or the time to test 30+ cards...
Having two drivers supporting the same set of hardware seems pretty
pointless to me. Plus, it confuses hotplugging/automatic detection.
Regards,
Faidon
^ permalink raw reply
* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: Herbert Xu @ 2006-06-12 6:18 UTC (permalink / raw)
To: David Miller; +Cc: gerrit, netdev, kaber, jmorris
In-Reply-To: <20060611.212913.70218067.davem@davemloft.net>
David Miller <davem@davemloft.net> wrote:
>
> Probably a better way to handle this is to correct the
> INDATAGRAMS value by decrementing it when we notice that
> the checksum is incorrect in a deferred manner.
I think sunrpc should instead increment the appropriate counters directly
as otherwise checksum errors won't be recorded correctly for sunrpc packets.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: David Miller @ 2006-06-12 6:13 UTC (permalink / raw)
To: gerrit; +Cc: netdev, kaber, jmorris
In-Reply-To: <200606120702.46014@strip-the-willow>
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Mon, 12 Jun 2006 07:02:45 +0100
> This is clearly preferable - would it look like this:
>
> csum_copy_err:
> UDP_INC_STATS_BH(UDP_MIB_INERRORS);
> UDP_DEC_STATS_BH(UDP_MIB_INDATAGRAMS); /* requires new macro */
>
> skb_kill_datagram(sk, skb, flags);
> /* ... */
>
> in udp_recvmsg? Here I must pass - there is no xxx_DEC_BH macro in
> include/net/snmp.h and I don't know whether the following guess is correct:
>
> #define SNMP_DEC_STATS_BH(mib, field) \
> (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]--)
>
> If this is correct, then it seems done; one could use this macro or add
> a corresponding UDP_DEC_STATS_BH to include/net/udp.h .
The index of mib[] in those macros is always "!in_softirq()", the
*_BH() variants use zero for the index because they are called in
contexts where we know that "!in_sortirq()" evaluates to false.
So your SNMP_DEC_STATS_BH() macro is correct.
Can you cook up the patch, which adds your SNMP_DEC_STATS_BH() macro,
the UDP_DEC_STATS_BH counterpart, and the change that uses it in
net/ipv4/udp.c?
I'd appreciate this, thanks a lot.
^ permalink raw reply
* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: Gerrit Renker @ 2006-06-12 6:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, kaber, jmorris
In-Reply-To: <20060611.212913.70218067.davem@davemloft.net>
Quoting David Miller:
|
| > Fix: Move the `UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS)' statement from
| > udp_queue_rcv_skb to udp_recvmsg. Now InDatagrams only counts those
| > datagrams which were really delivered (as per RFC 2013).
| >
|
| Unfortunately this breaks NFS and other in-kernel UDP socket usages,
| which never call recvmsg() and instead take the packet via the
| ->data_ready() callback done by sock_queue_receive_skb().
|
| Your patch will make the counter never get incremented when such
| a user is using the UDP socket.
|
| Probably a better way to handle this is to correct the
| INDATAGRAMS value by decrementing it when we notice that
| the checksum is incorrect in a deferred manner.
This is clearly preferable - would it look like this:
csum_copy_err:
UDP_INC_STATS_BH(UDP_MIB_INERRORS);
UDP_DEC_STATS_BH(UDP_MIB_INDATAGRAMS); /* requires new macro */
skb_kill_datagram(sk, skb, flags);
/* ... */
in udp_recvmsg? Here I must pass - there is no xxx_DEC_BH macro in
include/net/snmp.h and I don't know whether the following guess is correct:
#define SNMP_DEC_STATS_BH(mib, field) \
(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]--)
If this is correct, then it seems done; one could use this macro or add
a corresponding UDP_DEC_STATS_BH to include/net/udp.h .
^ permalink raw reply
* Re: TCP Westwood+ patches
From: David Miller @ 2006-06-12 6:02 UTC (permalink / raw)
To: shemminger; +Cc: ldecicco, netdev, saverio.mascolo
In-Reply-To: <20060606115306.15b52b38@dxpl.pdx.osdl.net>
From: Stephen Hemminger <shemminger@osdl.org>
Date: Tue, 6 Jun 2006 11:53:06 -0700
> I cleaned these up and put them in a git tree.
All 4 patches are in my tree now.
Thanks Stephen.
^ permalink raw reply
* [PATCH netdev-2.6#upstream] net: au1000_eth: netdev_priv() conversion
From: Herbert Valerio Riedel @ 2006-06-12 5:52 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-mips, ppopov, sshtylyov, ralf
convert driver to use netdev_priv(net_device*) instead of accessing ->priv
directly; where applicable, declare the resulting local pointer to be 'const'
Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
---
drivers/net/au1000_eth.c | 51 +++++++++++++++++++++++-----------------------
1 files changed, 25 insertions(+), 26 deletions(-)
505c73271046495d4948bf7b5adc7c4e3b88835d
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 038d5fc..558aae3 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -199,7 +199,7 @@ #endif
*/
static int mdio_read(struct net_device *dev, int phy_addr, int reg)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
volatile u32 *const mii_control_reg = &aup->mac->mii_control;
volatile u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
@@ -233,7 +233,7 @@ static int mdio_read(struct net_device *
static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
volatile u32 *const mii_control_reg = &aup->mac->mii_control;
volatile u32 *const mii_data_reg = &aup->mac->mii_data;
u32 timedout = 20;
@@ -288,7 +288,7 @@ static int mdiobus_reset(struct mii_bus
static int mii_probe (struct net_device *dev)
{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct phy_device *phydev = NULL;
#if defined(AU1XXX_PHY_STATIC_CONFIG)
@@ -419,7 +419,7 @@ void ReleaseDB(struct au1000_private *au
static void enable_rx_tx(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
@@ -430,7 +430,7 @@ static void enable_rx_tx(struct net_devi
static void hard_stop(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk(KERN_INFO "%s: hard stop\n", dev->name);
@@ -442,7 +442,7 @@ static void hard_stop(struct net_device
static void enable_mac(struct net_device *dev, int force_reset)
{
unsigned long flags;
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
spin_lock_irqsave(&aup->lock, flags);
@@ -461,7 +461,7 @@ static void enable_mac(struct net_device
static void reset_mac_unlocked(struct net_device *dev)
{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
int i;
hard_stop(dev);
@@ -487,7 +487,7 @@ static void reset_mac_unlocked(struct ne
static void reset_mac(struct net_device *dev)
{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
unsigned long flags;
if (au1000_debug > 4)
@@ -576,7 +576,7 @@ static int __init au1000_init_module(voi
static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (aup->phy_dev)
return phy_ethtool_gset(aup->phy_dev, cmd);
@@ -586,7 +586,7 @@ static int au1000_get_settings(struct ne
static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -600,7 +600,7 @@ static int au1000_set_settings(struct ne
static void
au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
@@ -657,7 +657,7 @@ static struct net_device * au1000_probe(
printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
dev->name, base, irq);
- aup = dev->priv;
+ aup = netdev_priv(dev);
/* Allocate the data buffers */
/* Snooping works fine with eth on all au1xxx */
@@ -822,7 +822,7 @@ err_out:
*/
static int au1000_init(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
u32 flags;
int i;
u32 control;
@@ -873,7 +873,7 @@ #endif
static void
au1000_adjust_link(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct phy_device *phydev = aup->phy_dev;
unsigned long flags;
@@ -953,7 +953,7 @@ au1000_adjust_link(struct net_device *de
static int au1000_open(struct net_device *dev)
{
int retval;
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk("%s: open: dev=%p\n", dev->name, dev);
@@ -988,7 +988,7 @@ static int au1000_open(struct net_device
static int au1000_close(struct net_device *dev)
{
unsigned long flags;
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk("%s: close: dev=%p\n", dev->name, dev);
@@ -1014,12 +1014,11 @@ static void __exit au1000_cleanup_module
{
int i, j;
struct net_device *dev;
- struct au1000_private *aup;
for (i = 0; i < num_ifs; i++) {
dev = iflist[i].dev;
if (dev) {
- aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
unregister_netdev(dev);
for (j = 0; j < NUM_RX_DMA; j++)
if (aup->rx_db_inuse[j])
@@ -1039,7 +1038,7 @@ static void __exit au1000_cleanup_module
static void update_tx_stats(struct net_device *dev, u32 status)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct net_device_stats *ps = &aup->stats;
if (status & TX_FRAME_ABORTED) {
@@ -1068,7 +1067,7 @@ static void update_tx_stats(struct net_d
*/
static void au1000_tx_ack(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
volatile tx_dma_t *ptxd;
ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -1095,7 +1094,7 @@ static void au1000_tx_ack(struct net_dev
*/
static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct net_device_stats *ps = &aup->stats;
volatile tx_dma_t *ptxd;
u32 buff_stat;
@@ -1149,7 +1148,7 @@ static int au1000_tx(struct sk_buff *skb
static inline void update_rx_stats(struct net_device *dev, u32 status)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct net_device_stats *ps = &aup->stats;
ps->rx_packets++;
@@ -1177,7 +1176,7 @@ static inline void update_rx_stats(struc
*/
static int au1000_rx(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
struct sk_buff *skb;
volatile rx_dma_t *prxd;
u32 buff_stat, status;
@@ -1286,7 +1285,7 @@ static void au1000_tx_timeout(struct net
static void set_rx_mode(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
@@ -1319,7 +1318,7 @@ static void set_rx_mode(struct net_devic
static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (!netif_running(dev)) return -EINVAL;
@@ -1330,7 +1329,7 @@ static int au1000_ioctl(struct net_devic
static struct net_device_stats *au1000_get_stats(struct net_device *dev)
{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ struct au1000_private *const aup = netdev_priv(dev);
if (au1000_debug > 4)
printk("%s: au1000_get_stats: dev=%p\n", dev->name, dev);
--
1.3.2
^ permalink raw reply related
* New and hot Most quality products for anyone who wants to become a champion in bed
From: Rosemarie @ 2006-06-12 5:26 UTC (permalink / raw)
To: newbie-owner
Don't accept limitations on the size of your favorite member Benefit from simple, approved methods that will help you gain more Fuller, harder tools to please her all the night long - and explosive climaxes Notice that happy glow in her eyes after you did all the things that night We got loads of quality and safe products to make your life better http://sexygd.com
Let bygones be bygones No man is an island No one grows old by living; only by losing interest in living There is more than one way to skin a cat Angry Men Make Themselves a Bed of Nettles
^ permalink raw reply
* Re: [ PATCH 2.6.17-rc6 1/1] udp.c: counting InDatagrams which are never delivered
From: David Miller @ 2006-06-12 4:29 UTC (permalink / raw)
To: gerrit; +Cc: netdev, kaber, jmorris
In-Reply-To: <200606061925.40327@this-message-has-been-logged>
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Tue, 6 Jun 2006 19:25:40 +0100
> Fix: Move the `UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS)' statement from
> udp_queue_rcv_skb to udp_recvmsg. Now InDatagrams only counts those
> datagrams which were really delivered (as per RFC 2013).
>
> Please CC: any correspondence to gerrit@erg.abdn.ac.uk
>
> Signed-off-by: <gerrit@erg.abdn.ac.uk>
Unfortunately this breaks NFS and other in-kernel UDP socket usages,
which never call recvmsg() and instead take the packet via the
->data_ready() callback done by sock_queue_receive_skb().
Your patch will make the counter never get incremented when such
a user is using the UDP socket.
Probably a better way to handle this is to correct the
INDATAGRAMS value by decrementing it when we notice that
the checksum is incorrect in a deferred manner.
^ permalink raw reply
* Re: [PATCH] net.ipv4.ip_autoconfig sysctl removal
From: David Miller @ 2006-06-12 4:21 UTC (permalink / raw)
To: shemminger; +Cc: netdev
In-Reply-To: <20060605105831.6a314086@dxpl.pdx.osdl.net>
From: Stephen Hemminger <shemminger@osdl.org>
Date: Mon, 5 Jun 2006 10:58:31 -0700
> The sysctl net.ipv4.ip_autoconfig is a legacy value that is not used.
> Can it finally go in 2.6.18 or do we need to go through the whole
> feature-removal process?
>
> Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
I think killing this on in 2.6.18 is ok, applied.
Thanks.
^ permalink raw reply
* Re: [PATCH] bnx2: endian fixes
From: David Miller @ 2006-06-12 3:57 UTC (permalink / raw)
To: adobriyan; +Cc: netdev, mchan
In-Reply-To: <20060610115250.GA7268@martell.zuzino.mipt.ru>
From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Sat, 10 Jun 2006 15:52:51 +0400
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Applied, thanks Alexey.
^ permalink raw reply
* Re: [PATCH] [IrDA] irda-usb.c: STIR421x cleanups
From: David Miller @ 2006-06-12 3:56 UTC (permalink / raw)
To: samuel; +Cc: netdev, irda-users, nfedchik
In-Reply-To: <20060612061235.GB3736@sortiz.org>
From: Samuel Ortiz <samuel@sortiz.org>
Date: Mon, 12 Jun 2006 09:12:35 +0300
> This patch is for the net-2.6.18 tree.
> It cleans the STIR421x part of the irda-usb code. We also no longer try to
> load all existing firmwares but only the matching one (according to the USB
> id we get from the dongle).
>
> Signed-off-by: Nick Fedchik <nfedchik@atlantic-link.com.ua>
> Signed-off-by: Samuel Ortiz <samuel@sortiz.org>
Applied, thanks a lot.
^ permalink raw reply
* Re: [PATCH netdev-2.6#upstream] net: au1000_eth: PHY framework conversion
From: Jeff Garzik @ 2006-06-12 3:19 UTC (permalink / raw)
To: Herbert Valerio Riedel; +Cc: netdev, linux-mips, ppopov, sshtylyov, ralf
In-Reply-To: <E1Fli0i-0006o2-Tb@fencepost.gnu.org>
Herbert Valerio Riedel wrote:
> convert au1000_eth driver to use PHY framework and garbage collected
> functions and identifiers that became unused/obsolete in the process
>
> Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
applied
^ permalink raw reply
* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-12 1:11 UTC (permalink / raw)
To: Johannes Berg; +Cc: netdev
In-Reply-To: <1149867292.3864.30.camel@johannes.berg>
Johannes Berg wrote:
> On Fri, 2006-06-09 at 10:31 -0500, Larry Finger wrote:
>
>> Do you mean a special dump, or is the kernel debug output and wpa_supplicant debug output sufficient?
>
> I was thinking of packet dumps but earlier you said you couldn't create
> any so I'm out of ideas for now.
I was finally able to get my second laptop running with bcm43xx so I could get packet dumps. When I
analyzed them, the Association Response packet contained the following information:
"Association denied due to requesting station not supporting short preamble operation (0x0013)"
I think this is a bug in the code on my WRT54G V5 and I will report it to Linksys; however, in the
meantime, I am able to connect using the following _ugly_ hack to softmac_assoc_req and
softmac_reassoc_req:
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index cc6cd56..a1d0c10 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -199,6 +199,8 @@ ieee80211softmac_assoc_req(struct ieee80
(*pkt)->capability |= mac->ieee->short_slot ?
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
*/
+ /* add short preamble operation capability */
+ (*pkt)->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
(*pkt)->capability |= mac->ieee->sec.level ? cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
/* Fill in Listen Interval (?) */
(*pkt)->listen_interval = cpu_to_le16(10);
@@ -247,6 +249,8 @@ ieee80211softmac_reassoc_req(struct ieee
(*pkt)->capability |= mac->ieee->short_slot ?
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
*/
+ /* add short preamble operation capability */
+ (*pkt)->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
(*pkt)->capability |= mac->ieee->sec.level ?
cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
I expect that softmac should be listening to the driver as to whether this capability is available;
however, I'm now up and running once again.
Larry
^ permalink raw reply related
* Remove useless check for null dev from uli526x_interrupt()
From: Dave Jones @ 2006-06-12 0:27 UTC (permalink / raw)
To: netdev
As we're already dereferencing dev a few lines above, if this
check could ever trigger, we'd have already oopsed.
Signed-off-by: Dave Jones <davej@redhat.com>
--- linux-2.6/drivers/net/tulip/uli526x.c~ 2006-06-11 20:24:41.000000000 -0400
+++ linux-2.6/drivers/net/tulip/uli526x.c 2006-06-11 20:25:14.000000000 -0400
@@ -666,11 +666,6 @@ static irqreturn_t uli526x_interrupt(int
unsigned long ioaddr = dev->base_addr;
unsigned long flags;
- if (!dev) {
- ULI526X_DBUG(1, "uli526x_interrupt() without DEVICE arg", 0);
- return IRQ_NONE;
- }
-
spin_lock_irqsave(&db->lock, flags);
outl(0, ioaddr + DCR7);
^ permalink raw reply
* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Neil Horman @ 2006-06-12 0:13 UTC (permalink / raw)
To: Jeff Moyer
Cc: Mitch Williams, Kok, Auke-jan H, Matt Mackall, Garzik, Jeff,
netdev, Brandeburg, Jesse, Kok, Auke
In-Reply-To: <x49ac8nwo83.fsf@redhat.com>
On Thu, Jun 08, 2006 at 01:29:00PM -0400, Jeff Moyer wrote:
> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Mitch Williams <mitch.a.williams@intel.com> adds:
>
> mitch.a.williams> On Wed, 2006-06-07 at 11:44 -0700, Jeff Moyer wrote:
> >> That patch locks around the tx clean routine. As such, it doesn't
> >> prevent the problem.
>
> mitch.a.williams> The call to netif_rx_schedule_prep provides locking
> mitch.a.williams> because it sets the __LINK_STATE_RX_SCHED bit atomically.
> mitch.a.williams> The spinlock around e1000_clean_tx_irq is to protect it
> mitch.a.williams> from other calls to the transmit routine, not NAPI.
>
> Yes, but what prevents recursion in the poll routine? Consider that the
> poll routine could end up triggerring a printk (think iptables, here). In
> that case, you end up calling into netpoll, and if the tx ring is full, we
> call the poll_controller routine. We've now recursed.
>
> The poll lock was originally introduced to prevent recursion, not
> concurrent access.
>
Any further thoughts on this guys? I still think my last solution solves all of
the netpoll problems, and isn't going to have any noticable impact on
performance.
Regards
Neil
> -Jeff
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFT] Realtek 8168 ethernet support
From: Francois Romieu @ 2006-06-11 23:30 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Randy.Dunlap, Daniel Drake, netdev
In-Reply-To: <20060610224811.GA3256@electric-eye.fr.zoreil.com>
The patch below agaisnt 2.6.17-rc6 includes the following changes:
commit 3072cc0aba3ac0c944e196a63c4154ca5746ec0b
r8169: sync with vendor's driver
- add several PCI ID for the PCI-E adapters ;
- new identification strings ;
- the RTL_GIGA_MAC_VER_ defines have been renamed to closely match the
out-of-tree driver. It makes the comparison less hairy ;
- various magic ;
- the PCI region for the device with PCI ID 0x8136 is guessed.
Explanation: the in-kernel Linux driver is written to allow MM register
accesses and avoid the IO tax. The relevant BAR register was found at
base address 1 for the plain-old PCI 8169. User reported lspci show that
it is found at base address 2 for the new Gigabit PCI-E 816{8/9}.
Typically:
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.: Unknown device 8168 (rev 01)
Subsystem: Unknown device 1631:e015
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, cache line size 20
Interrupt: pin A routed to IRQ 16
Region 0: I/O ports at b800 [size=256]
Region 2: Memory at ff7ff000 (64-bit, non-prefetchable) [size=4K]
^^^^^^^^
So far I have not received any lspci report for the 0x8136 and
Realtek's driver do not help: be it under BSD or Linux, their r1000 driver
include a USE_IO_SPACE #define but the bar address is always hardcoded
to 1 in the MM case. :o/
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
commit 33857396c4f7d171f4ccaca86356df5fe2fdd304
r8169: remove rtl8169_init_board
Rationale:
- its signature is not exactly pretty;
- it has no knowledge of pci_device_id;
- kiss 23 lines good bye.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
commit af50f4372644c3c18c2af697a933c90f2a96be77
r8169: hardware flow control
The datasheet suggests that the device handles the hardware flow
control almost automagically. User report a different story, so
let's try to twiddle the mii registers.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
commit d1e6ebbea2297df970e52823e1d8c9af62b0548d
r8169: RX fifo overflow recovery
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
commit 17fb3bf33149eb2cb1a37ff94ab236ab01f91a40
r8169: mac address change support
Fix for http://bugzilla.kernel.org/show_bug.cgi?id=6032.
Cc: Tim Mattox <tmattox@gmail.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
The patch is for review only: mac address change apart, I need to
test it and it will surely conflict with jeff#netdev because of a
recently added PCI ID.
The patches are available at:
http://www.fr.zoreil.com/linux/kernel/2.6.x/2.6.17-rc6/r8169
or:
git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6.git r8169
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0ad3310..53a33c5 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -150,11 +150,16 @@ #define RTL_R16(reg) readw (ioaddr + (r
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
enum mac_version {
- RTL_GIGA_MAC_VER_B = 0x00,
- /* RTL_GIGA_MAC_VER_C = 0x03, */
- RTL_GIGA_MAC_VER_D = 0x01,
- RTL_GIGA_MAC_VER_E = 0x02,
- RTL_GIGA_MAC_VER_X = 0x04 /* Greater than RTL_GIGA_MAC_VER_E */
+ RTL_GIGA_MAC_VER_01 = 0x00,
+ RTL_GIGA_MAC_VER_02 = 0x01,
+ RTL_GIGA_MAC_VER_03 = 0x02,
+ RTL_GIGA_MAC_VER_04 = 0x03,
+ RTL_GIGA_MAC_VER_05 = 0x04,
+ RTL_GIGA_MAC_VER_11 = 0x0b,
+ RTL_GIGA_MAC_VER_12 = 0x0c,
+ RTL_GIGA_MAC_VER_13 = 0x0d,
+ RTL_GIGA_MAC_VER_14 = 0x0e,
+ RTL_GIGA_MAC_VER_15 = 0x0f
};
enum phy_version {
@@ -166,7 +171,6 @@ enum phy_version {
RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
};
-
#define _R(NAME,MAC,MASK) \
{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
@@ -175,18 +179,28 @@ static const struct {
u8 mac_version;
u32 RxConfigMask; /* Clears the bits supported by this chip */
} rtl_chip_info[] = {
- _R("RTL8169", RTL_GIGA_MAC_VER_B, 0xff7e1880),
- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_D, 0xff7e1880),
- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_E, 0xff7e1880),
- _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_X, 0xff7e1880),
+ _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880),
+ _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880),
+ _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880),
+ _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880),
+ _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880),
+ _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
+ _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
+ _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
+ _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
+ _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880) // PCI-E 8139
};
#undef _R
static struct pci_device_id rtl8169_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), },
- { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), },
- { PCI_DEVICE(0x16ec, 0x0116), },
- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, 2 },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, 2 },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, 2 },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, 1 },
+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, 1 },
+ { PCI_DEVICE(0x16ec, 0x0116), 0, 0, 1 },
+ { PCI_VENDOR_ID_LINKSYS, 0x1032,
+ PCI_ANY_ID, 0x0024, 0, 0, 1 },
{0,},
};
@@ -256,10 +270,11 @@ enum RTL8169_register_content {
RxOK = 0x01,
/* RxStatusDesc */
- RxRES = 0x00200000,
- RxCRC = 0x00080000,
- RxRUNT = 0x00100000,
- RxRWT = 0x00400000,
+ RxFOVF = (1 << 23),
+ RxRWT = (1 << 22),
+ RxRES = (1 << 21),
+ RxRUNT = (1 << 20),
+ RxCRC = (1 << 19),
/* ChipCmdBits */
CmdReset = 0x10,
@@ -345,6 +360,7 @@ enum RTL8169_register_content {
PHY_Cap_100_Full = 0x0100,
/* PHY_1000_CTRL_REG = 9 */
+ PHY_Cap_1000_Half = 0x0100,
PHY_Cap_1000_Full = 0x0200,
PHY_Cap_Null = 0x0,
@@ -748,27 +764,47 @@ static int rtl8169_set_speed_xmii(struct
auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full |
PHY_Cap_100_Half | PHY_Cap_100_Full);
giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG);
- giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null);
+ giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half | PHY_Cap_Null);
if (autoneg == AUTONEG_ENABLE) {
auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full |
PHY_Cap_100_Half | PHY_Cap_100_Full);
- giga_ctrl |= PHY_Cap_1000_Full;
+ giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
} else {
if (speed == SPEED_10)
auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full;
else if (speed == SPEED_100)
auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full;
else if (speed == SPEED_1000)
- giga_ctrl |= PHY_Cap_1000_Full;
+ giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
if (duplex == DUPLEX_HALF)
auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
if (duplex == DUPLEX_FULL)
auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
+
+ /* This tweak comes straight from Realtek's driver. */
+ if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
+ (tp->mac_version == RTL_GIGA_MAC_VER_13)) {
+ auto_nego = PHY_Cap_100_Half | 0x01;
+ }
}
+ /* The 8100e/8101e do Fast Ethernet only. */
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+ if ((giga_ctrl & (PHY_Cap_1000_Full | PHY_Cap_1000_Half)) &&
+ netif_msg_link(tp)) {
+ printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
+ dev->name);
+ }
+ giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half);
+ }
+
+ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
@@ -960,6 +996,11 @@ static void rtl8169_gset_xmii(struct net
else if (status & _10bps)
cmd->speed = SPEED_10;
+ if (status & TxFlowCtrl)
+ cmd->advertising |= ADVERTISED_Asym_Pause;
+ if (status & RxFlowCtrl)
+ cmd->advertising |= ADVERTISED_Pause;
+
cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
DUPLEX_FULL : DUPLEX_HALF;
}
@@ -1139,10 +1180,16 @@ static void rtl8169_get_mac_version(stru
u32 mask;
int mac_version;
} mac_info[] = {
- { 0x1 << 28, RTL_GIGA_MAC_VER_X },
- { 0x1 << 26, RTL_GIGA_MAC_VER_E },
- { 0x1 << 23, RTL_GIGA_MAC_VER_D },
- { 0x00000000, RTL_GIGA_MAC_VER_B } /* Catch-all */
+ { 0x38800000, RTL_GIGA_MAC_VER_15 },
+ { 0x38000000, RTL_GIGA_MAC_VER_12 },
+ { 0x34000000, RTL_GIGA_MAC_VER_13 },
+ { 0x30800000, RTL_GIGA_MAC_VER_14 },
+ { 0x30000000, RTL_GIGA_MAC_VER_11 },
+ { 0x18000000, RTL_GIGA_MAC_VER_05 },
+ { 0x10000000, RTL_GIGA_MAC_VER_04 },
+ { 0x04000000, RTL_GIGA_MAC_VER_03 },
+ { 0x00800000, RTL_GIGA_MAC_VER_02 },
+ { 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */
}, *p = mac_info;
u32 reg;
@@ -1154,24 +1201,7 @@ static void rtl8169_get_mac_version(stru
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
{
- struct {
- int version;
- char *msg;
- } mac_print[] = {
- { RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" },
- { RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" },
- { RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" },
- { 0, NULL }
- }, *p;
-
- for (p = mac_print; p->msg; p++) {
- if (tp->mac_version == p->version) {
- dprintk("mac_version == %s (%04d)\n", p->msg,
- p->version);
- return;
- }
- }
- dprintk("mac_version == Unknown\n");
+ dprintk("mac_version = 0x%02x\n", tp->mac_version);
}
static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
@@ -1256,7 +1286,7 @@ static void rtl8169_hw_phy_config(struct
rtl8169_print_mac_version(tp);
rtl8169_print_phy_version(tp);
- if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
+ if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
return;
if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
return;
@@ -1266,7 +1296,7 @@ static void rtl8169_hw_phy_config(struct
/* Shazam ! */
- if (tp->mac_version == RTL_GIGA_MAC_VER_X) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
mdio_write(ioaddr, 31, 0x0001);
mdio_write(ioaddr, 9, 0x273a);
mdio_write(ioaddr, 14, 0x7bfb);
@@ -1305,7 +1335,7 @@ static void rtl8169_phy_timer(unsigned l
void __iomem *ioaddr = tp->mmio_addr;
unsigned long timeout = RTL8169_PHY_TIMEOUT;
- assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
+ assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
@@ -1341,7 +1371,7 @@ static inline void rtl8169_delete_timer(
struct rtl8169_private *tp = netdev_priv(dev);
struct timer_list *timer = &tp->timer;
- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+ if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
(tp->phy_version >= RTL_GIGA_PHY_VER_H))
return;
@@ -1353,7 +1383,7 @@ static inline void rtl8169_request_timer
struct rtl8169_private *tp = netdev_priv(dev);
struct timer_list *timer = &tp->timer;
- if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+ if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
(tp->phy_version >= RTL_GIGA_PHY_VER_H))
return;
@@ -1381,6 +1411,41 @@ static void rtl8169_netpoll(struct net_d
}
#endif
+static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr)
+{
+ unsigned int i, j;
+
+ RTL_W8(Cfg9346, Cfg9346_Unlock);
+ for (i = 0; i < 2; i++) {
+ __le32 l = 0;
+
+ for (j = 0; j < 4; j++) {
+ l <<= 8;
+ l |= dev->dev_addr[4*i + j];
+ }
+ RTL_W32(MAC0 + 4*i, cpu_to_be32(l));
+ }
+ RTL_W8(Cfg9346, Cfg9346_Lock);
+}
+
+static int rtl8169_set_mac_addr(struct net_device *dev, void *p)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ if (netif_running(dev)) {
+ spin_lock_irq(&tp->lock);
+ __rtl8169_set_mac_addr(dev, tp->mmio_addr);
+ spin_unlock_irq(&tp->lock);
+ }
+ return 0;
+}
+
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
void __iomem *ioaddr)
{
@@ -1390,23 +1455,61 @@ static void rtl8169_release_board(struct
free_netdev(dev);
}
+static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ static int board_idx = -1;
+ u8 autoneg, duplex;
+ u16 speed;
+
+ board_idx++;
+
+ rtl8169_hw_phy_config(dev);
+
+ dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+ RTL_W8(0x82, 0x01);
+
+ if (tp->mac_version < RTL_GIGA_MAC_VER_03) {
+ dprintk("Set PCI Latency=0x40\n");
+ pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
+ }
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
+ dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+ RTL_W8(0x82, 0x01);
+ dprintk("Set PHY Reg 0x0bh = 0x00h\n");
+ mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
+ }
+
+ rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
+
+ rtl8169_set_speed(dev, autoneg, speed, duplex);
+
+ if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
+ printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+}
+
static int __devinit
-rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
- void __iomem **ioaddr_out)
+rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- void __iomem *ioaddr;
- struct net_device *dev;
+ const unsigned int region = ent->driver_data;
struct rtl8169_private *tp;
- int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap;
+ struct net_device *dev;
+ void __iomem *ioaddr;
+ unsigned int i, pm_cap;
+ int rc;
- assert(ioaddr_out != NULL);
+ if (netif_msg_drv(&debug)) {
+ printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
+ MODULENAME, RTL8169_VERSION);
+ }
- /* dev zeroed in alloc_etherdev */
dev = alloc_etherdev(sizeof (*tp));
- if (dev == NULL) {
+ if (!dev) {
if (netif_msg_drv(&debug))
printk(KERN_ERR PFX "unable to alloc new ethernet\n");
- goto err_out;
+ rc = -ENOMEM;
+ goto out;
}
SET_MODULE_OWNER(dev);
@@ -1421,17 +1524,17 @@ rtl8169_init_board(struct pci_dev *pdev,
printk(KERN_ERR PFX "%s: enable failure\n",
pci_name(pdev));
}
- goto err_out_free_dev;
+ goto err_out_free_dev_1;
}
rc = pci_set_mwi(pdev);
if (rc < 0)
- goto err_out_disable;
+ goto err_out_disable_2;
/* save power state before pci_enable_device overwrites it */
pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
if (pm_cap) {
- u16 pwr_command;
+ u16 pwr_command, acpi_idle_state;
pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
@@ -1443,22 +1546,24 @@ rtl8169_init_board(struct pci_dev *pdev,
}
/* make sure PCI base addr 1 is MMIO */
- if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
+ if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
- "region #1 not an MMIO resource, aborting\n");
+ "region #%d not an MMIO resource, aborting\n",
+ region);
}
rc = -ENODEV;
- goto err_out_mwi;
+ goto err_out_mwi_3;
}
+
/* check for weird/broken PCI region reporting */
- if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
+ if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
"Invalid PCI region size(s), aborting\n");
}
rc = -ENODEV;
- goto err_out_mwi;
+ goto err_out_mwi_3;
}
rc = pci_request_regions(pdev, MODULENAME);
@@ -1467,7 +1572,7 @@ rtl8169_init_board(struct pci_dev *pdev,
printk(KERN_ERR PFX "%s: could not request regions.\n",
pci_name(pdev));
}
- goto err_out_mwi;
+ goto err_out_mwi_3;
}
tp->cp_cmd = PCIMulRW | RxChkSum;
@@ -1483,19 +1588,19 @@ rtl8169_init_board(struct pci_dev *pdev,
printk(KERN_ERR PFX
"DMA configuration failed.\n");
}
- goto err_out_free_res;
+ goto err_out_free_res_4;
}
}
pci_set_master(pdev);
/* ioremap MMIO region */
- ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
- if (ioaddr == NULL) {
+ ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
+ if (!ioaddr) {
if (netif_msg_probe(tp))
printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
rc = -EIO;
- goto err_out_free_res;
+ goto err_out_free_res_4;
}
/* Unneeded ? Don't mess with Mrs. Murphy. */
@@ -1538,56 +1643,6 @@ rtl8169_init_board(struct pci_dev *pdev,
RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
RTL_W8(Cfg9346, Cfg9346_Lock);
- *ioaddr_out = ioaddr;
- *dev_out = dev;
-out:
- return rc;
-
-err_out_free_res:
- pci_release_regions(pdev);
-
-err_out_mwi:
- pci_clear_mwi(pdev);
-
-err_out_disable:
- pci_disable_device(pdev);
-
-err_out_free_dev:
- free_netdev(dev);
-err_out:
- *ioaddr_out = NULL;
- *dev_out = NULL;
- goto out;
-}
-
-static int __devinit
-rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct net_device *dev = NULL;
- struct rtl8169_private *tp;
- void __iomem *ioaddr = NULL;
- static int board_idx = -1;
- u8 autoneg, duplex;
- u16 speed;
- int i, rc;
-
- assert(pdev != NULL);
- assert(ent != NULL);
-
- board_idx++;
-
- if (netif_msg_drv(&debug)) {
- printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
- MODULENAME, RTL8169_VERSION);
- }
-
- rc = rtl8169_init_board(pdev, &dev, &ioaddr);
- if (rc)
- return rc;
-
- tp = netdev_priv(dev);
- assert(ioaddr != NULL);
-
if (RTL_R8(PHYstatus) & TBI_Enable) {
tp->set_speed = rtl8169_set_speed_tbi;
tp->get_settings = rtl8169_gset_tbi;
@@ -1616,6 +1671,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
dev->stop = rtl8169_close;
dev->tx_timeout = rtl8169_tx_timeout;
dev->set_multicast_list = rtl8169_set_rx_mode;
+ dev->set_mac_address = rtl8169_set_mac_addr;
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
@@ -1643,15 +1699,8 @@ #endif
spin_lock_init(&tp->lock);
rc = register_netdev(dev);
- if (rc) {
- rtl8169_release_board(pdev, dev, ioaddr);
- return rc;
- }
-
- if (netif_msg_probe(tp)) {
- printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
- dev->name, rtl_chip_info[tp->chipset].name);
- }
+ if (rc < 0)
+ goto err_out_unmap_5;
pci_set_drvdata(pdev, dev);
@@ -1660,38 +1709,29 @@ #endif
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
"IRQ %d\n",
dev->name,
- rtl_chip_info[ent->driver_data].name,
+ rtl_chip_info[tp->chipset].name,
dev->base_addr,
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5], dev->irq);
}
- rtl8169_hw_phy_config(dev);
-
- dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
- RTL_W8(0x82, 0x01);
-
- if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
- dprintk("Set PCI Latency=0x40\n");
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
- }
+ rtl8169_init_phy(dev, tp);
- if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
- dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
- RTL_W8(0x82, 0x01);
- dprintk("Set PHY Reg 0x0bh = 0x00h\n");
- mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
- }
-
- rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
-
- rtl8169_set_speed(dev, autoneg, speed, duplex);
-
- if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
- printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+out:
+ return rc;
- return 0;
+err_out_unmap_5:
+ iounmap(ioaddr);
+err_out_free_res_4:
+ pci_release_regions(pdev);
+err_out_mwi_3:
+ pci_clear_mwi(pdev);
+err_out_disable_2:
+ pci_disable_device(pdev);
+err_out_free_dev_1:
+ free_netdev(dev);
+ goto out;
}
static void __devexit
@@ -1787,6 +1827,7 @@ rtl8169_hw_start(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+ struct pci_dev *pdev = tp->pci_dev;
u32 i;
/* Soft reset the chip. */
@@ -1799,8 +1840,28 @@ rtl8169_hw_start(struct net_device *dev)
udelay(10);
}
+ if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+ pci_write_config_word(pdev, 0x68, 0x00);
+ pci_write_config_word(pdev, 0x69, 0x08);
+ }
+
+ /* Undocumented stuff. */
+ if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+ u16 cmd;
+
+ /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
+ if ((RTL_R8(Config2) & 0x07) & 0x01)
+ RTL_W32(0x7c, 0x0007ffff);
+
+ RTL_W32(0x7c, 0x0007ff00);
+
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ cmd = cmd & 0xef;
+ pci_write_config_word(pdev, PCI_COMMAND, cmd);
+ }
+
+
RTL_W8(Cfg9346, Cfg9346_Unlock);
- RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(EarlyTxThres, EarlyTxThld);
/* Low hurts. Let's disable the filtering. */
@@ -1815,17 +1876,18 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W32(TxConfig,
(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
TxInterFrameGapShift));
- tp->cp_cmd |= RTL_R16(CPlusCmd);
- RTL_W16(CPlusCmd, tp->cp_cmd);
- if ((tp->mac_version == RTL_GIGA_MAC_VER_D) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_E)) {
+ tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW;
+
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
"Bit-3 and bit-14 MUST be 1\n");
- tp->cp_cmd |= (1 << 14) | PCIMulRW;
- RTL_W16(CPlusCmd, tp->cp_cmd);
+ tp->cp_cmd |= (1 << 14);
}
+ RTL_W16(CPlusCmd, tp->cp_cmd);
+
/*
* Undocumented corner. Supposedly:
* (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
@@ -1836,6 +1898,7 @@ rtl8169_hw_start(struct net_device *dev)
RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W8(Cfg9346, Cfg9346_Lock);
udelay(10);
@@ -1849,6 +1912,8 @@ rtl8169_hw_start(struct net_device *dev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16(IntrMask, rtl8169_intr_mask);
+ __rtl8169_set_mac_addr(dev, ioaddr);
+
netif_start_queue(dev);
}
@@ -2435,6 +2500,10 @@ rtl8169_rx_interrupt(struct net_device *
tp->stats.rx_length_errors++;
if (status & RxCRC)
tp->stats.rx_crc_errors++;
+ if (status & RxFOVF) {
+ rtl8169_schedule_work(dev, rtl8169_reset_task);
+ tp->stats.rx_fifo_errors++;
+ }
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
} else {
struct sk_buff *skb = tp->Rx_skbuff[entry];
@@ -2724,6 +2793,15 @@ rtl8169_set_rx_mode(struct net_device *d
tmp = rtl8169_rx_config | rx_mode |
(RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+ mc_filter[0] = 0xffffffff;
+ mc_filter[1] = 0xffffffff;
+ }
+
RTL_W32(RxConfig, tmp);
RTL_W32(MAR0 + 0, mc_filter[0]);
RTL_W32(MAR0 + 4, mc_filter[1]);
^ permalink raw reply related
* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Dave Jones @ 2006-06-11 23:08 UTC (permalink / raw)
To: Kyle McMartin; +Cc: Faidon Liambotis, netdev
In-Reply-To: <20060611223140.GB1163@skunkworks.cabal.ca>
On Sun, Jun 11, 2006 at 06:31:40PM -0400, Kyle McMartin wrote:
> On Sun, Jun 11, 2006 at 06:40:54PM -0400, Dave Jones wrote:
> > Under hostap, it's a brick, it won't even report any scanning results.
> >
>
> Did you switch it into managed mode? The hostap driver, iirc, defaults
> to running in master (AP) mode.
Ah, yes, that gets it able to scan again, thanks.
This is another gotcha that is going to prevent a smooth transition
from orinoco->hostap for end users though.
Dave
--
http://www.codemonkey.org.uk
^ 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