Netdev List
 help / color / mirror / Atom feed
* Re: Oops in 2.6.23-rc5
From: Christian Kujau @ 2007-09-02 12:12 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-kernel, netdev, torvalds, davem
In-Reply-To: <E1IRgwF-0004G0-00@gondolin.me.apana.org.au>

On Sun, 2 Sep 2007, Herbert Xu wrote:
> You want this patch (by davem).

I applied the patch and the box is up for 1hr now. Since I was able to 
reproduce the oops pretty reliable with this bittorrent thingy, I 
did the same a few times now, but the box did NOT crash :)

> Unfortunately people are travelling so I'm not sure when it'll
> get picked up by Linus.

I've seen this patch only in:
http://article.gmane.org/gmane.linux.network/70781

And, for the archives, a simliar looking error report:
http://article.gmane.org/gmane.linux.network/70777

Thanks for the quick reply, Herbert!

Christian.
-- 
BOFH excuse #297:

Too many interrupts

^ permalink raw reply

* Re: [OOPS] 2.6.23-rc5 ? network/via-rhine [was: hang with CONFIG_MCYRIXIII]
From: Satyam Sharma @ 2007-09-02 12:18 UTC (permalink / raw)
  To: Mark Hindley; +Cc: Linux Kernel Mailing List, rl, netdev
In-Reply-To: <20070902113637.GA3160@hindley.org.uk>



On Sun, 2 Sep 2007, Mark Hindley wrote:
> 
> BUG: unable to handle kernel NULL pointer dereference at virtual address 00000025            
> [...]
> Call Trace:
>  [<c0259b1b>] tcp_rtt_estimator+0xba/0x100
> [...]
> EIP: [<c0259a57>] tcp_rto_min+0x8/0x12 SS:ESP 0068:c0341dec

Third report of this oops within past few hours :-)

You want the patch available at:

(very long URL)
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=blobdiff;f=net/ipv4/tcp_input.c;h=bbad2cdb74b7c18c0ae742be241857b126f06890;hp=1ee72127462bf37ed5ef834ebc71111b1cf070d5;hb=5c127c58ae9bf196d787815b1bd6b0aec5aee816;hpb=88282c6ecf0dacefda6090b0289d35e8a3cc6221

^ permalink raw reply

* Re: Fwd: That whole "Linux stealing our code" thing
From: Adrian Bunk @ 2007-09-02 11:50 UTC (permalink / raw)
  To: Igor Sobrado
  Cc: Alan Cox, Constantine A. Murenin, Jeff Garzik,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Slaby
In-Reply-To: <Pine.LNX.4.64.0709021303001.4312-wnk7FUYfzmtu2DZcH3qp6zJQgOOX0AMFMQBsIrBqeMw@public.gmane.org>

On Sun, Sep 02, 2007 at 01:20:27PM +0200, Igor Sobrado wrote:
> On Sun, 2 Sep 2007, Alan Cox wrote:
>> You can shout this all you like but you would be wrong. You can remove
>> the licence if you have permission to do so. For the ath c files there
>> was permission to do so.
>
> There was permission to do so from Reyk Floeter?  Really?
>
>> Your understanding isn't quite right. One of many things you may get with
>> dual licensed code is the right to pick a licence from several choices,
>> you may also get the right to remove some choices from the recipient.
>
> Reyk code was never dual licensed!  His code is under truly free licensing 
> terms (BSD).

Jiri's patch touched both files containing BSD-only code by Reyk and 
code Reyk contributed to leaving the file dual licenced.

>> A work that combines GPL and BSD licensed material is not the same as a
>> work which says I may choose between two licences. If both licences must
>> always apply (which is a perfectly possible condition to put in a
>> licence) then putting such a "both" GPL/BSD licence piece of code into
>> OpenBSD would require any OpenBSD distributed containing it was GPL
>> licenced when conveyed, which I am *very* sure is not the intent.
>>
>> Thus what you appear to be doing by putting the ath5k C code in OpenBSD is
>> conveying it under the BSD licence (making a choice between the two
>> offered) and conveying a right for parties down the chain to convey it
>> under one of the licences only.
>
> I think that Theo explained this point clearly quite a few times in the 
> last days.
>
>> And as we've already established the header files are quite different.
>
> Is a simple change in the header files a reason to vindicate the people 
> that changed the licensing terms?  Obviously, it isn't.
>
>> Doesn't mean its not somewhat rude but illegal and rude are two very
>> different things.
>
> No, because this change is both rude and illegal.

You mixed two completely different things in your email:

1. Jiri's patch (that was never merged into Linux) not only removed the 
   BSD header from dual licenced files but also from not dual licenced
   files.

2. Theo accused Alan that telling people that it was OK to choose one 
   licence for dual licenced code was "advising people to break the law".

Jiri's patch was legally not OK regarding 1. - there's no discussion 
regarding this.

The point 2 is what the email of Theo that was forwarded to linux-kernel 
is about and what the discussion is about. That's quite a rude action 
by Theo unless he's able to prove that this accusation is correct.

> Igor

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: Fwd: That whole "Linux stealing our code" thing
From: Jan Engelhardt @ 2007-09-02 11:40 UTC (permalink / raw)
  To: Theo de Raadt; +Cc: Bob Beck, linux-kernel, linux-wireless, netdev
In-Reply-To: <200709020036.l820aaNf014181@cvs.openbsd.org>


On Sep 1 2007 18:36, Theo de Raadt wrote:
>
>When companies have taken our wireless device drivers, many many of
>them have given changes and fixes back.  Some maybe didn't, but that
>is OK.

For companies it's ok, but for linux people it is not?

(1) You do not know how much of the modifications companies did
    are actually returned

(2) You do not know whether the ath5k linux part authors will
    give back at a later point (much like companies)


^ permalink raw reply

* Re: Ethernet weirdness on 82xx
From: Denys @ 2007-09-02 11:14 UTC (permalink / raw)
  To: Rune Torgersen, linuxppc-embedded, netdev
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B0353A6AB@ismail.innsys.innovsys.com>

Sorry  forgot, maybe also arp_ignore is related to that

--
Denys Fedoryshchenko
Technical Manager
Virtual ISP S.A.L.


^ permalink raw reply

* Re: Ethernet weirdness on 82xx
From: Denys @ 2007-09-02 11:12 UTC (permalink / raw)
  To: Rune Torgersen, linuxppc-embedded, netdev
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B0353A6AB@ismail.innsys.innovsys.com>

Thats normal.
Check arp_filter sysctl :
arp_filter - BOOLEAN
        1 - Allows you to have multiple network interfaces on the same
        subnet, and have the ARPs for each interface be answered
        based on whether or not the kernel would route a packet from
        the ARP'd IP out that interface (therefore you must use source
        based routing for this to work). In other words it allows control
        of which cards (usually 1) will respond to an arp request.

        0 - (default) The kernel can respond to arp requests with addresses
        from other interfaces. This may seem wrong but it usually makes
        sense, because it increases the chance of successful communication.
        IP addresses are owned by the complete host on Linux, not by
        particular interfaces. Only for more complex setups like load-
        balancing, does this behaviour cause problems.

        arp_filter for the interface will be enabled if at least one of
        conf/{all,interface}/arp_filter is set to TRUE,
        it will be disabled otherwise

IMHO default setting can mess up things in some conditions.

On Fri, 31 Aug 2007 16:35:19 -0500, Rune Torgersen wrote
> I'm not sure if this is by design or an actual bug.
> 
> We have a system witb an 8280 with two active ethernets (fcc2 and 
> fcc3) We are running kernel 2.6.18.1 (and won't be upgrading in a 
> while) out of arch/ppc
> 
> Eth0 and eth1 are in totally different subnets.
> We happened to have both ehternets connected to the same network,
>  and I ran a arping agains the IP on eth0. Both ports (eth0 and eth1)
>  responded with the same address, but different macs....
> 
> sudo /sbin/arping -c1 172.23.12.114
> ARPING 172.23.12.114 from 172.23.15.21 eth0
> Unicast reply from 172.23.12.114 [00:30:D7:00:14:55]  0.838ms
> Unicast reply from 172.23.12.114 [00:30:D7:00:14:54]  0.890ms
> Sent 1 probes (1 broadcast(s))
> Received 2 response(s)
> 
> It only gets both responses on the first (broadcast) query from 
> arping All responses afterward is then from the wrong port....
> 
> The ethernet setup on the target box:
> 
> eth0      Link encap:Ethernet  HWaddr 00:30:D7:00:14:54
>           inet addr:172.23.12.114  Bcast:172.23.15.255
> Mask:255.255.248.0
>           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
>           RX packets:473244 errors:0 dropped:2 overruns:0 frame:0
>           TX packets:186655 errors:0 dropped:0 overruns:0 carrier:0
>           collisions:0 txqueuelen:1000
>           RX bytes:162928671 (155.3 Mb)  TX bytes:42222862 (40.2 Mb)
>           Base address:0x8500
> 
> eth1      Link encap:Ethernet  HWaddr 00:30:D7:00:14:55
>           inet addr:192.168.0.100  Bcast:192.168.0.255
> Mask:255.255.255.0
>           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
>           RX packets:1553 errors:0 dropped:0 overruns:0 frame:0
>           TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
>           collisions:0 txqueuelen:1000
>           RX bytes:203182 (198.4 Kb)  TX bytes:168 (168.0 b)
>           Base address:0x8600
> -
> 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


--
Denys Fedoryshchenko
Technical Manager
Virtual ISP S.A.L.


^ permalink raw reply

* [OOPS] 2.6.23-rc5 ? network/via-rhine [was: hang with CONFIG_MCYRIXIII]
From: Mark Hindley @ 2007-09-02 11:36 UTC (permalink / raw)
  To: linux-kernel; +Cc: rl, netdev
In-Reply-To: <20070902110401.GB4790@hindley.org.uk>

I have now got an oops trace out of this box, which I presume has been
the cause of the previously observed hangs.

To my inexperienced eye it looks like it is related to via-rhine.

Thanks 

Mark
 
BUG: unable to handle kernel NULL pointer dereference at virtual address 00000025            
 printing eip:                                                                                                        
c0259a57                                                                                                              
*pde = 00000000                                                                                                       
Oops: 0000 [#1]                                                                                                       
PREEMPT                                                                                                               
Modules linked in: nfs cpufreq_userspace nfsd exportfs lockd sunrpc ppdev lp ac battery ipv6 sd_mod cpufreq_ondemand cpufreq_powersave longhaul af_packet tcp_diag inetv
CPU:    0                                                                                                             
EIP:    0060:[<c0259a57>]    Not tainted VLI                                                                          
EFLAGS: 00010246   (2.6.23-rc5 #1)                                                                                    
EIP is at tcp_rto_min+0x8/0x12                                                                                        
eax: 000000c8   ebx: c7ab1080   ecx: ffffffee   edx: 00000000                                                         
esi: c7ab1080   edi: 00000000   ebp: c9a24b20   esp: c0341dec                                                         
ds: 007b   es: 007b   fs: 0000  gs: 0033  ss: 0068                                                                    
Process ssh (pid: 4928, ti=c0341000 task=c963cf90 task.ti=c35b9000)                                                   
Stack: c0259b1b c7ab1080 c7ab1080 c025a2e8 c030c8a0 c025b906 00000080 00000080                                        
       c022f433 cacde032 00000000 00000000 00000001 28419aa8 731a8024 28419b18                                        
       00000000 00000000 c011ebc5 28419b18 00000282 028b585b 00000004 cceb3540                                        
Call Trace:                                                                                                           
 [<c0259b1b>] tcp_rtt_estimator+0xba/0x100                                                                            
 [<c025a2e8>] tcp_ack_saw_tstamp+0x14/0x43
 [<c025b906>] tcp_ack+0x6aa/0x1726
 [<c022f433>] skb_checksum+0x49/0x289
 [<c011ebc5>] local_bh_enable+0x5/0x8c
 [<c025f1bf>] tcp_rcv_established+0x344/0x5ed
 [<c024b660>] ip_route_input+0x3a/0xcdc
 [<c0264226>] tcp_v4_do_rcv+0x27/0x31d
 [<c0266309>] tcp_v4_rcv+0x71a/0x765
 [<c024e7b6>] ip_local_deliver+0x159/0x1bf
 [<c024e630>] ip_rcv+0x44e/0x47b
 [<c01b9540>] rb_insert_color+0x4c/0xad
 [<c024e630>] ip_rcv+0x44e/0x47b
 [<c0115bb4>] enqueue_entity+0x1d2/0x1f3
 [<c024e1e2>] ip_rcv+0x0/0x47b
 [<c023470b>] netif_receive_skb+0x30d/0x38e
 [<d00d55a8>] rhine_napipoll+0x2a7/0x46d [via_rhine]
 [<c02368c9>] net_rx_action+0x85/0x171
 [<c011ea8e>] __do_softirq+0x35/0x75
 [<c010665c>] do_softirq+0x3e/0x8d
 [<c013c6cc>] handle_level_irq+0x0/0xd0
 [<c011ea20>] irq_exit+0x29/0x62
 [<c010693b>] do_IRQ+0x94/0xad
 [<c0104cf3>] common_interrupt+0x23/0x30
 =======================
Code: 00 8b 14 24 8b 82 8c 02 00 00 89 82 10 04 00 00 a1 e0 6e 2f c0 89 82 14 04 00 00 83 c4 0c 5b 5e 5f 5d c3 8b 50 44 b8 c8 00 00 00 <f6> 42 25 20 74 03 8b 42 54 c3  
EIP: [<c0259a57>] tcp_rto_min+0x8/0x12 SS:ESP 0068:c0341dec
Kernel panic - not syncing: Fatal exception in interrupt


^ permalink raw reply

* Re: [PATCH -mm] net/sched/sch_cbq.c: Shut up uninitialized variable warning
From: Patrick McHardy @ 2007-09-02 11:36 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Andrew Morton, Linux Kernel Mailing List, David Miller, netdev
In-Reply-To: <alpine.LFD.0.999.0709020656050.20781@enigma.security.iitk.ac.in>

Satyam Sharma wrote:
> net/sched/sch_cbq.c: In function 'cbq_enqueue':
> net/sched/sch_cbq.c:383: warning: 'ret' may be used uninitialized in this function
>
> has been verified to be a bogus case. So let's shut it up.
>
> Signed-off-by: Satyam Sharma <satyam@infradead.org>

Acked-by: Patrick McHardy <kaber@trash.net>

^ permalink raw reply

* Re: [ofa-general] Re: [PATCH V4 10/10] net/bonding: Destroy bonding master when last slave is gone
From: Moni Shoua @ 2007-09-02 11:32 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: rdreier, davem, general, netdev
In-Reply-To: <16908.1188417014@death>

Jay Vosburgh wrote:
> Moni Shoua <monisonlists@gmail.com> wrote:
> 
>> Jay Vosburgh wrote:
>>> Moni Shoua <monis@voltaire.com> wrote:
>>>
>>>> When bonding enslaves non Ethernet devices it takes pointers to functions 
>>>> in the module that owns the slaves. In this case it becomes unsafe
>>>> to keep the bonding master registered after last slave was unenslaved 
>>>> because we don't know if the pointers are still valid.  Destroying the bond when slave_cnt is zero
>>>> ensures that these functions be used anymore.
>>> 	Would it not be simpler to run the bonding master through
>>> ether_setup() again when the final slave is released (to reset all of
>>> the pointers to their "ethernet" values)?  I'm presuming here the
>>> pointers of questionable validity are the ones set in the
>>> bond_setup_by_slave() copied from the slave_dev->hard_header, et al.
>>>
>>> 	Having the bonding master disappear (but only sometimes) after
>>> the last slave is removed is a semantic change I'd rather not introduce
>>> if it's not necessary.
>> Thanks for the comments.
>>
>> Having the master disappear is one way I could think of to solve the problem of leaving
>> the bonding module with pointers to illegal addresses.
>> The other way is to increase the usage count, with try_module_get(), of the module which owns of the slave.
>> To do that I  have to restore the field  owner in structure net_device (it was removed in 2.6).
> 
> 	What I was asking above is really whether or not it's feasible
> to simply reset the affected pointers back to the "ethernet" values from
> ether_setup().  I would think this should return the bonding master back
> to the original state it started in before any slaves were added.
> Unless I'm missing something; I'm willing to believe there's some
> IB-specific tidbit I'm unaware of that makes this more complicated than
> it seems.

It's possible to reset the bonding master by calling ether_setup but with one exception: its neighbors.
When enslaving IPoIB devices, the bonding master neighbors point to a destructor function in the ib_ipoib module.
When ib_ipoib goes down the neighbors of the bonding master still exist and when their turn come to die they will
try to access this function and the kernel will crash. This is why I want to destroy the bonding master before ib_ipoib
is unloaded (to kill its neighbors). For any other issue (i.e. taken pointer), ether_setup would solve the problem.

> 
> 	This presumes that I'm correct in thinking that the pointers
> you're talking about (as being unsafe after removal of last slave) are
> the ones copied in your new function bond_setup_by_slave().
> 
> 	I don't think it's desirable to acquire a reference to the slave
> driver module.
> 
> 	-J
> 
> ---
> 	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
> 

^ permalink raw reply

* [-mm patch] IPV6 must select XFRM
From: Adrian Bunk @ 2007-09-02 11:25 UTC (permalink / raw)
  To: Andrew Morton, davem; +Cc: linux-kernel, netdev
In-Reply-To: <20070831215822.26e1432b.akpm@linux-foundation.org>

On Fri, Aug 31, 2007 at 09:58:22PM -0700, Andrew Morton wrote:
>...
> Changes since 2.6.23-rc3-mm1:
>...
>  git-net.patch
>...
>  git trees
>...

This patch fixes the following compile error:

<--  snip  -->

...
  LD      .tmp_vmlinux1
net/built-in.o: In function `inet6_csk_xmit':
(.text+0x72b0f): undefined reference to `flow_cache_genid'
net/built-in.o: In function `inet6_csk_xmit':
(.text+0x72be5): undefined reference to `flow_cache_genid'
make[1]: *** [.tmp_vmlinux1] Error 1

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -5,6 +5,7 @@
 #   IPv6 as module will cause a CRASH if you try to unload it
 config IPV6
 	tristate "The IPv6 protocol"
+	select XFRM
 	default m
 	---help---
 	  This is complemental support for the IP version 6.

^ permalink raw reply

* Re: Fwd: That whole "Linux stealing our code" thing
From: Igor Sobrado @ 2007-09-02 11:20 UTC (permalink / raw)
  To: Alan Cox
  Cc: Constantine A. Murenin, Adrian Bunk, Jeff Garzik,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Slaby
In-Reply-To: <20070902113638.78fbd202-v58gJUvfdfWUJIigds3554dd74u8MsAO@public.gmane.org>

On Sun, 2 Sep 2007, Alan Cox wrote:
> You can shout this all you like but you would be wrong. You can remove
> the licence if you have permission to do so. For the ath c files there
> was permission to do so.

There was permission to do so from Reyk Floeter?  Really?

> Your understanding isn't quite right. One of many things you may get with
> dual licensed code is the right to pick a licence from several choices,
> you may also get the right to remove some choices from the recipient.

Reyk code was never dual licensed!  His code is under truly free 
licensing terms (BSD).

> A work that combines GPL and BSD licensed material is not the same as a
> work which says I may choose between two licences. If both licences must
> always apply (which is a perfectly possible condition to put in a
> licence) then putting such a "both" GPL/BSD licence piece of code into
> OpenBSD would require any OpenBSD distributed containing it was GPL
> licenced when conveyed, which I am *very* sure is not the intent.
>
> Thus what you appear to be doing by putting the ath5k C code in OpenBSD is
> conveying it under the BSD licence (making a choice between the two
> offered) and conveying a right for parties down the chain to convey it
> under one of the licences only.

I think that Theo explained this point clearly quite a few times in the 
last days.

> And as we've already established the header files are quite different.

Is a simple change in the header files a reason to vindicate the people 
that changed the licensing terms?  Obviously, it isn't.

> Doesn't mean its not somewhat rude but illegal and rude are two very
> different things.

No, because this change is both rude and illegal.

Igor

^ permalink raw reply

* [PATCH] ethtool: provide default behavior for a few sub-ioctls
From: Jeff Garzik @ 2007-09-02 11:17 UTC (permalink / raw)
  To: netdev


Just checked this in...



commit 2c0205e3480ac39f5b52b2220ff0c77141502936
Author: Jeff Garzik <jeff@garzik.org>
Date:   Sun Sep 2 07:13:36 2007 -0400

    [ETHTOOL] Provide default behaviors for a few ethtool sub-ioctls
    
    For the operations
    	get-tx-csum
    	get-sg
    	get-tso
    	get-ufo
    the default ethtool_op_xxx behavior is fine for all drivers, so we
    permit op==NULL to imply the default behavior.
    
    This provides a more uniform behavior across all drivers, eliminating
    ethtool(8) "ioctl not supported" errors on older drivers that had
    not been updated for the latest sub-ioctls.
    
    The ethtool_op_xxx() functions are left exported, in case anyone
    wishes to call them directly from a driver-private implementation --
    a not-uncommon case.  Should an ethtool_op_xxx() helper remain unused
    for a while, except by net/core/ethtool.c, we can un-export it at a
    later date.
    
    Signed-off-by: Jeff Garzik <jeff@garzik.org>

 drivers/net/8139cp.c                    |    3 ---
 drivers/net/atl1/atl1_ethtool.c         |    3 ---
 drivers/net/bnx2.c                      |    3 ---
 drivers/net/bonding/bond_main.c         |    4 ----
 drivers/net/chelsio/cxgb2.c             |    3 ---
 drivers/net/cxgb3/cxgb3_main.c          |    3 ---
 drivers/net/e1000/e1000_ethtool.c       |    2 --
 drivers/net/ehea/ehea_ethtool.c         |    3 ---
 drivers/net/epic100.c                   |    2 --
 drivers/net/fealnx.c                    |    2 --
 drivers/net/fec_8xx/fec_main.c          |    2 --
 drivers/net/forcedeth.c                 |    3 ---
 drivers/net/fs_enet/fs_enet-main.c      |    2 --
 drivers/net/ibm_emac/ibm_emac_core.c    |    2 --
 drivers/net/ibmveth.c                   |    2 --
 drivers/net/ixgb/ixgb_ethtool.c         |    2 --
 drivers/net/loopback.c                  |    1 -
 drivers/net/macvlan.c                   |    4 ----
 drivers/net/mv643xx_eth.c               |    1 -
 drivers/net/myri10ge/myri10ge.c         |    3 ---
 drivers/net/ne2k-pci.c                  |    2 --
 drivers/net/netxen/netxen_nic_ethtool.c |    3 ---
 drivers/net/pcnet32.c                   |    3 ---
 drivers/net/r8169.c                     |    3 ---
 drivers/net/s2io.c                      |    3 ---
 drivers/net/sc92031.c                   |    4 ----
 drivers/net/skge.c                      |    2 --
 drivers/net/sky2.c                      |    3 ---
 drivers/net/spider_net_ethtool.c        |    1 -
 drivers/net/tg3.c                       |    3 ---
 drivers/net/tulip/de2104x.c             |    2 --
 drivers/net/tulip/winbond-840.c         |    2 --
 drivers/net/typhoon.c                   |    3 ---
 drivers/net/ucc_geth_ethtool.c          |    2 --
 drivers/net/via-rhine.c                 |    2 --
 drivers/net/xen-netfront.c              |    3 ---
 net/bridge/br_device.c                  |    3 ---
 net/core/ethtool.c                      |   32 +++++++++++++++++---------------
 38 files changed, 17 insertions(+), 109 deletions(-)

2c0205e3480ac39f5b52b2220ff0c77141502936
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a79f28c..9e674c9 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1567,11 +1567,8 @@ static const struct ethtool_ops cp_ethtool_ops = {
 	.set_msglevel		= cp_set_msglevel,
 	.get_rx_csum		= cp_get_rx_csum,
 	.set_rx_csum		= cp_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_csum, /* local! */
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= cp_get_regs,
 	.get_wol		= cp_get_wol,
diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atl1/atl1_ethtool.c
index 1f616c5..53353b6 100644
--- a/drivers/net/atl1/atl1_ethtool.c
+++ b/drivers/net/atl1/atl1_ethtool.c
@@ -489,15 +489,12 @@ const struct ethtool_ops atl1_ethtool_ops = {
 	.get_pauseparam		= atl1_get_pauseparam,
 	.set_pauseparam 	= atl1_set_pauseparam,
 	.get_rx_csum		= atl1_get_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
 	.get_link		= ethtool_op_get_link,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= atl1_get_strings,
 	.nway_reset		= atl1_nway_reset,
 	.get_ethtool_stats	= atl1_get_ethtool_stats,
 	.get_stats_count	= atl1_get_stats_count,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 };
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 24e7f9a..87df593 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6257,11 +6257,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
 	.set_pauseparam		= bnx2_set_pauseparam,
 	.get_rx_csum		= bnx2_get_rx_csum,
 	.set_rx_csum		= bnx2_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= bnx2_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= bnx2_set_tso,
 	.self_test_count	= bnx2_self_test_count,
 	.self_test		= bnx2_self_test,
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1afda32..c318e9d 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4195,10 +4195,6 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
 }
 
 static const struct ethtool_ops bond_ethtool_ops = {
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_tso		= ethtool_op_get_tso,
-	.get_ufo		= ethtool_op_get_ufo,
-	.get_sg			= ethtool_op_get_sg,
 	.get_drvinfo		= bond_ethtool_get_drvinfo,
 };
 
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 231ce43..69b3d15 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -790,9 +790,7 @@ static const struct ethtool_ops t1_ethtool_ops = {
 	.set_pauseparam    = set_pauseparam,
 	.get_rx_csum       = get_rx_csum,
 	.set_rx_csum       = set_rx_csum,
-	.get_tx_csum       = ethtool_op_get_tx_csum,
 	.set_tx_csum       = ethtool_op_set_tx_csum,
-	.get_sg            = ethtool_op_get_sg,
 	.set_sg            = ethtool_op_set_sg,
 	.get_link          = ethtool_op_get_link,
 	.get_strings       = get_strings,
@@ -800,7 +798,6 @@ static const struct ethtool_ops t1_ethtool_ops = {
 	.get_ethtool_stats = get_stats,
 	.get_regs_len      = get_regs_len,
 	.get_regs          = get_regs,
-	.get_tso           = ethtool_op_get_tso,
 	.set_tso           = set_tso,
 };
 
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index dc5d269..63a31b2 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1568,9 +1568,7 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
 	.set_pauseparam = set_pauseparam,
 	.get_rx_csum = get_rx_csum,
 	.set_rx_csum = set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
 	.get_link = ethtool_op_get_link,
 	.get_strings = get_strings,
@@ -1581,7 +1579,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
 	.get_regs_len = get_regs_len,
 	.get_regs = get_regs,
 	.get_wol = get_wol,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 };
 
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 4c3785c..fc07f05 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1965,9 +1965,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.set_rx_csum            = e1000_set_rx_csum,
 	.get_tx_csum            = e1000_get_tx_csum,
 	.set_tx_csum            = e1000_set_tx_csum,
-	.get_sg                 = ethtool_op_get_sg,
 	.set_sg                 = ethtool_op_set_sg,
-	.get_tso                = ethtool_op_get_tso,
 	.set_tso                = e1000_set_tso,
 	.self_test_count        = e1000_diag_test_count,
 	.self_test              = e1000_diag_test,
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index decec8c..fe9207a 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -247,9 +247,6 @@ const struct ethtool_ops ehea_ethtool_ops = {
 	.get_msglevel = ehea_get_msglevel,
 	.set_msglevel = ehea_set_msglevel,
 	.get_link = ethtool_op_get_link,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.get_sg = ethtool_op_get_sg,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 	.get_strings = ehea_get_strings,
 	.get_stats_count = ehea_get_stats_count,
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 1197784..43dbf96 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1495,8 +1495,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_link		= netdev_get_link,
 	.get_msglevel		= netdev_get_msglevel,
 	.set_msglevel		= netdev_set_msglevel,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.begin			= ethtool_begin,
 	.complete		= ethtool_complete
 };
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index ff9f177..d52e2a0 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1892,8 +1892,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_link		= netdev_get_link,
 	.get_msglevel		= netdev_get_msglevel,
 	.set_msglevel		= netdev_set_msglevel,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 };
 
 static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c
index e5502af..d82e7d7 100644
--- a/drivers/net/fec_8xx/fec_main.c
+++ b/drivers/net/fec_8xx/fec_main.c
@@ -1042,9 +1042,7 @@ static const struct ethtool_ops fec_ethtool_ops = {
 	.get_link	= ethtool_op_get_link,
 	.get_msglevel	= fec_get_msglevel,
 	.set_msglevel	= fec_set_msglevel,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
 	.set_tx_csum	= ethtool_op_set_tx_csum,	/* local! */
-	.get_sg		= ethtool_op_get_sg,
 	.set_sg		= ethtool_op_set_sg,
 	.get_regs	= fec_get_regs,
 };
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 1938d6d..7f248ab 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -4707,7 +4707,6 @@ static const struct ethtool_ops ops = {
 	.get_regs_len = nv_get_regs_len,
 	.get_regs = nv_get_regs,
 	.nway_reset = nv_nway_reset,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = nv_set_tso,
 	.get_ringparam = nv_get_ringparam,
 	.set_ringparam = nv_set_ringparam,
@@ -4715,9 +4714,7 @@ static const struct ethtool_ops ops = {
 	.set_pauseparam = nv_set_pauseparam,
 	.get_rx_csum = nv_get_rx_csum,
 	.set_rx_csum = nv_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = nv_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = nv_set_sg,
 	.get_strings = nv_get_strings,
 	.get_stats_count = nv_get_stats_count,
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a4a2a0e..a5af728 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -915,9 +915,7 @@ static const struct ethtool_ops fs_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_msglevel = fs_get_msglevel,
 	.set_msglevel = fs_set_msglevel,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_csum,	/* local! */
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
 	.get_regs = fs_get_regs,
 };
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index f752e5f..bd7ac43 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -1900,8 +1900,6 @@ static const struct ethtool_ops emac_ethtool_ops = {
 	.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
 
 	.get_link = ethtool_op_get_link,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 };
 
 static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index acba90f..4f641d6 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -638,8 +638,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_drvinfo		= netdev_get_drvinfo,
 	.get_settings		= netdev_get_settings,
 	.get_link		= netdev_get_link,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 };
 
 static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 0413cd9..4432acc 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -714,11 +714,9 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
 	.set_rx_csum = ixgb_set_rx_csum,
 	.get_tx_csum = ixgb_get_tx_csum,
 	.set_tx_csum = ixgb_set_tx_csum,
-	.get_sg	= ethtool_op_get_sg,
 	.set_sg	= ethtool_op_set_sg,
 	.get_msglevel = ixgb_get_msglevel,
 	.set_msglevel = ixgb_set_msglevel,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = ixgb_set_tso,
 	.get_strings = ixgb_get_strings,
 	.phys_id = ixgb_phys_id,
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 5106c23..ee38515 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -192,7 +192,6 @@ static u32 always_on(struct net_device *dev)
 
 static const struct ethtool_ops loopback_ethtool_ops = {
 	.get_link		= always_on,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 	.get_tx_csum		= always_on,
 	.get_sg			= always_on,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index dc74d00..75c7799 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -282,10 +282,6 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
 static const struct ethtool_ops macvlan_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 	.get_rx_csum		= macvlan_ethtool_get_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_tso		= ethtool_op_get_tso,
-	.get_ufo		= ethtool_op_get_ufo,
-	.get_sg			= ethtool_op_get_sg,
 	.get_drvinfo		= macvlan_ethtool_get_drvinfo,
 };
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1799eee..7a17487 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2763,7 +2763,6 @@ static const struct ethtool_ops mv643xx_ethtool_ops = {
 	.set_settings           = mv643xx_set_settings,
 	.get_drvinfo            = mv643xx_get_drvinfo,
 	.get_link               = mv643xx_eth_get_link,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
 	.get_stats_count        = mv643xx_get_stats_count,
 	.get_ethtool_stats      = mv643xx_get_ethtool_stats,
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1c42266..ac5a6dd 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1469,11 +1469,8 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
 	.get_ringparam = myri10ge_get_ringparam,
 	.get_rx_csum = myri10ge_get_rx_csum,
 	.set_rx_csum = myri10ge_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_hw_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 	.get_link = ethtool_op_get_link,
 	.get_strings = myri10ge_get_strings,
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f81d939..e8c1ebb 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -636,8 +636,6 @@ static void ne2k_pci_get_drvinfo(struct net_device *dev,
 
 static const struct ethtool_ops ne2k_pci_ethtool_ops = {
 	.get_drvinfo		= ne2k_pci_get_drvinfo,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 };
 
 static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index a6138b4..08c76b3 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -744,11 +744,8 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_ringparam = netxen_nic_get_ringparam,
 	.get_pauseparam = netxen_nic_get_pauseparam,
 	.set_pauseparam = netxen_nic_set_pauseparam,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 	.self_test_count = netxen_nic_diag_test_count,
 	.self_test = netxen_nic_diag_test,
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index e6a6753..a3cc1dc 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1506,9 +1506,6 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
 	.get_link		= pcnet32_get_link,
 	.get_ringparam		= pcnet32_get_ringparam,
 	.set_ringparam		= pcnet32_set_ringparam,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.get_strings		= pcnet32_get_strings,
 	.self_test_count	= pcnet32_self_test_count,
 	.self_test		= pcnet32_ethtool_test,
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index b85ab4a..4f8c831 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1060,11 +1060,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.set_msglevel		= rtl8169_set_msglevel,
 	.get_rx_csum		= rtl8169_get_rx_csum,
 	.set_rx_csum		= rtl8169_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= rtl8169_get_regs,
 	.get_wol		= rtl8169_get_wol,
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 24feb00..b9394ca 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5936,13 +5936,10 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.set_pauseparam = s2io_ethtool_setpause_data,
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
 	.set_rx_csum = s2io_ethtool_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = s2io_ethtool_op_get_tso,
 	.set_tso = s2io_ethtool_op_set_tso,
-	.get_ufo = ethtool_op_get_ufo,
 	.set_ufo = ethtool_op_set_ufo,
 	.self_test_count = s2io_ethtool_self_test_count,
 	.self_test = s2io_ethtool_test,
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 872cb1c..02c472e 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1396,13 +1396,9 @@ static struct ethtool_ops sc92031_ethtool_ops = {
 	.set_wol		= sc92031_ethtool_set_wol,
 	.nway_reset		= sc92031_ethtool_nway_reset,
 	.get_link		= ethtool_op_get_link,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.get_strings		= sc92031_ethtool_get_strings,
 	.get_stats_count	= sc92031_ethtool_get_stats_count,
 	.get_ethtool_stats	= sc92031_ethtool_get_ethtool_stats,
-	.get_ufo		= ethtool_op_get_ufo,
 };
 
 static int __devinit sc92031_probe(struct pci_dev *pdev,
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e3d8520..9e41be6 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -811,9 +811,7 @@ static const struct ethtool_ops skge_ethtool_ops = {
 	.set_pauseparam = skge_set_pauseparam,
 	.get_coalesce	= skge_get_coalesce,
 	.set_coalesce	= skge_set_coalesce,
-	.get_sg		= ethtool_op_get_sg,
 	.set_sg		= skge_set_sg,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
 	.set_tx_csum	= skge_set_tx_csum,
 	.get_rx_csum	= skge_get_rx_csum,
 	.set_rx_csum	= skge_set_rx_csum,
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index e6d937e..e0aaffd 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3534,11 +3534,8 @@ static const struct ethtool_ops sky2_ethtool_ops = {
 	.get_eeprom_len	= sky2_get_eeprom_len,
 	.get_eeprom	= sky2_get_eeprom,
 	.set_eeprom	= sky2_set_eeprom,
-	.get_sg 	= ethtool_op_get_sg,
 	.set_sg 	= ethtool_op_set_sg,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
 	.set_tx_csum	= sky2_set_tx_csum,
-	.get_tso	= ethtool_op_get_tso,
 	.set_tso	= sky2_set_tso,
 	.get_rx_csum	= sky2_get_rx_csum,
 	.set_rx_csum	= sky2_set_rx_csum,
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
index d940474..1460d50 100644
--- a/drivers/net/spider_net_ethtool.c
+++ b/drivers/net/spider_net_ethtool.c
@@ -188,7 +188,6 @@ const struct ethtool_ops spider_net_ethtool_ops = {
 	.nway_reset		= spider_net_ethtool_nway_reset,
 	.get_rx_csum		= spider_net_ethtool_get_rx_csum,
 	.set_rx_csum		= spider_net_ethtool_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_csum,
 	.get_ringparam          = spider_net_ethtool_get_ringparam,
 	.get_strings		= spider_net_get_strings,
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5874042..2b32643 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9280,11 +9280,8 @@ static const struct ethtool_ops tg3_ethtool_ops = {
 	.set_pauseparam		= tg3_set_pauseparam,
 	.get_rx_csum		= tg3_get_rx_csum,
 	.set_rx_csum		= tg3_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= tg3_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= tg3_set_tso,
 	.self_test_count	= tg3_get_test_count,
 	.self_test		= tg3_self_test,
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d380e0b..8e8ec2d 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1670,8 +1670,6 @@ static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 
 static const struct ethtool_ops de_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 	.get_drvinfo		= de_get_drvinfo,
 	.get_regs_len		= de_get_regs_len,
 	.get_settings		= de_get_settings,
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 5824f6a..abcf51c 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1452,8 +1452,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_link		= netdev_get_link,
 	.get_msglevel		= netdev_get_msglevel,
 	.set_msglevel		= netdev_set_msglevel,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 0358720..0dd2187 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1235,11 +1235,8 @@ static const struct ethtool_ops typhoon_ethtool_ops = {
 	.set_wol		= typhoon_set_wol,
 	.get_link		= ethtool_op_get_link,
 	.get_rx_csum		= typhoon_get_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 	.get_ringparam		= typhoon_get_ringparam,
 };
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 64bef7c..73aa677 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -373,9 +373,7 @@ static const struct ethtool_ops uec_ethtool_ops = {
 	.set_ringparam          = uec_set_ringparam,
 	.get_pauseparam         = uec_get_pauseparam,
 	.set_pauseparam         = uec_set_pauseparam,
-	.get_sg                 = ethtool_op_get_sg,
 	.set_sg                 = ethtool_op_set_sg,
-	.get_tso                = ethtool_op_get_tso,
 	.get_stats_count        = uec_get_stats_count,
 	.get_strings            = uec_get_strings,
 	.get_ethtool_stats      = uec_get_ethtool_stats,
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index b56dff2..abdb1f2 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1809,8 +1809,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.set_msglevel		= netdev_set_msglevel,
 	.get_wol		= rhine_get_wol,
 	.set_wol		= rhine_set_wol,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 4445810..c704c00 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1661,11 +1661,8 @@ static void backend_changed(struct xenbus_device *dev,
 
 static struct ethtool_ops xennet_ethtool_ops =
 {
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = xennet_set_sg,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = xennet_set_tso,
 	.get_link = ethtool_op_get_link,
 };
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 0eded17..446cd50 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -150,11 +150,8 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
 static struct ethtool_ops br_ethtool_ops = {
 	.get_drvinfo = br_getinfo,
 	.get_link = ethtool_op_get_link,
-	.get_sg = ethtool_op_get_sg,
 	.set_sg = br_set_sg,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = br_set_tx_csum,
-	.get_tso = ethtool_op_get_tso,
 	.set_tso = br_set_tso,
 };
 
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index c5e0593..747df44 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -479,10 +479,10 @@ static int ethtool_get_tx_csum(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_value edata = { ETHTOOL_GTXCSUM };
 
-	if (!dev->ethtool_ops->get_tx_csum)
-		return -EOPNOTSUPP;
-
-	edata.data = dev->ethtool_ops->get_tx_csum(dev);
+	if (dev->ethtool_ops->get_tx_csum)
+		edata.data = dev->ethtool_ops->get_tx_csum(dev);
+	else
+		edata.data = ethtool_op_get_tx_csum(dev);
 
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
@@ -531,10 +531,10 @@ static int ethtool_get_sg(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_value edata = { ETHTOOL_GSG };
 
-	if (!dev->ethtool_ops->get_sg)
-		return -EOPNOTSUPP;
-
-	edata.data = dev->ethtool_ops->get_sg(dev);
+	if (dev->ethtool_ops->get_sg)
+		edata.data = dev->ethtool_ops->get_sg(dev);
+	else
+		edata.data = ethtool_op_get_sg(dev);
 
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
@@ -562,10 +562,10 @@ static int ethtool_get_tso(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_value edata = { ETHTOOL_GTSO };
 
-	if (!dev->ethtool_ops->get_tso)
-		return -EOPNOTSUPP;
-
-	edata.data = dev->ethtool_ops->get_tso(dev);
+	if (dev->ethtool_ops->get_tso)
+		edata.data = dev->ethtool_ops->get_tso(dev);
+	else
+		edata.data = ethtool_op_get_tso(dev);
 
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
@@ -592,9 +592,11 @@ static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_value edata = { ETHTOOL_GUFO };
 
-	if (!dev->ethtool_ops->get_ufo)
-		return -EOPNOTSUPP;
-	edata.data = dev->ethtool_ops->get_ufo(dev);
+	if (dev->ethtool_ops->get_ufo)
+		edata.data = dev->ethtool_ops->get_ufo(dev);
+	else
+		edata.data = ethtool_op_get_ufo(dev);
+
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		 return -EFAULT;
 	return 0;

^ permalink raw reply related

* Re: [Bugme-new] [Bug 8961] New: BUG triggered by oidentd in netlink code
From: Patrick McHardy @ 2007-09-02 10:56 UTC (permalink / raw)
  To: Herbert Xu; +Cc: link, linux-kernel, akpm, netdev, bugme-daemon
In-Reply-To: <E1IRghZ-0004EL-00@gondolin.me.apana.org.au>

Herbert Xu wrote:
> Patrick McHardy <kaber@trash.net> wrote:
>   
>> Thanks. I'm not sure either, it would require two concurrent requests
>> to be processed, but AFAICS oidentd only uses a single netlink socket.
>> Perhaps multiple running instances or something else using the inet_diag
>> interface?
>>     
>
> Since identd serves requests from the outside world it is
> quite possible for two identd instances to run simultaneously
> serving two requests.
>
> I'm not familiar with oidentd but this is certainly pidentd
> works.

Right, I forgot about inetd. Thanks Herbert :)


^ permalink raw reply

* [PATCH 2/2] drivers/net/: all drivers/net/ cleanup with ARRAY_SIZE
From: Denis Cheng @ 2007-09-02 10:30 UTC (permalink / raw)
  To: Robert P. J. Day, David S. Miller; +Cc: netdev, linux-kernel, cr_quan
In-Reply-To: <11887290181154-git-send-email-crquan@gmail.com>

Signed-off-by: Denis Cheng <crquan@gmail.com>
---
 drivers/net/apne.c                         |    2 +-
 drivers/net/arm/am79c961a.c                |    2 +-
 drivers/net/atarilance.c                   |    2 +-
 drivers/net/atl1/atl1_hw.c                 |    2 +-
 drivers/net/bnx2.c                         |    2 +-
 drivers/net/cs89x0.c                       |    6 +++---
 drivers/net/e1000/e1000_ethtool.c          |    3 +--
 drivers/net/fec_8xx/fec_mii.c              |    5 ++---
 drivers/net/ibm_emac/ibm_emac_debug.c      |    8 ++++----
 drivers/net/irda/actisys-sir.c             |    2 +-
 drivers/net/ixgb/ixgb_ethtool.c            |    3 +--
 drivers/net/lp486e.c                       |    4 +---
 drivers/net/mv643xx_eth.c                  |    3 +--
 drivers/net/ne-h8300.c                     |    2 +-
 drivers/net/ne.c                           |    2 +-
 drivers/net/ne2.c                          |    2 +-
 drivers/net/ne2k-pci.c                     |    2 +-
 drivers/net/netxen/netxen_nic.h            |    2 +-
 drivers/net/netxen/netxen_nic_hw.c         |    2 +-
 drivers/net/pcmcia/axnet_cs.c              |    2 +-
 drivers/net/pcmcia/pcnet_cs.c              |    4 ++--
 drivers/net/phy/phy.c                      |    2 +-
 drivers/net/skfp/smt.c                     |    2 +-
 drivers/net/skfp/srf.c                     |    4 ++--
 drivers/net/tulip/de4x5.c                  |    6 +++---
 drivers/net/wireless/airo.c                |    6 +++---
 drivers/net/wireless/hostap/hostap_ioctl.c |    6 +++---
 drivers/net/wireless/ipw2100.c             |    7 +++----
 drivers/net/wireless/libertas/fw.c         |    3 +--
 drivers/net/wireless/libertas/main.c       |   14 +++++++-------
 drivers/net/wireless/libertas/wext.c       |    4 ++--
 drivers/net/wireless/netwave_cs.c          |    6 +++---
 drivers/net/wireless/prism54/isl_ioctl.c   |    7 +++----
 drivers/net/wireless/ray_cs.c              |    6 +++---
 drivers/net/wireless/wavelan.c             |    6 +++---
 drivers/net/wireless/wavelan_cs.c          |    6 +++---
 drivers/net/wireless/wl3501_cs.c           |    2 +-
 drivers/net/zorro8390.c                    |    2 +-
 38 files changed, 71 insertions(+), 80 deletions(-)

diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index 9541911..8806151 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -247,7 +247,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
 	    {0x00,	NE_EN0_RSARHI},
 	    {E8390_RREAD+E8390_START, NE_CMD},
 	};
-	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
 	    outb(program_seq[i].value, ioaddr + program_seq[i].offset);
 	}
 
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 2143eeb..7796455 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -414,7 +414,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
 	/*
 	 * Update the multicast hash table
 	 */
-	for (i = 0; i < sizeof(multi_hash) / sizeof(multi_hash[0]); i++)
+	for (i = 0; i < ARRAY_SIZE(multi_hash); i++)
 		write_rreg(dev->base_addr, i + LADRL, multi_hash[i]);
 
 	/*
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index dfa8b9b..a5c20d2 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -263,7 +263,7 @@ struct lance_addr {
 									   (highest byte stripped) */
 };
 
-#define	N_LANCE_ADDR	(sizeof(lance_addr_list)/sizeof(*lance_addr_list))
+#define	N_LANCE_ADDR	ARRAY_SIZE(lance_addr_list)
 
 
 /* Definitions for the Lance */
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index ef886bd..9d3bd22 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -603,7 +603,7 @@ static struct atl1_spi_flash_dev flash_table[] = {
 
 static void atl1_init_flash_opcode(struct atl1_hw *hw)
 {
-	if (hw->flash_vendor >= sizeof(flash_table) / sizeof(flash_table[0]))
+	if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
 		hw->flash_vendor = 0;	/* ATMEL */
 
 	/* Init OP table */
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 854d80c..aa9e636 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -3500,7 +3500,7 @@ bnx2_init_nvram(struct bnx2 *bp)
 	/* Determine the selected interface. */
 	val = REG_RD(bp, BNX2_NVM_CFG1);
 
-	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
+	entry_count = ARRAY_SIZE(flash_table);
 
 	if (val & 0x40000000) {
 
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 9774bb1..d0f4a1a 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -806,7 +806,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
 		        i = cs8900_irq_map[0];
 #else
 			/* Translate the IRQ using the IRQ mapping table. */
-			if (i >= sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]))
+			if (i >= ARRAY_SIZE(cs8900_irq_map))
 				printk("\ncs89x0: invalid ISA interrupt number %d\n", i);
 			else
 				i = cs8900_irq_map[i];
@@ -1247,11 +1247,11 @@ write_irq(struct net_device *dev, int chip_type, int irq)
 
 	if (chip_type == CS8900) {
 		/* Search the mapping table for the corresponding IRQ pin. */
-		for (i = 0; i != sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]); i++)
+		for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
 			if (cs8900_irq_map[i] == irq)
 				break;
 		/* Not found */
-		if (i == sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]))
+		if (i == ARRAY_SIZE(cs8900_irq_map))
 			i = 3;
 		writereg(dev, PP_CS8900_ISAINT, i);
 	} else {
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 4c3785c..55909d7 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -106,8 +106,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
 };
 
 #define E1000_QUEUE_STATS_LEN 0
-#define E1000_GLOBAL_STATS_LEN	\
-	sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
+#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
 #define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN)
 static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register test  (offline)", "Eeprom test    (offline)",
diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c
index b3fa0d6..e8e10a0 100644
--- a/drivers/net/fec_8xx/fec_mii.c
+++ b/drivers/net/fec_8xx/fec_mii.c
@@ -308,12 +308,11 @@ int fec_mii_phy_id_detect(struct net_device *dev)
 		return -1;
 	}
 
-	for (i = 0, phy = phy_info; i < sizeof(phy_info) / sizeof(phy_info[0]);
-	     i++, phy++)
+	for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
 		if (phy->id == (phy_hwid >> 4) || phy->id == 0)
 			break;
 
-	if (i >= sizeof(phy_info) / sizeof(phy_info[0])) {
+	if (i >= ARRAY_SIZE(phy_info)) {
 		printk(KERN_ERR DRV_MODULE_NAME
 		       ": %s PHY id 0x%08x is not supported!\n",
 		       dev->name, phy_hwid);
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c
index 92f970d..1f70906 100644
--- a/drivers/net/ibm_emac/ibm_emac_debug.c
+++ b/drivers/net/ibm_emac/ibm_emac_debug.c
@@ -132,7 +132,7 @@ void emac_dbg_register(int idx, struct ocp_enet_private *dev)
 {
 	unsigned long flags;
 
-	if (idx >= sizeof(__emacs) / sizeof(__emacs[0])) {
+	if (idx >= ARRAY_SIZE(__emacs)) {
 		printk(KERN_WARNING
 		       "invalid index %d when registering EMAC for debugging\n",
 		       idx);
@@ -148,7 +148,7 @@ void mal_dbg_register(int idx, struct ibm_ocp_mal *mal)
 {
 	unsigned long flags;
 
-	if (idx >= sizeof(__mals) / sizeof(__mals[0])) {
+	if (idx >= ARRAY_SIZE(__mals)) {
 		printk(KERN_WARNING
 		       "invalid index %d when registering MAL for debugging\n",
 		       idx);
@@ -167,11 +167,11 @@ void emac_dbg_dump_all(void)
 
 	local_irq_save(flags);
 
-	for (i = 0; i < sizeof(__mals) / sizeof(__mals[0]); ++i)
+	for (i = 0; i < ARRAY_SIZE(__mals); ++i)
 		if (__mals[i])
 			emac_mal_dump(__mals[i]);
 
-	for (i = 0; i < sizeof(__emacs) / sizeof(__emacs[0]); ++i)
+	for (i = 0; i < ARRAY_SIZE(__emacs); ++i)
 		if (__emacs[i])
 			emac_mac_dump(i, __emacs[i]);
 
diff --git a/drivers/net/irda/actisys-sir.c b/drivers/net/irda/actisys-sir.c
index 9715ab5..ccf6ec5 100644
--- a/drivers/net/irda/actisys-sir.c
+++ b/drivers/net/irda/actisys-sir.c
@@ -67,7 +67,7 @@ static int actisys_reset(struct sir_dev *);
 /* Note : the 220L doesn't support 38400, but we will fix that below */
 static unsigned baud_rates[] = { 9600, 19200, 57600, 115200, 38400 };
 
-#define MAX_SPEEDS (sizeof(baud_rates)/sizeof(baud_rates[0]))
+#define MAX_SPEEDS ARRAY_SIZE(baud_rates)
 
 static struct dongle_driver act220l = {
 	.owner		= THIS_MODULE,
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 0413cd9..21d35bc 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -94,8 +94,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
 	{"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
 };
 
-#define IXGB_STATS_LEN	\
-	sizeof(ixgb_gstrings_stats) / sizeof(struct ixgb_stats)
+#define IXGB_STATS_LEN	ARRAY_SIZE(ixgb_gstrings_stats)
 
 static int
 ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 5fc18da..408ae6e 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -515,8 +515,6 @@ CLEAR_INT(void) {
 	outb(0, IOADDR+8);
 }
 
-#define SIZE(x)	(sizeof(x)/sizeof((x)[0]))
-
 #if 0
 /* selftest or dump */
 static void
@@ -532,7 +530,7 @@ i596_port_do(struct net_device *dev, int portcmd, char *cmdname) {
 	mdelay(30);             /* random, unmotivated */
 
 	printk("lp486e i82596 %s result:\n", cmdname);
-	for (m = SIZE(lp->dump.dump); m && lp->dump.dump[m-1] == 0; m--)
+	for (m = ARRAY_SIZE(lp->dump.dump); m && lp->dump.dump[m-1] == 0; m--)
 		;
 	for (i = 0; i < m; i++) {
 		printk(" %04x", lp->dump.dump[i]);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 1799eee..80fa3e8 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2688,8 +2688,7 @@ static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
 	{ "late_collision", MV643XX_STAT(mib_counters.late_collision) },
 };
 
-#define MV643XX_STATS_LEN	\
-	sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats)
+#define MV643XX_STATS_LEN	ARRAY_SIZE(mv643xx_gstrings_stats)
 
 static void mv643xx_get_drvinfo(struct net_device *netdev,
 				struct ethtool_drvinfo *drvinfo)
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index 38fd525..7599d77 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -259,7 +259,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 			{E8390_RREAD+E8390_START, E8390_CMD},
 		};
 
-		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 			outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 
 	}
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index c9f74bf..eac2fa6 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -377,7 +377,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
 			{E8390_RREAD+E8390_START, E8390_CMD},
 		};
 
-		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 			outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 
 	}
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 089b5bb..c6c2a91 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -432,7 +432,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
 			{E8390_RREAD+E8390_START, E8390_CMD},
 		};
 
-		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 			outb_p(program_seq[i].value, base_addr +
 				program_seq[i].offset);
 
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f81d939..9c2abcc 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -308,7 +308,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
 			{0x00,	EN0_RSARHI},
 			{E8390_RREAD+E8390_START, E8390_CMD},
 		};
-		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 			outb(program_seq[i].value, ioaddr + program_seq[i].offset);
 
 	}
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index d4c92cc..9ff7117 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1118,7 +1118,7 @@ static const struct netxen_brdinfo netxen_boards[] = {
 	{NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"},
 };
 
-#define NUM_SUPPORTED_BOARDS (sizeof(netxen_boards)/sizeof(struct netxen_brdinfo))
+#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards)
 
 static inline void get_brd_port_by_type(u32 type, int *ports)
 {
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a7b8d7f..2c19b8d 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -569,7 +569,7 @@ int netxen_is_flash_supported(struct netxen_adapter *adapter)
 	/* if the flash size less than 4Mb, make huge war cry and die */
 	for (j = 1; j < 4; j++) {
 		addr = j * NETXEN_NIC_WINDOW_MARGIN;
-		for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) {
+		for (i = 0; i < ARRAY_SIZE(locs); i++) {
 			if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
 			    && netxen_rom_fast_read(adapter, (addr + locs[i]),
 						    &val02) == 0) {
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 50dff1b..2f3c4dc 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -232,7 +232,7 @@ static int get_prom(struct pcmcia_device *link)
     axnet_reset_8390(dev);
     mdelay(10);
 
-    for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 	outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 
     for (i = 0; i < 6; i += 2) {
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 63de89e..02c245b 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -207,7 +207,7 @@ static hw_info_t hw_info[] = {
     { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
 };
 
-#define NR_INFO		(sizeof(hw_info)/sizeof(hw_info_t))
+#define NR_INFO		ARRAY_SIZE(hw_info)
 
 static hw_info_t default_info = { 0, 0, 0, 0, 0 };
 static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII };
@@ -375,7 +375,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link)
     pcnet_reset_8390(dev);
     mdelay(10);
 
-    for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(program_seq); i++)
 	outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
 
     for (i = 0; i < 32; i++)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e323efd..003e7e7 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -204,7 +204,7 @@ static const struct phy_setting settings[] = {
 	},
 };
 
-#define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting))
+#define MAX_NUM_SETTINGS ARRAY_SIZE(settings)
 
 /**
  * phy_find_setting - find a PHY settings array entry that matches speed & duplex
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index 75afc1f..ced2c8f 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1654,7 +1654,7 @@ static const struct smt_pdef {
 	{ SMT_P4053,	0,	SWAP_SMT_P4053			} ,
 } ;
 
-#define N_SMT_PLEN	(sizeof(smt_pdef)/sizeof(smt_pdef[0]))
+#define N_SMT_PLEN	ARRAY_SIZE(smt_pdef)
 
 int smt_check_para(struct s_smc *smc, struct smt_header	*sm,
 		   const u_short list[])
diff --git a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c
index 16573ac..6caf713 100644
--- a/drivers/net/skfp/srf.c
+++ b/drivers/net/skfp/srf.c
@@ -43,7 +43,7 @@ static void clear_reported(struct s_smc *smc);
 static void smt_send_srf(struct s_smc *smc);
 static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index);
 
-#define MAX_EVCS	(sizeof(smc->evcs)/sizeof(smc->evcs[0]))
+#define MAX_EVCS	ARRAY_SIZE(smc->evcs)
 
 struct evc_init {
 	u_char code ;
@@ -67,7 +67,7 @@ static const struct evc_init evc_inits[] = {
 	{ SMT_EVENT_PORT_PATH_CHANGE,		INDEX_PORT,NUMPHYS,SMT_P4053 } ,
 } ;
 
-#define MAX_INIT_EVC	(sizeof(evc_inits)/sizeof(evc_inits[0]))
+#define MAX_INIT_EVC	ARRAY_SIZE(evc_inits)
 
 void smt_init_evc(struct s_smc *smc)
 {
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 0990289..dcddaf7 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -3946,7 +3946,7 @@ create_packet(struct net_device *dev, char *frame, int len)
 static int
 EISA_signature(char *name, struct device *device)
 {
-    int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
+    int i, status = 0, siglen = ARRAY_SIZE(de4x5_signatures);
     struct eisa_device *edev;
 
     *name = '\0';
@@ -3967,7 +3967,7 @@ EISA_signature(char *name, struct device *device)
 static int
 PCI_signature(char *name, struct de4x5_private *lp)
 {
-    int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
+    int i, status = 0, siglen = ARRAY_SIZE(de4x5_signatures);
 
     if (lp->chipset == DC21040) {
 	strcpy(name, "DE434/5");
@@ -5073,7 +5073,7 @@ mii_get_phy(struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
     u_long iobase = dev->base_addr;
-    int i, j, k, n, limit=sizeof(phy_info)/sizeof(struct phy_table);
+    int i, j, k, n, limit=ARRAY_SIZE(phy_info);
     int id;
 
     lp->active = 0;
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index ee1cc14..7519f9c 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -7579,9 +7579,9 @@ static const iw_handler		airo_private_handler[] =
 
 static const struct iw_handler_def	airo_handler_def =
 {
-	.num_standard	= sizeof(airo_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(airo_private_handler)/sizeof(iw_handler),
-	.num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(airo_handler),
+	.num_private	= ARRAY_SIZE(airo_private_handler),
+	.num_private_args = ARRAY_SIZE(airo_private_args),
 	.standard	= airo_handler,
 	.private	= airo_private_handler,
 	.private_args	= airo_private_args,
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 8c71077..65dffbb 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3976,9 +3976,9 @@ static const iw_handler prism2_private_handler[] =
 
 const struct iw_handler_def hostap_iw_handler_def =
 {
-	.num_standard	= sizeof(prism2_handler) / sizeof(iw_handler),
-	.num_private	= sizeof(prism2_private_handler) / sizeof(iw_handler),
-	.num_private_args = sizeof(prism2_priv) / sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(prism2_handler),
+	.num_private	= ARRAY_SIZE(prism2_private_handler),
+	.num_private_args = ARRAY_SIZE(prism2_priv),
 	.standard	= (iw_handler *) prism2_handler,
 	.private	= (iw_handler *) prism2_private_handler,
 	.private_args	= (struct iw_priv_args *) prism2_priv,
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8990585..7ba033b 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -8279,10 +8279,9 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 
 static struct iw_handler_def ipw2100_wx_handler_def = {
 	.standard = ipw2100_wx_handlers,
-	.num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
-	.num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
-	.num_private_args = sizeof(ipw2100_private_args) /
-	    sizeof(struct iw_priv_args),
+	.num_standard = ARRAY_SIZE(ipw2100_wx_handlers),
+	.num_private = ARRAY_SIZE(ipw2100_private_handler),
+	.num_private_args = ARRAY_SIZE(ipw2100_private_args),
 	.private = (iw_handler *) ipw2100_private_handler,
 	.private_args = (struct iw_priv_args *)ipw2100_private_args,
 	.get_wireless_stats = ipw2100_wx_wireless_stats,
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 2dc84ff..c77b1f4 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -179,8 +179,7 @@ static void wlan_init_adapter(wlan_private * priv)
 
 	/* 802.11 specific */
 	adapter->secinfo.wep_enabled = 0;
-	for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
-	     i++)
+	for (i = 0; i < ARRAY_SIZE(adapter->wep_keys); i++)
 		memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
 	adapter->wep_tx_keyidx = 0;
 	adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 9f36624..db9e504 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -121,28 +121,28 @@ struct region_cfp_table {
 static struct region_cfp_table region_cfp_table[] = {
 	{0x10,			/*US FCC */
 	 channel_freq_power_US_BG,
-	 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_US_BG),
 	 }
 	,
 	{0x20,			/*CANADA IC */
 	 channel_freq_power_US_BG,
-	 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_US_BG),
 	 }
 	,
 	{0x30, /*EU*/ channel_freq_power_EU_BG,
-	 sizeof(channel_freq_power_EU_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_EU_BG),
 	 }
 	,
 	{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
-	 sizeof(channel_freq_power_SPN_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_SPN_BG),
 	 }
 	,
 	{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
-	 sizeof(channel_freq_power_FR_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_FR_BG),
 	 }
 	,
 	{0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
-	 sizeof(channel_freq_power_JPN_BG) / sizeof(struct chan_freq_power),
+	 ARRAY_SIZE(channel_freq_power_JPN_BG),
 	 }
 	,
 /*Add new region here */
@@ -1076,7 +1076,7 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c
 
 	lbs_deb_enter(LBS_DEB_MAIN);
 
-	end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
+	end = ARRAY_SIZE(region_cfp_table);
 
 	for (i = 0; i < end ; i++) {
 		lbs_deb_main("region_cfp_table[i].region=%d\n",
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 2fcc3bf..8a9379c 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -2298,13 +2298,13 @@ static const iw_handler mesh_wlan_handler[] = {
 	(iw_handler) NULL,		/* SIOCSIWPMKSA */
 };
 struct iw_handler_def libertas_handler_def = {
-	.num_standard	= sizeof(wlan_handler) / sizeof(iw_handler),
+	.num_standard	= ARRAY_SIZE(wlan_handler),
 	.standard	= (iw_handler *) wlan_handler,
 	.get_wireless_stats = wlan_get_wireless_stats,
 };
 
 struct iw_handler_def mesh_handler_def = {
-	.num_standard	= sizeof(mesh_wlan_handler) / sizeof(iw_handler),
+	.num_standard	= ARRAY_SIZE(mesh_wlan_handler),
 	.standard	= (iw_handler *) mesh_wlan_handler,
 	.get_wireless_stats = wlan_get_wireless_stats,
 };
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 45b00e1..c580188 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -710,9 +710,9 @@ static const iw_handler		netwave_private_handler[] =
 
 static const struct iw_handler_def	netwave_handler_def =
 {
-	.num_standard	= sizeof(netwave_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(netwave_private_handler)/sizeof(iw_handler),
-	.num_private_args = sizeof(netwave_private_args)/sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(netwave_handler),
+	.num_private	= ARRAY_SIZE(netwave_private_handler),
+	.num_private_args = ARRAY_SIZE(netwave_private_args),
 	.standard	= (iw_handler *) netwave_handler,
 	.private	= (iw_handler *) netwave_private_handler,
 	.private_args	= (struct iw_priv_args *) netwave_private_args,
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 585f599..19e2b50 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3239,10 +3239,9 @@ static const iw_handler prism54_private_handler[] = {
 };
 
 const struct iw_handler_def prism54_handler_def = {
-	.num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
-	.num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
-	.num_private_args =
-	    sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
+	.num_standard = ARRAY_SIZE(prism54_handler),
+	.num_private = ARRAY_SIZE(prism54_private_handler),
+	.num_private_args = ARRAY_SIZE(prism54_private_args),
 	.standard = (iw_handler *) prism54_handler,
 	.private = (iw_handler *) prism54_private_handler,
 	.private_args = (struct iw_priv_args *) prism54_private_args,
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 3be6242..6a93fc6 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1568,9 +1568,9 @@ static const struct iw_priv_args	ray_private_args[] = {
 
 static const struct iw_handler_def	ray_handler_def =
 {
-	.num_standard	= sizeof(ray_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(ray_private_handler)/sizeof(iw_handler),
-	.num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(ray_handler),
+	.num_private	= ARRAY_SIZE(ray_private_handler),
+	.num_private_args = ARRAY_SIZE(ray_private_args),
 	.standard	= ray_handler,
 	.private	= ray_private_handler,
 	.private_args	= ray_private_args,
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 1cf090d..d8803d6 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -2400,9 +2400,9 @@ static const struct iw_priv_args wavelan_private_args[] = {
 
 static const struct iw_handler_def	wavelan_handler_def =
 {
-	.num_standard	= sizeof(wavelan_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(wavelan_private_handler)/sizeof(iw_handler),
-	.num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(wavelan_handler),
+	.num_private	= ARRAY_SIZE(wavelan_private_handler),
+	.num_private_args = ARRAY_SIZE(wavelan_private_args),
 	.standard	= wavelan_handler,
 	.private	= wavelan_private_handler,
 	.private_args	= wavelan_private_args,
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 5740d4d..212afee 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -2719,9 +2719,9 @@ static const iw_handler		wavelan_private_handler[] =
 
 static const struct iw_handler_def	wavelan_handler_def =
 {
-	.num_standard	= sizeof(wavelan_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(wavelan_private_handler)/sizeof(iw_handler),
-	.num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+	.num_standard	= ARRAY_SIZE(wavelan_handler),
+	.num_private	= ARRAY_SIZE(wavelan_private_handler),
+	.num_private_args = ARRAY_SIZE(wavelan_private_args),
 	.standard	= wavelan_handler,
 	.private	= wavelan_private_handler,
 	.private_args	= wavelan_private_args,
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index c8b5c22..5874451 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1894,7 +1894,7 @@ static const iw_handler	wl3501_handler[] = {
 };
 
 static const struct iw_handler_def wl3501_handler_def = {
-	.num_standard	= sizeof(wl3501_handler) / sizeof(iw_handler),
+	.num_standard	= ARRAY_SIZE(wl3501_handler),
 	.standard	= (iw_handler *)wl3501_handler,
 	.get_wireless_stats = wl3501_get_wireless_stats,
 };
diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c
index d85e2ea..29f9750 100644
--- a/drivers/net/zorro8390.c
+++ b/drivers/net/zorro8390.c
@@ -191,7 +191,7 @@ static int __devinit zorro8390_init(struct net_device *dev,
 	    {0x00,	NE_EN0_RSARHI},
 	    {E8390_RREAD+E8390_START, NE_CMD},
 	};
-	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
 	    z_writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
 	}
     }
-- 
1.5.3.rc7


^ permalink raw reply related

* [PATCH 1/2] net/: all net/ cleanup with ARRAY_SIZE
From: Denis Cheng @ 2007-09-02 10:30 UTC (permalink / raw)
  To: Robert P. J. Day, David S. Miller; +Cc: netdev, linux-kernel, cr_quan
In-Reply-To: <Pine.LNX.4.64.0709020235420.22012@localhost.localdomain>

Signed-off-by: Denis Cheng <crquan@gmail.com>
---
 net/atm/proc.c      |    2 +-
 net/decnet/dn_dev.c |    2 +-
 net/ipv4/af_inet.c  |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/atm/proc.c b/net/atm/proc.c
index 99fc1fe..a3e52ff 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -175,7 +175,7 @@ static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
 
 	seq_printf(seq, "%3d %3d %5d %-3s %7d %-5s %7d %-6s",
 	    vcc->dev->number,vcc->vpi,vcc->vci,
-	    vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" :
+	    vcc->qos.aal >= ARRAY_SIZE(aal_name) ? "err" :
 	    aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
 	    class_name[vcc->qos.rxtp.traffic_class],vcc->qos.txtp.min_pcr,
 	    class_name[vcc->qos.txtp.traffic_class]);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index fa6604f..9470cb9 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -149,7 +149,7 @@ static struct dn_dev_parms dn_dev_list[] =  {
 }
 };
 
-#define DN_DEV_LIST_SIZE (sizeof(dn_dev_list)/sizeof(struct dn_dev_parms))
+#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
 
 #define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x))
 
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e681034..d5e8b67 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -939,7 +939,7 @@ static struct inet_protosw inetsw_array[] =
        }
 };
 
-#define INETSW_ARRAY_LEN (sizeof(inetsw_array) / sizeof(struct inet_protosw))
+#define INETSW_ARRAY_LEN ARRAY_SIZE(inetsw_array)
 
 void inet_register_protosw(struct inet_protosw *p)
 {
-- 
1.5.3.rc7


^ permalink raw reply related

* Re: Fwd: That whole "Linux stealing our code" thing
From: Alan Cox @ 2007-09-02 10:36 UTC (permalink / raw)
  To: Constantine A. Murenin
  Cc: Adrian Bunk, Jeff Garzik, linux-kernel, linux-wireless, netdev,
	Jiri Slaby
In-Reply-To: <f34ca13c0709011753h7733089dt48570480a7a19baa@mail.gmail.com>

> - If you receive ISC or BSD licensed code, you may not delete the
>  license.  Same principle, since the notice says so.  It's the law.
>  Really.

You can shout this all you like but you would be wrong. You can remove
the licence if you have permission to do so. For the ath c files there
was permission to do so.

> My understanding is that with dual-licensed code, you choose to comply
> with all of the terms of either licence. However, you cannot simply
> remove either of these licences from the code, unless you specifically
> receive such right from the copyright holder (remember, with the
> copyright law, unless the rights are specifically given, they are
> retained). This is what Theo was trying to educate the community on. I
> don't see anything unethical in explaining the legal issues.

Your understanding isn't quite right. One of many things you may get with
dual licensed code is the right to pick a licence from several choices,
you may also get the right to remove some choices from the recipient.

A work that combines GPL and BSD licensed material is not the same as a
work which says I may choose between two licences. If both licences must
always apply (which is a perfectly possible condition to put in a
licence) then putting such a "both" GPL/BSD licence piece of code into
OpenBSD would require any OpenBSD distributed containing it was GPL
licenced when conveyed, which I am *very* sure is not the intent.

Thus what you appear to be doing by putting the ath5k C code in OpenBSD is
conveying it under the BSD licence (making a choice between the two
offered) and conveying a right for parties down the chain to convey it
under one of the licences only.

And as we've already established the header files are quite different.


Doesn't mean its not somewhat rude but illegal and rude are two very
different things.


^ permalink raw reply

* Re: That whole "Linux stealing our code" thing
From: Alan Cox @ 2007-09-02 10:18 UTC (permalink / raw)
  To: Jonathan Gray
  Cc: Jason Dixon, bunk, mureninc, jeff, linux-kernel, linux-wireless,
	netdev, jirislaby
In-Reply-To: <20070902022253.GA18201@mail.netspace.net.au>

> co-operation. Together we advance our detective work and knowledge of
> the Macintosh platforms to the good of all Macintosh users dumped"
> 
> Alan Cox circa 1999.
> 
> http://lists.freedesktop.org/archives/xorg/2007-August/027419.html
> 
> "well I'd be quite happy to see X go GPL but I'm aware
> thats not the intention of the project ;)"
> Alan Cox circa 2007.
> 
> What changed? 

Nothing that I am aware of. You can't take Linux/Mac68K code back into
BSD either. BSD code is being used according to the BSD licence. You
could adopt a different licence if the way your code is being used
bothers you, thats.

Where I've reused BSD code I've aways tried to contribute it back to the
BSD people or share the knowledge (and the knowledge far more than the
code mattered both ways for Mac68K systems)

I suggest you read drivers/net/wan/syncppp.c, which is I think the only
BSD derived bit of code of mine left in the kernel - and its quite
specific what it says.

Ath5k isn't my code so I don't get to pick. Having the OpenBSD maintainer
make bogus remarks about that doesn't help anyone, especially when he's
wrong and doesn't appear to know about the subject in the first place.

Alan

^ permalink raw reply

* [PATCH] remove setup of platform device from jazzsonic.c
From: Thomas Bogendoerfer @ 2007-09-02  8:41 UTC (permalink / raw)
  To: akpm, jgarzik; +Cc: netdev


remove setup platform device from jazzsonic, which is done in arch code now

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 75f6f44..435060a 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -45,7 +45,6 @@
 #include <asm/jazzdma.h>
 
 static char jazz_sonic_string[] = "jazzsonic";
-static struct platform_device *jazz_sonic_device;
 
 #define SONIC_MEM_SIZE	0x100
 
@@ -70,14 +69,6 @@ static unsigned int sonic_debug = 1;
 #endif
 
 /*
- * Base address and interrupt of the SONIC controller on JAZZ boards
- */
-static struct {
-	unsigned int port;
-	unsigned int irq;
-} sonic_portlist[] = { {JAZZ_ETHERNET_BASE, JAZZ_ETHERNET_IRQ}, {0, 0}};
-
-/*
  * We cannot use station (ethernet) address prefixes to detect the
  * sonic controller since these are board manufacturer depended.
  * So we check for known Silicon Revision IDs instead.
@@ -215,13 +206,12 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
 	struct sonic_local *lp;
+	struct resource *res;
 	int err = 0;
 	int i;
 
-	/*
-	 * Don't probe if we're not running on a Jazz board.
-	 */
-	if (mips_machgroup != MACH_GROUP_JAZZ)
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
 		return -ENODEV;
 
 	dev = alloc_etherdev(sizeof(struct sonic_local));
@@ -235,20 +225,9 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
 
 	netdev_boot_setup_check(dev);
 
-	if (dev->base_addr >= KSEG0) { /* Check a single specified location. */
-		err = sonic_probe1(dev);
-	} else if (dev->base_addr != 0) { /* Don't probe at all. */
-		err = -ENXIO;
-	} else {
-		for (i = 0; sonic_portlist[i].port; i++) {
-			dev->base_addr = sonic_portlist[i].port;
-			dev->irq = sonic_portlist[i].irq;
-			if (sonic_probe1(dev) == 0)
-				break;
-		}
-		if (!sonic_portlist[i].port)
-			err = -ENODEV;
-	}
+	dev->base_addr = res->start;
+	dev->irq = platform_get_irq(pdev, 0);
+	err = sonic_probe1(dev);
 	if (err)
 		goto out;
 	err = register_netdev(dev);
@@ -303,38 +282,12 @@ static struct platform_driver jazz_sonic_driver = {
 
 static int __init jazz_sonic_init_module(void)
 {
-	int err;
-
-	if ((err = platform_driver_register(&jazz_sonic_driver))) {
-		printk(KERN_ERR "Driver registration failed\n");
-		return err;
-	}
-
-	jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);
-	if (!jazz_sonic_device)
-		goto out_unregister;
-
-	if (platform_device_add(jazz_sonic_device)) {
-		platform_device_put(jazz_sonic_device);
-		jazz_sonic_device = NULL;
-	}
-
-	return 0;
-
-out_unregister:
-	platform_driver_unregister(&jazz_sonic_driver);
-
-	return -ENOMEM;
+	return platform_driver_register(&jazz_sonic_driver);
 }
 
 static void __exit jazz_sonic_cleanup_module(void)
 {
 	platform_driver_unregister(&jazz_sonic_driver);
-
-	if (jazz_sonic_device) {
-		platform_device_unregister(jazz_sonic_device);
-		jazz_sonic_device = NULL;
-	}
 }
 
 module_init(jazz_sonic_init_module);
-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply related

* Re: 2.6.23-rc4-mm1 OOPS in forcedeth?
From: Satyam Sharma @ 2007-09-02  9:55 UTC (permalink / raw)
  To: thunder7; +Cc: Jeff Garzik, Andrew Morton, Linux Kernel Mailing List, netdev
In-Reply-To: <20070902061900.GA5595@amd64.of.nowhere>



On Sun, 2 Sep 2007, thunder7@xs4all.nl wrote:
> 
> > > thunder7@xs4all.nl wrote:
> > > > 
> > > > On this machine (Athlon 64 X2 4600, 4 GiB memory, lots of disks),
> > > > 2.6.23-rc1-mm2 runs fine. 2.6.23-rc4-mm1 reproducably dies within seconds of
> > > > starting
> > > > a rsync session on another PC against this machine.
> > > > 
> > > > NULL pointer dereference
> > > > code:	nv_napi_poll+0x108
> > > > trace:	net_rx_action+0xab
> > > > 	__do_softirq+0x74
> > > > 	call_softirq+0x1c
> > > > 	do_softirq+0x3d
> > > > 	irq_exit+0x85
> > > > 	do_IRQ+0x85
> > > > 	ret_from_intr+0x0
> 
> There are 4 pictures of oopses here:
> 
> http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_1.jpg
> http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_2.jpg
> http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_3.jpg
> http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_4.jpg

OK, I've been pouring over forcedeth.c and the newly introduce NAPI code,
but didn't debug this yet, so I'll at least lay out the situation so that
somebody else who's more experienced @netdev can pick up from here with
minimal time wastage.

Here's what's happening (repeatedly, reproducibly) on Jurriaan's x64 box:

(1) The following NULL dereference oops:

    nv_rx_process_optimized(), inlined from nv_napi_poll(), found that
    "skb" i.e. np->get_rx_ctx->skb == NULL when trying to update
    skb->ip_summed.

(2) The following BUG in napi_complete():

    BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));

    from the nv_napi_poll()->__netif_rx_complete()->napi_complete()
    callchain is triggering. IOW napi_complete() found that a NAPI
    poll wasn't/shouldn't have been scheduled at all (!)

The above two problems appear to be occurring independently, AFAICT.


Satyam

^ permalink raw reply

* 2.6.23-rc4-mm1 net bitops compile error
From: Adrian Bunk @ 2007-09-02  9:14 UTC (permalink / raw)
  To: Andrew Morton, Jiri Slaby; +Cc: linux-kernel, netdev
In-Reply-To: <20070831215822.26e1432b.akpm@linux-foundation.org>

defconfig fails with the following error on parisc:

<--  snip  -->

...
  CC      net/core/gen_estimator.o
In file included from include2/asm/bitops.h:111,
                 from /home/bunk/linux/kernel-2.6/linux-2.6.23-rc4-mm1/net/core/gen_estimator.c:18:
/home/bunk/linux/kernel-2.6/linux-2.6.23-rc4-mm1/include/asm-generic/bitops/non-atomic.h: 
In function '__set_bit':
/home/bunk/linux/kernel-2.6/linux-2.6.23-rc4-mm1/include/asm-generic/bitops/non-atomic.h:17: 
error: implicit declaration of function 'BIT_MASK'
/home/bunk/linux/kernel-2.6/linux-2.6.23-rc4-mm1/include/asm-generic/bitops/non-atomic.h:18: 
error: implicit declaration of function 'BIT_WORD'
make[3]: *** [net/core/gen_estimator.o] Error 1

<--  snip  -->

Either #include <asm/bitops.h> must become forbidden and #error or the 
move of the #define's to include/linux/bitops.h reverted.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply

* [RFC PATCH v0.2] net driver: mpc52xx fec
From: Domen Puncer @ 2007-09-02  7:41 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: netdev
In-Reply-To: <20070810095153.GC13994@moe.telargo.com>

Hi!

new in this version:
- fixed stuff that was commented on.
- added 7-wire support (compile at least, if someone has the hardware,
	please test!)
- ethtool support

(this obsoletes Sylvain's patch that's floating around:
 0008-drivers-net-Add-support-for-Freescale-MPC5200-SoC-i.patch)

If there are no objections, I would like this to be merged after
bestcomm (mpc52xx dma engine) patches hit mainline, and that will
hopefully be at the beginning of the 2.6.24 merge window.

--
Driver for ethernet on mpc5200/mpc5200b SoCs (FEC).


Signed-off-by: Domen Puncer <domen.puncer@telargo.com>

---
 arch/powerpc/boot/dts/lite5200b.dts |   18 
 arch/powerpc/sysdev/bestcomm/fec.h  |   15 
 drivers/net/Kconfig                 |    1 
 drivers/net/Makefile                |    1 
 drivers/net/fec_mpc52xx/Kconfig     |   25 
 drivers/net/fec_mpc52xx/Makefile    |    7 
 drivers/net/fec_mpc52xx/fec.c       | 1127 ++++++++++++++++++++++++++++++++++++
 drivers/net/fec_mpc52xx/fec.h       |  329 ++++++++++
 drivers/net/fec_mpc52xx/fec_phy.c   |  238 +++++++
 9 files changed, 1759 insertions(+), 2 deletions(-)

Index: linux.git/drivers/net/Kconfig
===================================================================
--- linux.git.orig/drivers/net/Kconfig
+++ linux.git/drivers/net/Kconfig
@@ -1956,6 +1956,7 @@ config NE_H8300
 	  controller on the Renesas H8/300 processor.
 
 source "drivers/net/fec_8xx/Kconfig"
+source "drivers/net/fec_mpc52xx/Kconfig"
 source "drivers/net/fs_enet/Kconfig"
 
 endif # NET_ETHERNET
Index: linux.git/drivers/net/Makefile
===================================================================
--- linux.git.orig/drivers/net/Makefile
+++ linux.git/drivers/net/Makefile
@@ -204,6 +204,7 @@ obj-$(CONFIG_SMC911X) += smc911x.o
 obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx/
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 
Index: linux.git/arch/powerpc/boot/dts/lite5200b.dts
===================================================================
--- linux.git.orig/arch/powerpc/boot/dts/lite5200b.dts
+++ linux.git/arch/powerpc/boot/dts/lite5200b.dts
@@ -306,10 +306,26 @@
 		ethernet@3000 {
 			device_type = "network";
 			compatible = "mpc5200b-fec\0mpc5200-fec";
-			reg = <3000 800>;
+			reg = <3000 400>;
 			mac-address = [ 02 03 04 05 06 07 ]; // Bad!
 			interrupts = <2 5 0>;
 			interrupt-parent = <&mpc5200_pic>;
+			phy-handle = <&phy0>;
+		};
+
+		mdio@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "mpc5200b-fec-phy";
+			reg = <3000 400>;	// fec range, since we need to setup fec interrupts
+			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
+			interrupt-parent = <&mpc5200_pic>;
+
+			phy0:ethernet-phy@0 {
+				device_type = "ethernet-phy";
+				reg = <0>;
+			};
 		};
 
 		ata@3a00 {
Index: linux.git/arch/powerpc/sysdev/bestcomm/fec.h
===================================================================
--- linux.git.orig/arch/powerpc/sysdev/bestcomm/fec.h
+++ linux.git/arch/powerpc/sysdev/bestcomm/fec.h
@@ -21,7 +21,20 @@ struct bcom_fec_bd {
 };
 
 #define BCOM_FEC_TX_BD_TFD	0x08000000ul	/* transmit frame done */
-#define BCOM_FEC_TX_BD_INT	0x04000000ul	/* interrupt */
+#define BCOM_FEC_TX_BD_TC	0x04000000ul	/* transmit CRC */
+#define BCOM_FEC_TX_BD_ABC	0x02000000ul	/* append bad CRC */
+
+#define BCOM_FEC_RX_BD_L	0x08000000ul	/* buffer is last in frame */
+#define BCOM_FEC_RX_BD_BC	0x00800000ul	/* DA is broadcast */
+#define BCOM_FEC_RX_BD_MC	0x00400000ul	/* DA is multicast and not broadcast */
+#define BCOM_FEC_RX_BD_LG	0x00200000ul	/* Rx frame length violation */
+#define BCOM_FEC_RX_BD_NO	0x00100000ul	/* Rx non-octet aligned frame */
+#define BCOM_FEC_RX_BD_CR	0x00040000ul	/* Rx CRC error */
+#define BCOM_FEC_RX_BD_OV	0x00020000ul	/* overrun */
+#define BCOM_FEC_RX_BD_TR	0x00010000ul	/* Rx frame truncated */
+#define BCOM_FEC_RX_BD_LEN_MASK	0x000007fful	/* mask for length of received frame */
+#define BCOM_FEC_RX_BD_ERRORS	(BCOM_FEC_RX_BD_LG | BCOM_FEC_RX_BD_NO | \
+		BCOM_FEC_RX_BD_CR | BCOM_FEC_RX_BD_OV | BCOM_FEC_RX_BD_TR)
 
 
 extern struct bcom_task *
Index: linux.git/drivers/net/fec_mpc52xx/Kconfig
===================================================================
--- /dev/null
+++ linux.git/drivers/net/fec_mpc52xx/Kconfig
@@ -0,0 +1,25 @@
+menu "MPC5200 Networking Options"
+	depends PPC_MPC52xx && NET_ETHERNET
+
+config FEC_MPC52xx
+	tristate "FEC Ethernet"
+	depends on NET_ETHERNET
+	select PPC_BESTCOMM
+	select PPC_BESTCOMM_FEC
+	select CRC32
+	---help---
+	  This option enables support for the MPC5200's on-chip
+	  Fast Ethernet Controller
+
+config FEC_MPC52xx_MDIO
+	bool "Use external Ethernet MII PHY"
+	depends on FEC_MPC52xx
+	select PHYLIB
+	default y
+	---help---
+	  The MPC5200's FEC can connect to the Ethernet either with
+	  an external MII PHY chip or 10 Mbps 7-wire interface
+	  (Motorola? industry standard).
+	  If your board uses an external PHY, say y, else n.
+
+endmenu
Index: linux.git/drivers/net/fec_mpc52xx/Makefile
===================================================================
--- /dev/null
+++ linux.git/drivers/net/fec_mpc52xx/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
+
+fec_mpc52xx-objs := fec.o
+
+ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
+fec_mpc52xx-objs += fec_phy.o
+endif
Index: linux.git/drivers/net/fec_mpc52xx/fec.c
===================================================================
--- /dev/null
+++ linux.git/drivers/net/fec_mpc52xx/fec.c
@@ -0,0 +1,1127 @@
+/*
+ * drivers/drivers/net/fec_mpc52xx/fec.c
+ *
+ * Driver for the MPC5200 Fast Ethernet Controller
+ *
+ * Originally written by Dale Farnsworth <dfarnsworth@mvista.com> and
+ * now maintained by Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2007  Domen Puncer, Telargo, Inc.
+ * Copyright (C) 2007  Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003-2004  MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/hardirq.h>
+#include <linux/delay.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/mpc52xx.h>
+
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/fec.h>
+
+#include "fec.h"
+
+#define DRIVER_NAME "mpc52xx-fec"
+
+static irqreturn_t fec_interrupt(int, void *);
+static irqreturn_t fec_rx_interrupt(int, void *);
+static irqreturn_t fec_tx_interrupt(int, void *);
+static struct net_device_stats *fec_get_stats(struct net_device *);
+static void fec_set_multicast_list(struct net_device *dev);
+static void fec_hw_init(struct net_device *dev);
+static void fec_stop(struct net_device *dev);
+static void fec_start(struct net_device *dev);
+static void fec_reset(struct net_device *dev);
+
+static u8 mpc52xx_fec_mac_addr[6];
+static const u8 null_mac[6];
+
+static void fec_tx_timeout(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+
+	dev_warn(&dev->dev, "transmit timed out\n");
+
+	fec_reset(dev);
+
+	priv->stats.tx_errors++;
+
+	if (!priv->tx_full)
+		netif_wake_queue(dev);
+}
+
+static void fec_set_paddr(struct net_device *dev, u8 *mac)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	out_be32(&fec->paddr1, *(u32 *)(&mac[0]));
+	out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE);
+}
+
+static void fec_get_paddr(struct net_device *dev, u8 *mac)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	*(u32 *)(&mac[0]) = in_be32(&fec->paddr1);
+	*(u16 *)(&mac[4]) = in_be32(&fec->paddr2) >> 16;
+}
+
+static int fec_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *sock = addr;
+
+	memcpy(dev->dev_addr, sock->sa_data, dev->addr_len);
+
+	fec_set_paddr(dev, sock->sa_data);
+	return 0;
+}
+
+static void fec_free_rx_buffers(struct bcom_task *s)
+{
+	struct sk_buff *skb;
+
+	while (!bcom_queue_empty(s)) {
+		skb = bcom_retrieve_buffer(s, NULL, NULL);
+		kfree_skb(skb);
+	}
+}
+
+static int fec_alloc_rx_buffers(struct bcom_task *rxtsk)
+{
+	while (!bcom_queue_full(rxtsk)) {
+		struct sk_buff *skb;
+		struct bcom_fec_bd *bd;
+
+		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+		if (skb == NULL)
+			return -EAGAIN;
+
+		/* zero out the initial receive buffers to aid debugging */
+		memset(skb->data, 0, FEC_RX_BUFFER_SIZE);
+
+		bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk);
+
+		bd->status = FEC_RX_BUFFER_SIZE;
+		bd->skb_pa = virt_to_phys(skb->data);
+
+		bcom_submit_next_buffer(rxtsk, skb);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_FEC_MPC52xx_MDIO
+/* based on generic_adjust_link from fs_enet-main.c */
+static void fec_adjust_link(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct phy_device *phydev = priv->phydev;
+	int new_state = 0;
+
+	if (phydev->link != PHY_DOWN) {
+		if (phydev->duplex != priv->duplex) {
+			struct mpc52xx_fec __iomem *fec = priv->fec;
+			u32 rcntrl;
+			u32 tcntrl;
+
+			new_state = 1;
+			priv->duplex = phydev->duplex;
+
+			rcntrl = in_be32(&fec->r_cntrl);
+			tcntrl = in_be32(&fec->x_cntrl);
+
+			rcntrl &= ~FEC_RCNTRL_DRT;
+			tcntrl &= ~FEC_TCNTRL_FDEN;
+			if (phydev->duplex == DUPLEX_FULL)
+				tcntrl |= FEC_TCNTRL_FDEN;	/* FD enable */
+			else
+				rcntrl |= FEC_RCNTRL_DRT;	/* disable Rx on Tx (HD) */
+
+			out_be32(&fec->r_cntrl, rcntrl);
+			out_be32(&fec->x_cntrl, tcntrl);
+		}
+
+		if (phydev->speed != priv->speed) {
+			new_state = 1;
+			priv->speed = phydev->speed;
+		}
+
+		if (priv->link == PHY_DOWN) {
+			new_state = 1;
+			priv->link = phydev->link;
+			netif_schedule(dev);
+			netif_carrier_on(dev);
+			netif_start_queue(dev);
+		}
+
+	} else if (priv->link) {
+		new_state = 1;
+		priv->link = PHY_DOWN;
+		priv->speed = 0;
+		priv->duplex = -1;
+		netif_stop_queue(dev);
+		netif_carrier_off(dev);
+	}
+
+	if (new_state && netif_msg_link(priv))
+		phy_print_status(phydev);
+}
+
+static int fec_init_phy(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct phy_device *phydev;
+	char phy_id[BUS_ID_SIZE];
+
+	struct device_node *dn, *phy_dn;
+	unsigned int phy_addr;
+	const phandle *ph;
+	const unsigned int *prop;
+	struct resource res;
+	int ret;
+
+	dn = priv->ofdev->node;
+	ph = of_get_property(dn, "phy-handle", NULL);
+	if (!ph) {
+		dev_err(&dev->dev, "can't find \"phy-handle\" in device tree\n");
+		return -ENODEV;
+	}
+	phy_dn = of_find_node_by_phandle(*ph);
+
+	prop = of_get_property(phy_dn, "reg", NULL);
+	ret = of_address_to_resource(phy_dn->parent, 0, &res);
+	if (ret) {
+		dev_err(&dev->dev, "of_address_to_resource failed\n");
+		return ret;
+	}
+
+	phy_addr = *prop;
+	of_node_put(phy_dn);
+
+	snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, res.start, phy_addr);
+
+	priv->link = PHY_DOWN;
+	priv->speed = 0;
+	priv->duplex = -1;
+
+	phydev = phy_connect(dev, phy_id, &fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+	if (IS_ERR(phydev)) {
+		dev_err(&dev->dev, "phy_connect failed\n");
+		return PTR_ERR(phydev);
+	}
+	dev_info(&dev->dev, "attached phy %i to driver %s\n",
+			phydev->addr, phydev->drv->name);
+
+	priv->phydev = phydev;
+
+	return 0;
+}
+
+static int fec_phy_start(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	int err;
+
+	err = fec_init_phy(dev);
+	if (err) {
+		dev_err(&dev->dev, "fec_init_phy failed\n");
+		return err;
+	}
+
+	/* reset phy - this also wakes it from PDOWN */
+	phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+	phy_start(priv->phydev);
+
+	return 0;
+}
+
+static void fec_phy_stop(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+
+	phy_disconnect(priv->phydev);
+	/* power down phy */
+	phy_stop(priv->phydev);
+	phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
+}
+
+static int fec_phy_mii_ioctl(struct fec_priv *priv,
+		struct mii_ioctl_data *mii_data, int cmd)
+{
+	return phy_mii_ioctl(priv->phydev, mii_data, cmd);
+}
+
+static void fec_phy_hw_init(struct fec_priv *priv)
+{
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	out_be32(&fec->mii_speed, priv->phy_speed);
+	out_be32(&fec->imask, in_be32(&fec->imask) | FEC_IMASK_MII);
+}
+#else
+static inline int fec_phy_start(struct net_device *dev) { return 0; }
+static inline void fec_phy_stop(struct net_device *dev) { }
+static inline int fec_phy_mii_ioctl(struct fec_priv *priv,
+		struct mii_ioctl_data *mii_data, int cmd) { return -ENOTSUPP; }
+static inline void fec_phy_hw_init(struct fec_priv *priv) { }
+#endif
+
+static int fec_open(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	int err = -EBUSY;
+
+	if (request_irq(dev->irq, &fec_interrupt, IRQF_DISABLED | IRQF_SHARED,
+	                DRIVER_NAME "_ctrl", dev)) {
+		dev_err(&dev->dev, "ctrl interrupt request failed\n");
+		goto out;
+	}
+	if (request_irq(priv->r_irq, &fec_rx_interrupt, IRQF_DISABLED,
+	                DRIVER_NAME "_rx", dev)) {
+		dev_err(&dev->dev, "rx interrupt request failed\n");
+		goto free_ctrl_irq;
+	}
+	if (request_irq(priv->t_irq, &fec_tx_interrupt, IRQF_DISABLED,
+	                DRIVER_NAME "_tx", dev)) {
+		dev_err(&dev->dev, "tx interrupt request failed\n");
+		goto free_2irqs;
+	}
+
+	bcom_fec_rx_reset(priv->rx_dmatsk);
+	bcom_fec_tx_reset(priv->tx_dmatsk);
+
+	err = fec_alloc_rx_buffers(priv->rx_dmatsk);
+	if (err) {
+		dev_err(&dev->dev, "fec_alloc_rx_buffers failed\n");
+		goto free_irqs;
+	}
+
+	err = fec_phy_start(dev);
+	if (err)
+		goto free_skbs;
+
+	bcom_enable(priv->rx_dmatsk);
+	bcom_enable(priv->tx_dmatsk);
+
+	fec_start(dev);
+
+	netif_start_queue(dev);
+
+	return 0;
+
+ free_skbs:
+	fec_free_rx_buffers(priv->rx_dmatsk);
+
+ free_irqs:
+	free_irq(priv->t_irq, dev);
+ free_2irqs:
+	free_irq(priv->r_irq, dev);
+ free_ctrl_irq:
+	free_irq(dev->irq, dev);
+ out:
+
+	return err;
+}
+
+static int fec_close(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+
+	fec_stop(dev);
+
+	fec_free_rx_buffers(priv->rx_dmatsk);
+
+	free_irq(dev->irq, dev);
+	free_irq(priv->r_irq, dev);
+	free_irq(priv->t_irq, dev);
+
+	fec_phy_stop(dev);
+
+	return 0;
+}
+
+/* This will only be invoked if your driver is _not_ in XOFF state.
+ * What this means is that you need not check it, and that this
+ * invariant will hold if you make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ */
+static int fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct bcom_fec_bd *bd;
+
+	if (bcom_queue_full(priv->tx_dmatsk)) {
+		if (net_ratelimit())
+			dev_err(&dev->dev, "transmit queue overrun\n");
+		return 1;
+	}
+
+	spin_lock_irq(&priv->lock);
+	dev->trans_start = jiffies;
+
+	bd = (struct bcom_fec_bd *)
+		bcom_prepare_next_buffer(priv->tx_dmatsk);
+
+	bd->status = skb->len | BCOM_FEC_TX_BD_TFD | BCOM_FEC_TX_BD_TC;
+	bd->skb_pa = virt_to_phys(skb->data);
+
+	bcom_submit_next_buffer(priv->tx_dmatsk, skb);
+
+	if (bcom_queue_full(priv->tx_dmatsk)) {
+		priv->tx_full = 1;
+		netif_stop_queue(dev);
+	}
+
+	spin_unlock_irq(&priv->lock);
+
+	return 0;
+}
+
+/* This handles BestComm transmit task interrupts
+ */
+static irqreturn_t fec_tx_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct fec_priv *priv = netdev_priv(dev);
+
+	spin_lock(&priv->lock);
+
+	while (bcom_buffer_done(priv->tx_dmatsk)) {
+		struct sk_buff *skb;
+		skb = bcom_retrieve_buffer(priv->tx_dmatsk, NULL, NULL);
+
+		priv->tx_full = 0;
+		dev_kfree_skb_irq(skb);
+	}
+
+	if (netif_queue_stopped(dev) && !priv->tx_full)
+		netif_wake_queue(dev);
+
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t fec_rx_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct fec_priv *priv = netdev_priv(dev);
+
+	while (bcom_buffer_done(priv->rx_dmatsk)) {
+		struct sk_buff *skb;
+		struct sk_buff *rskb;
+		struct bcom_fec_bd *bd;
+		u32 status;
+
+		rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status, NULL);
+
+		/* Test for errors in received frame */
+		if (status & BCOM_FEC_RX_BD_ERRORS) {
+			/* Drop packet and reuse the buffer */
+			bd = (struct bcom_fec_bd *)
+				bcom_prepare_next_buffer(priv->rx_dmatsk);
+
+			bd->status = FEC_RX_BUFFER_SIZE;
+			bd->skb_pa = virt_to_phys(rskb->data);
+
+			bcom_submit_next_buffer(priv->rx_dmatsk, rskb);
+
+			priv->stats.rx_dropped++;
+
+			continue;
+		}
+
+		/* skbs are allocated on open, so now we allocate a new one,
+		 * and remove the old (with the packet) */
+		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+		if (skb) {
+			/* Process the received skb */
+			int length = status & BCOM_FEC_RX_BD_LEN_MASK;
+
+			skb_put(rskb, length - 4);	/* length without CRC32 */
+
+			rskb->dev = dev;
+			rskb->protocol = eth_type_trans(rskb, dev);
+
+			netif_rx(rskb);
+			dev->last_rx = jiffies;
+		} else {
+			/* Can't get a new one : reuse the same & drop pkt */
+			dev_notice(&dev->dev, "Memory squeeze, dropping packet.\n");
+			priv->stats.rx_dropped++;
+
+			skb = rskb;
+		}
+
+		bd = (struct bcom_fec_bd *)
+			bcom_prepare_next_buffer(priv->rx_dmatsk);
+
+		bd->status = FEC_RX_BUFFER_SIZE;
+		bd->skb_pa = virt_to_phys(skb->data);
+
+		bcom_submit_next_buffer(priv->rx_dmatsk, skb);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t fec_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+	u32 ievent;
+
+	ievent = in_be32(&fec->ievent);
+
+	ievent &= ~FEC_IEVENT_MII;	/* mii is handled separately */
+	if (!ievent)
+		return IRQ_NONE;
+
+	out_be32(&fec->ievent, ievent);		/* clear pending events */
+
+	if (ievent & ~(FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
+		if (ievent & ~FEC_IEVENT_TFINT)
+			dev_dbg(&dev->dev, "ievent: %08x\n", ievent);
+		return IRQ_HANDLED;
+	}
+
+	if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
+		dev_warn(&dev->dev, "FEC_IEVENT_RFIFO_ERROR\n");
+	if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
+		dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
+
+	fec_reset(dev);
+
+	netif_wake_queue(dev);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *fec_get_stats(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	stats->rx_bytes = in_be32(&fec->rmon_r_octets);
+	stats->rx_packets = in_be32(&fec->rmon_r_packets);
+	stats->rx_errors = in_be32(&fec->rmon_r_crc_align) +
+		in_be32(&fec->rmon_r_undersize) +
+		in_be32(&fec->rmon_r_oversize) +
+		in_be32(&fec->rmon_r_frag) +
+		in_be32(&fec->rmon_r_jab);
+
+	stats->tx_bytes = in_be32(&fec->rmon_t_octets);
+	stats->tx_packets = in_be32(&fec->rmon_t_packets);
+	stats->tx_errors = in_be32(&fec->rmon_t_crc_align) +
+		in_be32(&fec->rmon_t_undersize) +
+		in_be32(&fec->rmon_t_oversize) +
+		in_be32(&fec->rmon_t_frag) +
+		in_be32(&fec->rmon_t_jab);
+
+	stats->multicast = in_be32(&fec->rmon_r_mc_pkt);
+	stats->collisions = in_be32(&fec->rmon_t_col);
+
+	/* detailed rx_errors: */
+	stats->rx_length_errors = in_be32(&fec->rmon_r_undersize)
+					+ in_be32(&fec->rmon_r_oversize)
+					+ in_be32(&fec->rmon_r_frag)
+					+ in_be32(&fec->rmon_r_jab);
+	stats->rx_over_errors = in_be32(&fec->r_macerr);
+	stats->rx_crc_errors = in_be32(&fec->ieee_r_crc);
+	stats->rx_frame_errors = in_be32(&fec->ieee_r_align);
+	stats->rx_fifo_errors = in_be32(&fec->rmon_r_drop);
+	stats->rx_missed_errors = in_be32(&fec->rmon_r_drop);
+
+	/* detailed tx_errors: */
+	stats->tx_aborted_errors = 0;
+	stats->tx_carrier_errors = in_be32(&fec->ieee_t_cserr);
+	stats->tx_fifo_errors = in_be32(&fec->rmon_t_drop);
+	stats->tx_heartbeat_errors = in_be32(&fec->ieee_t_sqe);
+	stats->tx_window_errors = in_be32(&fec->ieee_t_lcol);
+
+	return stats;
+}
+
+/*
+ * Read MIB counters in order to reset them,
+ * then zero all the stats fields in memory
+ */
+static void fec_reset_stats(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	out_be32(&fec->mib_control, FEC_MIB_DISABLE);
+	memset_io(&fec->rmon_t_drop, 0,	(__force u32)&fec->reserved10 -
+			(__force u32)&fec->rmon_t_drop);
+	out_be32(&fec->mib_control, 0);
+
+	memset(&priv->stats, 0, sizeof(priv->stats));
+}
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ */
+static void fec_set_multicast_list(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+	u32 rx_control;
+
+	rx_control = in_be32(&fec->r_cntrl);
+
+	if (dev->flags & IFF_PROMISC) {
+		rx_control |= FEC_RCNTRL_PROM;
+		out_be32(&fec->r_cntrl, rx_control);
+	} else {
+		rx_control &= ~FEC_RCNTRL_PROM;
+		out_be32(&fec->r_cntrl, rx_control);
+
+		if (dev->flags & IFF_ALLMULTI) {
+			out_be32(&fec->gaddr1, 0xffffffff);
+			out_be32(&fec->gaddr2, 0xffffffff);
+		} else {
+			u32 crc;
+			int i;
+			struct dev_mc_list *dmi;
+			u32 gaddr1 = 0x00000000;
+			u32 gaddr2 = 0x00000000;
+
+			dmi = dev->mc_list;
+			for (i=0; i<dev->mc_count; i++) {
+				crc = ether_crc_le(6, dmi->dmi_addr) >> 26;
+				if (crc >= 32)
+					gaddr1 |= 1 << (crc-32);
+				else
+					gaddr2 |= 1 << crc;
+				dmi = dmi->next;
+			}
+			out_be32(&fec->gaddr1, gaddr1);
+			out_be32(&fec->gaddr2, gaddr2);
+		}
+	}
+}
+
+static void __init fec_str2mac(char *str, unsigned char *mac)
+{
+	int i;
+	u64 val64;
+
+	val64 = simple_strtoull(str, NULL, 16);
+
+	for (i = 0; i < 6; i++)
+		mac[5-i] = val64 >> (i*8);
+}
+
+static int __init mpc52xx_fec_mac_setup(char *mac_address)
+{
+	fec_str2mac(mac_address, mpc52xx_fec_mac_addr);
+	return 0;
+}
+
+__setup("mpc52xx-mac=", mpc52xx_fec_mac_setup);
+
+/**
+ * fec_hw_init
+ * @dev: network device
+ *
+ * Setup various hardware setting, only needed once on start
+ */
+static void fec_hw_init(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+	int i;
+
+	/* Whack a reset.  We should wait for this. */
+	out_be32(&fec->ecntrl, FEC_ECNTRL_RESET);
+	for (i = 0; i < FEC_RESET_DELAY; ++i) {
+		if ((in_be32(&fec->ecntrl) & FEC_ECNTRL_RESET) == 0)
+			break;
+		udelay(1);
+	}
+	if (i == FEC_RESET_DELAY)
+		dev_err(&dev->dev, "FEC Reset timeout!\n");
+
+	/* set pause to 0x20 frames */
+	out_be32(&fec->op_pause, FEC_OP_PAUSE_OPCODE | 0x20);
+
+	/* high service request will be deasserted when there's < 7 bytes in fifo
+	 * low service request will be deasserted when there's < 4*7 bytes in fifo
+	 */
+	out_be32(&fec->rfifo_cntrl, FEC_FIFO_CNTRL_FRAME | FEC_FIFO_CNTRL_LTG_7);
+	out_be32(&fec->tfifo_cntrl, FEC_FIFO_CNTRL_FRAME | FEC_FIFO_CNTRL_LTG_7);
+
+	/* alarm when <= x bytes in FIFO */
+	out_be32(&fec->rfifo_alarm, 0x0000030c);
+	out_be32(&fec->tfifo_alarm, 0x00000100);
+
+	/* begin transmittion when 256 bytes are in FIFO (or EOF or FIFO full) */
+	out_be32(&fec->x_wmrk, FEC_FIFO_WMRK_256B);
+
+	/* enable crc generation */
+	out_be32(&fec->xmit_fsm, FEC_XMIT_FSM_APPEND_CRC | FEC_XMIT_FSM_ENABLE_CRC);
+	out_be32(&fec->iaddr1, 0x00000000);	/* No individual filter */
+	out_be32(&fec->iaddr2, 0x00000000);	/* No individual filter */
+
+	/* set phy speed and enable MII interrupt
+	 * this can't be done in phy driver, since it needs to be called
+	 * before fec stuff (even on resume) */
+	fec_phy_hw_init(priv);
+}
+
+/**
+ * fec_start
+ * @dev: network device
+ *
+ * This function is called to start or restart the FEC during a link
+ * change.  This happens on fifo errors or when switching between half
+ * and full duplex.
+ */
+static void fec_start(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+	u32 rcntrl;
+	u32 tcntrl;
+	u32 tmp;
+
+	/* clear sticky error bits */
+	tmp = FEC_FIFO_STATUS_ERR | FEC_FIFO_STATUS_UF | FEC_FIFO_STATUS_OF;
+	out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status) & tmp);
+	out_be32(&fec->tfifo_status, in_be32(&fec->tfifo_status) & tmp);
+
+	/* FIFOs will reset on fec_enable */
+	out_be32(&fec->reset_cntrl, FEC_RESET_CNTRL_ENABLE_IS_RESET);
+
+	/* Set station address. */
+	fec_set_paddr(dev, dev->dev_addr);
+
+	fec_set_multicast_list(dev);
+
+	/* set max frame len, enable flow control, select mii mode */
+	rcntrl = FEC_RX_BUFFER_SIZE << 16;	/* max frame length */
+	rcntrl |= FEC_RCNTRL_FCE;
+	rcntrl |= MII_RCNTL_MODE;
+	if (priv->duplex == DUPLEX_FULL)
+		tcntrl = FEC_TCNTRL_FDEN;	/* FD enable */
+	else {
+		rcntrl |= FEC_RCNTRL_DRT;	/* disable Rx on Tx (HD) */
+		tcntrl = 0;
+	}
+	out_be32(&fec->r_cntrl, rcntrl);
+	out_be32(&fec->x_cntrl, tcntrl);
+
+	/* Clear any outstanding interrupt. */
+	out_be32(&fec->ievent, 0xffffffff);
+
+	/* Enable interrupts we wish to service. */
+	out_be32(&fec->imask, FEC_IMASK_ENABLE);
+
+	/* And last, enable the transmit and receive processing. */
+	out_be32(&fec->ecntrl, FEC_ECNTRL_ETHER_EN);
+	out_be32(&fec->r_des_active, 0x01000000);
+
+	priv->tx_full = 0;
+}
+
+/**
+ * fec_stop
+ * @dev: network device
+ *
+ * stop all activity on fec and empty dma buffers
+ */
+static void fec_stop(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+	unsigned long timeout;
+
+	/* disable all but MII interrupt */
+	out_be32(&fec->imask, in_be32(&fec->imask) & FEC_IMASK_MII);
+
+	/* Disable the rx task. */
+	bcom_disable(priv->rx_dmatsk);
+
+	/* Wait for tx queue to drain, but only if we're in process context */
+	if (!in_interrupt()) {
+		timeout = jiffies + msecs_to_jiffies(2000);
+		while (time_before(jiffies, timeout) &&
+				!bcom_queue_empty(priv->tx_dmatsk))
+			msleep(100);
+
+		if (time_after_eq(jiffies, timeout))
+			dev_err(&dev->dev, "queues didn't drain\n");
+#if 1
+		if (time_after_eq(jiffies, timeout)) {
+			dev_err(&dev->dev, "  tx: index: %i, outdex: %i\n",
+					priv->tx_dmatsk->index,
+					priv->tx_dmatsk->outdex);
+			dev_err(&dev->dev, "  rx: index: %i, outdex: %i\n",
+					priv->rx_dmatsk->index,
+					priv->rx_dmatsk->outdex);
+		}
+#endif
+	}
+
+	bcom_disable(priv->tx_dmatsk);
+
+	/* Stop FEC */
+	out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
+
+	return;
+}
+
+/* reset fec and bestcomm tasks */
+static void fec_reset(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	struct mpc52xx_fec __iomem *fec = priv->fec;
+
+	fec_stop(dev);
+
+	out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status));
+	out_be32(&fec->reset_cntrl, FEC_RESET_CNTRL_RESET_FIFO);
+
+	fec_free_rx_buffers(priv->rx_dmatsk);
+
+	fec_hw_init(dev);
+
+	phy_stop(priv->phydev);
+	phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+	phy_start(priv->phydev);
+
+	bcom_fec_rx_reset(priv->rx_dmatsk);
+	bcom_fec_tx_reset(priv->tx_dmatsk);
+
+	fec_alloc_rx_buffers(priv->rx_dmatsk);
+
+	fec_start(dev);
+}
+
+
+/* ethtool interface */
+static void fec_get_drvinfo(struct net_device *dev,
+		struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, DRIVER_NAME);
+}
+
+static int fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static u32 fec_get_msglevel(struct net_device *dev)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	return priv->msg_enable;
+}
+
+static void fec_set_msglevel(struct net_device *dev, u32 level)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+	priv->msg_enable = level;
+}
+
+static const struct ethtool_ops fec_ethtool_ops = {
+	.get_drvinfo = fec_get_drvinfo,
+	.get_settings = fec_get_settings,
+	.set_settings = fec_set_settings,
+	.get_link = ethtool_op_get_link,
+	.get_msglevel = fec_get_msglevel,
+	.set_msglevel = fec_set_msglevel,
+};
+
+
+static int fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct fec_priv *priv = netdev_priv(dev);
+
+	return fec_phy_mii_ioctl(priv, if_mii(rq), cmd);
+}
+
+/* ======================================================================== */
+/* OF Driver                                                                */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
+{
+	int rv;
+	struct net_device *ndev;
+	struct fec_priv *priv = NULL;
+	struct resource mem;
+
+	phys_addr_t rx_fifo;
+	phys_addr_t tx_fifo;
+
+	/* Get the ether ndev & it's private zone */
+	ndev = alloc_etherdev(sizeof(struct fec_priv));
+	if (!ndev)
+		return -ENOMEM;
+
+	priv = netdev_priv(ndev);
+
+	priv->ofdev = op;
+
+	/* Reserve FEC control zone */
+	rv = of_address_to_resource(op->node, 0, &mem);
+	if (rv) {
+		printk(KERN_ERR DRIVER_NAME ": "
+				"Error while parsing device node resource\n" );
+		return rv;
+	}
+	if ((mem.end - mem.start + 1) != sizeof(struct mpc52xx_fec)) {
+		printk(KERN_ERR DRIVER_NAME
+			" - invalid resource size (%lx != %x), check mpc52xx_devices.c\n",
+			(unsigned long)(mem.end - mem.start + 1), sizeof(struct mpc52xx_fec));
+		return -EINVAL;
+	}
+
+	if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec), DRIVER_NAME))
+		return -EBUSY;
+
+	/* Init ether ndev with what we have */
+	ndev->open		= fec_open;
+	ndev->stop		= fec_close;
+	ndev->hard_start_xmit	= fec_hard_start_xmit;
+	ndev->do_ioctl		= fec_ioctl;
+	ndev->ethtool_ops	= &fec_ethtool_ops;
+	ndev->get_stats		= fec_get_stats;
+	ndev->set_mac_address	= fec_set_mac_address;
+	ndev->set_multicast_list = fec_set_multicast_list;
+	ndev->tx_timeout	= fec_tx_timeout;
+	ndev->watchdog_timeo	= FEC_WATCHDOG_TIMEOUT;
+	ndev->flags &= ~IFF_RUNNING;
+	ndev->base_addr		= mem.start;
+
+	priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
+
+	spin_lock_init(&priv->lock);
+
+	/* ioremap the zones */
+	priv->fec = ioremap(mem.start, sizeof(struct mpc52xx_fec));
+
+	if (!priv->fec) {
+		rv = -ENOMEM;
+		goto probe_error;
+	}
+
+	/* Bestcomm init */
+	rx_fifo = ndev->base_addr + offsetof(struct mpc52xx_fec, rfifo_data);
+	tx_fifo = ndev->base_addr + offsetof(struct mpc52xx_fec, tfifo_data);
+
+	priv->rx_dmatsk = bcom_fec_rx_init(FEC_RX_NUM_BD, rx_fifo, FEC_RX_BUFFER_SIZE);
+	priv->tx_dmatsk = bcom_fec_tx_init(FEC_TX_NUM_BD, tx_fifo);
+
+	if (!priv->rx_dmatsk || !priv->tx_dmatsk) {
+		printk(KERN_ERR DRIVER_NAME ": Can not init SDMA tasks\n" );
+		rv = -ENOMEM;
+		goto probe_error;
+	}
+
+	/* Get the IRQ we need one by one */
+		/* Control */
+	ndev->irq = irq_of_parse_and_map(op->node, 0);
+
+		/* RX */
+	priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk);
+
+		/* TX */
+	priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk);
+
+	/* MAC address init */
+	if (memcmp(mpc52xx_fec_mac_addr, null_mac, 6) != 0)
+		memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
+	else
+		fec_get_paddr(ndev, ndev->dev_addr);
+
+	/* Phy speed */
+	priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
+
+	priv->msg_enable = (NETIF_MSG_IFUP << 1) - 1;
+	priv->duplex = DUPLEX_FULL;
+
+	/* Hardware init */
+	fec_hw_init(ndev);
+
+	fec_reset_stats(ndev);
+
+	/* Register the new network device */
+	rv = register_netdev(ndev);
+	if (rv < 0)
+		goto probe_error;
+
+	/* We're done ! */
+	dev_set_drvdata(&op->dev, ndev);
+
+	return 0;
+
+
+	/* Error handling - free everything that might be allocated */
+probe_error:
+
+	irq_dispose_mapping(ndev->irq);
+
+	if (priv->rx_dmatsk)
+		bcom_fec_rx_release(priv->rx_dmatsk);
+	if (priv->tx_dmatsk)
+		bcom_fec_tx_release(priv->tx_dmatsk);
+
+	if (priv->fec)
+		iounmap(priv->fec);
+
+	release_mem_region(mem.start, sizeof(struct mpc52xx_fec));
+
+	free_netdev(ndev);
+
+	return rv;
+}
+
+static int
+mpc52xx_fec_remove(struct of_device *op)
+{
+	struct net_device *ndev;
+	struct fec_priv *priv;
+
+	ndev = dev_get_drvdata(&op->dev);
+	if (!ndev)
+		return 0;
+	priv = netdev_priv(ndev);
+
+	unregister_netdev(ndev);
+
+	irq_dispose_mapping(ndev->irq);
+
+	bcom_fec_rx_release(priv->rx_dmatsk);
+	bcom_fec_tx_release(priv->tx_dmatsk);
+
+	iounmap(priv->fec);
+
+	release_mem_region(ndev->base_addr, sizeof(struct mpc52xx_fec));
+
+	free_netdev(ndev);
+
+	dev_set_drvdata(&op->dev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mpc52xx_fec_of_suspend(struct of_device *op, pm_message_t state)
+{
+	struct net_device *dev = dev_get_drvdata(&op->dev);
+
+	if (netif_running(dev))
+		fec_close(dev);
+
+	return 0;
+}
+
+static int mpc52xx_fec_of_resume(struct of_device *op)
+{
+	struct net_device *dev = dev_get_drvdata(&op->dev);
+
+	fec_hw_init(dev);
+	fec_reset_stats(dev);
+
+	if (netif_running(dev))
+		fec_open(dev);
+
+	return 0;
+}
+#endif
+
+static struct of_device_id mpc52xx_fec_match[] = {
+	{
+		.type		= "network",
+		.compatible	= "mpc5200-fec",
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, mpc52xx_fec_match);
+
+static struct of_platform_driver mpc52xx_fec_driver = {
+	.owner		= THIS_MODULE,
+	.name		= DRIVER_NAME,
+	.match_table	= mpc52xx_fec_match,
+	.probe		= mpc52xx_fec_probe,
+	.remove		= mpc52xx_fec_remove,
+#ifdef CONFIG_PM
+	.suspend	= mpc52xx_fec_of_suspend,
+	.resume		= mpc52xx_fec_of_resume,
+#endif
+};
+
+
+/* ======================================================================== */
+/* Module                                                                   */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_fec_init(void)
+{
+	int ret;
+	ret = fec_mdio_init();
+	if (ret) {
+		printk(KERN_ERR DRIVER_NAME ": fec_mdio_init failed\n");
+		return ret;
+	}
+
+	return of_register_platform_driver(&mpc52xx_fec_driver);
+}
+
+static void __exit
+mpc52xx_fec_exit(void)
+{
+	of_unregister_platform_driver(&mpc52xx_fec_driver);
+	fec_mdio_exit();
+}
+
+
+module_init(mpc52xx_fec_init);
+module_exit(mpc52xx_fec_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dale Farnsworth");
+MODULE_DESCRIPTION("Ethernet driver for the Freescale MPC52xx FEC");
+
Index: linux.git/drivers/net/fec_mpc52xx/fec.h
===================================================================
--- /dev/null
+++ linux.git/drivers/net/fec_mpc52xx/fec.h
@@ -0,0 +1,329 @@
+/*
+ * drivers/drivers/net/fec_mpc52xx/fec.h
+ *
+ * Driver for the MPC5200 Fast Ethernet Controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth@mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __DRIVERS_NET_MPC52XX_FEC_H__
+#define __DRIVERS_NET_MPC52XX_FEC_H__
+
+#include <linux/phy.h>
+
+/* Tunable constant */
+/* FEC_RX_BUFFER_SIZE includes 4 bytes for CRC32 */
+#define FEC_RX_BUFFER_SIZE	1522	/* max receive packet size */
+#define FEC_RX_NUM_BD		64
+#define FEC_TX_NUM_BD		64
+
+#define FEC_RESET_DELAY		50 	/* uS */
+
+#define FEC_WATCHDOG_TIMEOUT	((400*HZ)/1000)
+
+struct fec_priv {
+	int duplex;
+	int tx_full;
+	int r_irq;
+	int t_irq;
+	struct mpc52xx_fec __iomem *fec;
+	struct bcom_task *rx_dmatsk;
+	struct bcom_task *tx_dmatsk;
+	spinlock_t lock;
+	struct net_device_stats stats;
+	int msg_enable;
+	struct of_device *ofdev;
+	uint phy_speed;
+#ifdef CONFIG_FEC_MPC52xx_MDIO
+	struct phy_device *phydev;
+	enum phy_state link;
+	int speed;
+#endif	/* CONFIG_FEC_MPC52xx_MDIO */
+};
+
+
+/* ======================================================================== */
+/* Hardware register sets & bits                                            */
+/* ======================================================================== */
+
+struct mpc52xx_fec {
+	u32 fec_id;			/* FEC + 0x000 */
+	u32 ievent;			/* FEC + 0x004 */
+	u32 imask;			/* FEC + 0x008 */
+
+	u32 reserved0[1];		/* FEC + 0x00C */
+	u32 r_des_active;		/* FEC + 0x010 */
+	u32 x_des_active;		/* FEC + 0x014 */
+	u32 r_des_active_cl;		/* FEC + 0x018 */
+	u32 x_des_active_cl;		/* FEC + 0x01C */
+	u32 ivent_set;			/* FEC + 0x020 */
+	u32 ecntrl;			/* FEC + 0x024 */
+
+	u32 reserved1[6];		/* FEC + 0x028-03C */
+	u32 mii_data;			/* FEC + 0x040 */
+	u32 mii_speed;			/* FEC + 0x044 */
+	u32 mii_status;			/* FEC + 0x048 */
+
+	u32 reserved2[5];		/* FEC + 0x04C-05C */
+	u32 mib_data;			/* FEC + 0x060 */
+	u32 mib_control;		/* FEC + 0x064 */
+
+	u32 reserved3[6];		/* FEC + 0x068-7C */
+	u32 r_activate;			/* FEC + 0x080 */
+	u32 r_cntrl;			/* FEC + 0x084 */
+	u32 r_hash;			/* FEC + 0x088 */
+	u32 r_data;			/* FEC + 0x08C */
+	u32 ar_done;			/* FEC + 0x090 */
+	u32 r_test;			/* FEC + 0x094 */
+	u32 r_mib;			/* FEC + 0x098 */
+	u32 r_da_low;			/* FEC + 0x09C */
+	u32 r_da_high;			/* FEC + 0x0A0 */
+
+	u32 reserved4[7];		/* FEC + 0x0A4-0BC */
+	u32 x_activate;			/* FEC + 0x0C0 */
+	u32 x_cntrl;			/* FEC + 0x0C4 */
+	u32 backoff;			/* FEC + 0x0C8 */
+	u32 x_data;			/* FEC + 0x0CC */
+	u32 x_status;			/* FEC + 0x0D0 */
+	u32 x_mib;			/* FEC + 0x0D4 */
+	u32 x_test;			/* FEC + 0x0D8 */
+	u32 fdxfc_da1;			/* FEC + 0x0DC */
+	u32 fdxfc_da2;			/* FEC + 0x0E0 */
+	u32 paddr1;			/* FEC + 0x0E4 */
+	u32 paddr2;			/* FEC + 0x0E8 */
+	u32 op_pause;			/* FEC + 0x0EC */
+
+	u32 reserved5[4];		/* FEC + 0x0F0-0FC */
+	u32 instr_reg;			/* FEC + 0x100 */
+	u32 context_reg;		/* FEC + 0x104 */
+	u32 test_cntrl;			/* FEC + 0x108 */
+	u32 acc_reg;			/* FEC + 0x10C */
+	u32 ones;			/* FEC + 0x110 */
+	u32 zeros;			/* FEC + 0x114 */
+	u32 iaddr1;			/* FEC + 0x118 */
+	u32 iaddr2;			/* FEC + 0x11C */
+	u32 gaddr1;			/* FEC + 0x120 */
+	u32 gaddr2;			/* FEC + 0x124 */
+	u32 random;			/* FEC + 0x128 */
+	u32 rand1;			/* FEC + 0x12C */
+	u32 tmp;			/* FEC + 0x130 */
+
+	u32 reserved6[3];		/* FEC + 0x134-13C */
+	u32 fifo_id;			/* FEC + 0x140 */
+	u32 x_wmrk;			/* FEC + 0x144 */
+	u32 fcntrl;			/* FEC + 0x148 */
+	u32 r_bound;			/* FEC + 0x14C */
+	u32 r_fstart;			/* FEC + 0x150 */
+	u32 r_count;			/* FEC + 0x154 */
+	u32 r_lag;			/* FEC + 0x158 */
+	u32 r_read;			/* FEC + 0x15C */
+	u32 r_write;			/* FEC + 0x160 */
+	u32 x_count;			/* FEC + 0x164 */
+	u32 x_lag;			/* FEC + 0x168 */
+	u32 x_retry;			/* FEC + 0x16C */
+	u32 x_write;			/* FEC + 0x170 */
+	u32 x_read;			/* FEC + 0x174 */
+
+	u32 reserved7[2];		/* FEC + 0x178-17C */
+	u32 fm_cntrl;			/* FEC + 0x180 */
+	u32 rfifo_data;			/* FEC + 0x184 */
+	u32 rfifo_status;		/* FEC + 0x188 */
+	u32 rfifo_cntrl;		/* FEC + 0x18C */
+	u32 rfifo_lrf_ptr;		/* FEC + 0x190 */
+	u32 rfifo_lwf_ptr;		/* FEC + 0x194 */
+	u32 rfifo_alarm;		/* FEC + 0x198 */
+	u32 rfifo_rdptr;		/* FEC + 0x19C */
+	u32 rfifo_wrptr;		/* FEC + 0x1A0 */
+	u32 tfifo_data;			/* FEC + 0x1A4 */
+	u32 tfifo_status;		/* FEC + 0x1A8 */
+	u32 tfifo_cntrl;		/* FEC + 0x1AC */
+	u32 tfifo_lrf_ptr;		/* FEC + 0x1B0 */
+	u32 tfifo_lwf_ptr;		/* FEC + 0x1B4 */
+	u32 tfifo_alarm;		/* FEC + 0x1B8 */
+	u32 tfifo_rdptr;		/* FEC + 0x1BC */
+	u32 tfifo_wrptr;		/* FEC + 0x1C0 */
+
+	u32 reset_cntrl;		/* FEC + 0x1C4 */
+	u32 xmit_fsm;			/* FEC + 0x1C8 */
+
+	u32 reserved8[3];		/* FEC + 0x1CC-1D4 */
+	u32 rdes_data0;			/* FEC + 0x1D8 */
+	u32 rdes_data1;			/* FEC + 0x1DC */
+	u32 r_length;			/* FEC + 0x1E0 */
+	u32 x_length;			/* FEC + 0x1E4 */
+	u32 x_addr;			/* FEC + 0x1E8 */
+	u32 cdes_data;			/* FEC + 0x1EC */
+	u32 status;			/* FEC + 0x1F0 */
+	u32 dma_control;		/* FEC + 0x1F4 */
+	u32 des_cmnd;			/* FEC + 0x1F8 */
+	u32 data;			/* FEC + 0x1FC */
+
+	u32 rmon_t_drop;		/* FEC + 0x200 */
+	u32 rmon_t_packets;		/* FEC + 0x204 */
+	u32 rmon_t_bc_pkt;		/* FEC + 0x208 */
+	u32 rmon_t_mc_pkt;		/* FEC + 0x20C */
+	u32 rmon_t_crc_align;		/* FEC + 0x210 */
+	u32 rmon_t_undersize;		/* FEC + 0x214 */
+	u32 rmon_t_oversize;		/* FEC + 0x218 */
+	u32 rmon_t_frag;		/* FEC + 0x21C */
+	u32 rmon_t_jab;			/* FEC + 0x220 */
+	u32 rmon_t_col;			/* FEC + 0x224 */
+	u32 rmon_t_p64;			/* FEC + 0x228 */
+	u32 rmon_t_p65to127;		/* FEC + 0x22C */
+	u32 rmon_t_p128to255;		/* FEC + 0x230 */
+	u32 rmon_t_p256to511;		/* FEC + 0x234 */
+	u32 rmon_t_p512to1023;		/* FEC + 0x238 */
+	u32 rmon_t_p1024to2047;		/* FEC + 0x23C */
+	u32 rmon_t_p_gte2048;		/* FEC + 0x240 */
+	u32 rmon_t_octets;		/* FEC + 0x244 */
+	u32 ieee_t_drop;		/* FEC + 0x248 */
+	u32 ieee_t_frame_ok;		/* FEC + 0x24C */
+	u32 ieee_t_1col;		/* FEC + 0x250 */
+	u32 ieee_t_mcol;		/* FEC + 0x254 */
+	u32 ieee_t_def;			/* FEC + 0x258 */
+	u32 ieee_t_lcol;		/* FEC + 0x25C */
+	u32 ieee_t_excol;		/* FEC + 0x260 */
+	u32 ieee_t_macerr;		/* FEC + 0x264 */
+	u32 ieee_t_cserr;		/* FEC + 0x268 */
+	u32 ieee_t_sqe;			/* FEC + 0x26C */
+	u32 t_fdxfc;			/* FEC + 0x270 */
+	u32 ieee_t_octets_ok;		/* FEC + 0x274 */
+
+	u32 reserved9[2];		/* FEC + 0x278-27C */
+	u32 rmon_r_drop;		/* FEC + 0x280 */
+	u32 rmon_r_packets;		/* FEC + 0x284 */
+	u32 rmon_r_bc_pkt;		/* FEC + 0x288 */
+	u32 rmon_r_mc_pkt;		/* FEC + 0x28C */
+	u32 rmon_r_crc_align;		/* FEC + 0x290 */
+	u32 rmon_r_undersize;		/* FEC + 0x294 */
+	u32 rmon_r_oversize;		/* FEC + 0x298 */
+	u32 rmon_r_frag;		/* FEC + 0x29C */
+	u32 rmon_r_jab;			/* FEC + 0x2A0 */
+
+	u32 rmon_r_resvd_0;		/* FEC + 0x2A4 */
+
+	u32 rmon_r_p64;			/* FEC + 0x2A8 */
+	u32 rmon_r_p65to127;		/* FEC + 0x2AC */
+	u32 rmon_r_p128to255;		/* FEC + 0x2B0 */
+	u32 rmon_r_p256to511;		/* FEC + 0x2B4 */
+	u32 rmon_r_p512to1023;		/* FEC + 0x2B8 */
+	u32 rmon_r_p1024to2047;		/* FEC + 0x2BC */
+	u32 rmon_r_p_gte2048;		/* FEC + 0x2C0 */
+	u32 rmon_r_octets;		/* FEC + 0x2C4 */
+	u32 ieee_r_drop;		/* FEC + 0x2C8 */
+	u32 ieee_r_frame_ok;		/* FEC + 0x2CC */
+	u32 ieee_r_crc;			/* FEC + 0x2D0 */
+	u32 ieee_r_align;		/* FEC + 0x2D4 */
+	u32 r_macerr;			/* FEC + 0x2D8 */
+	u32 r_fdxfc;			/* FEC + 0x2DC */
+	u32 ieee_r_octets_ok;		/* FEC + 0x2E0 */
+
+	u32 reserved10[7];		/* FEC + 0x2E4-2FC */
+
+	u32 reserved11[64];		/* FEC + 0x300-3FF */
+};
+
+#define	FEC_MIB_DISABLE			0x80000000
+
+#define	FEC_IEVENT_HBERR		0x80000000
+#define	FEC_IEVENT_BABR			0x40000000
+#define	FEC_IEVENT_BABT			0x20000000
+#define	FEC_IEVENT_GRA			0x10000000
+#define	FEC_IEVENT_TFINT		0x08000000
+#define	FEC_IEVENT_MII			0x00800000
+#define	FEC_IEVENT_LATE_COL		0x00200000
+#define	FEC_IEVENT_COL_RETRY_LIM	0x00100000
+#define	FEC_IEVENT_XFIFO_UN		0x00080000
+#define	FEC_IEVENT_XFIFO_ERROR		0x00040000
+#define	FEC_IEVENT_RFIFO_ERROR		0x00020000
+
+#define	FEC_IMASK_HBERR			0x80000000
+#define	FEC_IMASK_BABR			0x40000000
+#define	FEC_IMASK_BABT			0x20000000
+#define	FEC_IMASK_GRA			0x10000000
+#define	FEC_IMASK_MII			0x00800000
+#define	FEC_IMASK_LATE_COL		0x00200000
+#define	FEC_IMASK_COL_RETRY_LIM		0x00100000
+#define	FEC_IMASK_XFIFO_UN		0x00080000
+#define	FEC_IMASK_XFIFO_ERROR		0x00040000
+#define	FEC_IMASK_RFIFO_ERROR		0x00020000
+
+/* all but MII, which is enabled separately */
+#define FEC_IMASK_ENABLE	(FEC_IMASK_HBERR | FEC_IMASK_BABR | \
+		FEC_IMASK_BABT | FEC_IMASK_GRA | FEC_IMASK_LATE_COL | \
+		FEC_IMASK_COL_RETRY_LIM | FEC_IMASK_XFIFO_UN | \
+		FEC_IMASK_XFIFO_ERROR | FEC_IMASK_RFIFO_ERROR)
+
+#define	FEC_RCNTRL_MAX_FL_SHIFT		16
+#define	FEC_RCNTRL_LOOP			0x01
+#define	FEC_RCNTRL_DRT			0x02
+#define	FEC_RCNTRL_MII_MODE		0x04
+#define	FEC_RCNTRL_PROM			0x08
+#define	FEC_RCNTRL_BC_REJ		0x10
+#define	FEC_RCNTRL_FCE			0x20
+
+#define	FEC_TCNTRL_GTS			0x00000001
+#define	FEC_TCNTRL_HBC			0x00000002
+#define	FEC_TCNTRL_FDEN			0x00000004
+#define	FEC_TCNTRL_TFC_PAUSE		0x00000008
+#define	FEC_TCNTRL_RFC_PAUSE		0x00000010
+
+#define	FEC_ECNTRL_RESET		0x00000001
+#define	FEC_ECNTRL_ETHER_EN		0x00000002
+
+#define FEC_MII_DATA_ST			0x40000000	/* Start frame */
+#define FEC_MII_DATA_OP_RD		0x20000000	/* Perform read */
+#define FEC_MII_DATA_OP_WR		0x10000000	/* Perform write */
+#define FEC_MII_DATA_PA_MSK		0x0f800000	/* PHY Address mask */
+#define FEC_MII_DATA_RA_MSK		0x007c0000	/* PHY Register mask */
+#define FEC_MII_DATA_TA			0x00020000	/* Turnaround */
+#define FEC_MII_DATA_DATAMSK		0x0000ffff	/* PHY data mask */
+
+#define FEC_MII_READ_FRAME	(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA)
+#define FEC_MII_WRITE_FRAME	(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | FEC_MII_DATA_TA)
+
+#define FEC_MII_DATA_RA_SHIFT		0x12		/* MII reg addr bits */
+#define FEC_MII_DATA_PA_SHIFT		0x17		/* MII PHY addr bits */
+
+#define FEC_PADDR2_TYPE			0x8808
+
+#define FEC_OP_PAUSE_OPCODE		0x00010000
+
+#define FEC_FIFO_WMRK_256B		0x3
+
+#define FEC_FIFO_STATUS_ERR		0x00400000
+#define FEC_FIFO_STATUS_UF		0x00200000
+#define FEC_FIFO_STATUS_OF		0x00100000
+
+#define FEC_FIFO_CNTRL_FRAME		0x08000000
+#define FEC_FIFO_CNTRL_LTG_7		0x07000000
+
+#define FEC_RESET_CNTRL_RESET_FIFO	0x02000000
+#define FEC_RESET_CNTRL_ENABLE_IS_RESET	0x01000000
+
+#define FEC_XMIT_FSM_APPEND_CRC		0x02000000
+#define FEC_XMIT_FSM_ENABLE_CRC		0x01000000
+
+
+#ifdef CONFIG_FEC_MPC52xx_MDIO /* 18-wire MII mode */
+
+#define MII_RCNTL_MODE		FEC_RCNTRL_MII_MODE
+
+int __init fec_mdio_init(void);
+void __exit fec_mdio_exit(void);
+
+#else /* 7-wire 10 Mbps mode */
+
+#define MII_RCNTL_MODE		0
+
+static inline int __init fec_mdio_init(void) { return 0; }
+static inline void __exit fec_mdio_exit(void) { }
+
+#endif /* CONFIG_FEC_MPC52xx_MDIO */
+
+#endif	/* __DRIVERS_NET_MPC52XX_FEC_H__ */
Index: linux.git/drivers/net/fec_mpc52xx/fec_phy.c
===================================================================
--- /dev/null
+++ linux.git/drivers/net/fec_mpc52xx/fec_phy.c
@@ -0,0 +1,238 @@
+/*
+ * Driver for the MPC5200 Fast Ethernet Controller - PHY/MII part
+ *
+ * Copyright (C) 2007  Domen Puncer, Telargo, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <asm/io.h>
+#include <asm/mpc52xx.h>
+#include <asm/of_platform.h>
+#include "fec.h"
+
+struct fec_mdio_priv {
+	int completed;
+	wait_queue_head_t wq;
+	struct mpc52xx_fec __iomem *regs;
+	int irq;
+};
+
+static int fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+	struct fec_mdio_priv *priv = bus->priv;
+	int tries = 100;
+
+	u32 request = FEC_MII_READ_FRAME;
+	request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
+	request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
+
+	out_be32(&priv->regs->mii_data, request);
+
+	/* wait for it to finish, this takes about 23 us on lite5200b */
+	while (priv->completed == 0 && tries--)
+		udelay(5);
+
+	priv->completed = 0;
+
+	if (tries == 0)
+		return -ETIMEDOUT;
+
+	return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK;
+}
+
+static int fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data)
+{
+	struct fec_mdio_priv *priv = bus->priv;
+	u32 value = data;
+	int tries = 100;
+
+	value |= FEC_MII_WRITE_FRAME;
+	value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
+	value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
+
+	out_be32(&priv->regs->mii_data, value);
+
+	/* wait for request to finish */
+	while (priv->completed == 0 && tries--)
+		udelay(5);
+
+	priv->completed = 0;
+
+	if (tries == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static irqreturn_t fec_mdio_interrupt(int irq, void *dev_id)
+{
+	struct fec_mdio_priv *priv = dev_id;
+	struct mpc52xx_fec __iomem *fec;
+	int ievent;
+
+	fec = priv->regs;
+	ievent = in_be32(&fec->ievent);
+
+	ievent &= FEC_IEVENT_MII;
+	if (!ievent)
+		return IRQ_NONE;
+
+	out_be32(&fec->ievent, ievent);
+
+	priv->completed = 1;
+	wake_up(&priv->wq);
+
+	return IRQ_HANDLED;
+}
+
+static int fec_mdio_probe(struct of_device *of, const struct of_device_id *match)
+{
+	struct device *dev = &of->dev;
+	struct device_node *np = of->node;
+	struct device_node *child = NULL;
+	struct mii_bus *bus;
+	struct fec_mdio_priv *priv;
+	struct resource res = {};
+	int err;
+	int i;
+
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+	if (bus == NULL)
+		return -ENOMEM;
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (priv == NULL) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	bus->name = "mpc52xx MII bus";
+	bus->read = fec_mdio_read;
+	bus->write = fec_mdio_write;
+
+	/* setup irqs */
+	bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (bus->irq == NULL) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+	for (i=0; i<PHY_MAX_ADDR; i++)
+		bus->irq[i] = PHY_POLL;
+
+	while ((child = of_get_next_child(np, child)) != NULL) {
+		int irq = irq_of_parse_and_map(child, 0);
+		if (irq != NO_IRQ) {
+			const u32 *id = of_get_property(child, "reg", NULL);
+			bus->irq[*id] = irq;
+		}
+	}
+
+	/* setup registers */
+	err = of_address_to_resource(np, 0, &res);
+	if (err)
+		goto out_free;
+	priv->regs = ioremap(res.start, res.end - res.start + 1);
+	if (priv->regs == NULL) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	priv->irq = irq_of_parse_and_map(np, 0);
+	err = request_irq(priv->irq, &fec_mdio_interrupt, IRQF_DISABLED | IRQF_SHARED,
+	                "fec_mdio", priv);
+	if (err) {
+		printk(KERN_ERR "%s: interrupt request failed with %i\n", __func__, err);
+		goto out_unmap;
+	}
+
+	bus->id = res.start;
+	bus->priv = priv;
+
+	bus->dev = dev;
+	dev_set_drvdata(dev, bus);
+
+	init_waitqueue_head(&priv->wq);
+
+	/* set MII speed */
+	out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
+
+	/* enable MII interrupt */
+	out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII);
+
+	err = mdiobus_register(bus);
+	if (err)
+		goto out_free_irq;
+
+	return 0;
+
+ out_free_irq:
+	free_irq(priv->irq, dev);
+	irq_dispose_mapping(priv->irq);
+ out_unmap:
+	iounmap(priv->regs);
+ out_free:
+	for (i=0; i<PHY_MAX_ADDR; i++)
+		if (bus->irq[i] != PHY_POLL)
+			irq_dispose_mapping(bus->irq[i]);
+	kfree(bus->irq);
+	kfree(priv);
+	kfree(bus);
+
+	return err;
+}
+
+static int fec_mdio_remove(struct of_device *of)
+{
+	struct device *dev = &of->dev;
+	struct mii_bus *bus = dev_get_drvdata(dev);
+	struct fec_mdio_priv *priv = bus->priv;
+	int i;
+
+	mdiobus_unregister(bus);
+	dev_set_drvdata(dev, NULL);
+
+	free_irq(priv->irq, dev);
+	irq_dispose_mapping(priv->irq);
+	iounmap(priv->regs);
+	for (i=0; i<PHY_MAX_ADDR; i++)
+		if (bus->irq[i])
+			irq_dispose_mapping(bus->irq[i]);
+	kfree(priv);
+	kfree(bus->irq);
+	kfree(bus);
+
+	return 0;
+}
+
+
+static struct of_device_id fec_mdio_match[] = {
+	{
+		.type = "mdio",
+		.compatible = "mpc5200b-fec-phy",
+	},
+	{},
+};
+
+static struct of_platform_driver fec_mdio_driver = {
+	.name = "mpc5200b-fec-phy",
+	.probe = fec_mdio_probe,
+	.remove = fec_mdio_remove,
+	.match_table = fec_mdio_match,
+};
+
+
+int __init fec_mdio_init(void)
+{
+	return of_register_platform_driver(&fec_mdio_driver);
+}
+
+void __exit fec_mdio_exit(void)
+{
+	of_unregister_platform_driver(&fec_mdio_driver);
+}

^ permalink raw reply

* Re: Problem with implementation of TCP_DEFER_ACCEPT?
From: Andi Kleen @ 2007-09-02  7:30 UTC (permalink / raw)
  To: TJ; +Cc: netdev
In-Reply-To: <1187947887.6976.18.camel@bagoas.tjworld.net>

TJ <linux@tjworld.net> writes:
> 
> Therefore, anyone deploying apache web servers in a web-farm behind the
> Juniper DX load-balanders and using TCP multiplexing (for which they pay
> a hefty licence fee!) 

If they ask for that much money they can surely fix it to work
properly too? 

-Andi

^ permalink raw reply

* Re: 2.6.23-rc4-mm1 OOPS in forcedeth?
From: thunder7 @ 2007-09-02  6:19 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Jeff Garzik, thunder7, Andrew Morton, Linux Kernel Mailing List,
	netdev
In-Reply-To: <alpine.LFD.0.999.0709020610590.20781@enigma.security.iitk.ac.in>

From: Satyam Sharma <satyam@infradead.org>
Date: Sun, Sep 02, 2007 at 06:24:29AM +0530
> Hi Jurriaan,
> 
> 
> > thunder7@xs4all.nl wrote:
> > > From: Andrew Morton <akpm@linux-foundation.org>
> > > Date: Fri, Aug 31, 2007 at 09:58:22PM -0700
> > > > ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.23-rc4/2.6.23-rc4-mm1/
> > > > 
> > > On this machine (Athlon 64 X2 4600, 4 GiB memory, lots of disks),
> > > 2.6.23-rc1-mm2 runs fine. 2.6.23-rc4-mm1 reproducably dies within seconds of
> > > starting
> > > a rsync session on another PC against this machine.
> > > 
> > > NULL pointer dereference
> > > code:	nv_napi_poll+0x108
> > > trace:	net_rx_action+0xab
> > > 	__do_softirq+0x74
> > > 	call_softirq+0x1c
> > > 	do_softirq+0x3d
> > > 	irq_exit+0x85
> > > 	do_IRQ+0x85
> > > 	ret_from_intr+0x0
> 
> The dmesg you posted below doesn't cover the messages from this oops
> itself. As you mentioned you can reproduce this oops easily, please do so,
> and post the *full* oops log (if it doesn't get logged to disk, you can
> try taking digicam photo, or write down *all* the messages and post here).
> I built an x86_64 kernel as per your .config, but don't see any memory
> dereference at nv_napi_poll+0x108 -- could be toolchain differences.
> 
There are 4 pictures of oopses here:

http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_1.jpg
http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_2.jpg
http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_3.jpg
http://www.xs4all.nl/~thunder7/oops_2623rc4mm1_4.jpg

image quality, well, they're readable.

Good luck,
Jurriaan
-- 
management n.
1. Corporate power elites distinguished primarily by their distance from
actual productive work and their chronic failure to manage (see also suit).
Spoken derisively, as in "Management decided that ...". 2. Mythically, a
vast bureaucracy responsible for all the world's minor irritations.
Hackers' satirical public notices are often signed `The Mgt'; this derives
from the "Illuminatus" novels (see the Bibliography in Appendix C).
Debian (Unstable) GNU/Linux 2.6.23-rc1-mm2 2x2010 bogomips load 0.43
the Jack Vance Integral Edition: http://www.integralarchive.org

^ permalink raw reply

* Re: That whole "Linux stealing our code" thing
From: Valdis.Kletnieks-PjAqaU27lzQ @ 2007-09-02  5:46 UTC (permalink / raw)
  To: Constantine A. Murenin
  Cc: Adrian Bunk, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, Alan Cox,
	jirislaby-Re5JQEeQqe8AvxtiuMwx3w, Nick Kossifidis
In-Reply-To: <f34ca13c0709012209x64c282b9o1fd0cb7d08690247-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 402 bytes --]

On Sun, 02 Sep 2007 01:09:18 EDT, "Constantine A. Murenin" said:

> The idea here is that no patching was needed in the first place --
> most of the files are/were BSD-licensed, because they were forked from
> OpenBSD.

Oh, silly me.  For some reason, I had it in my head that Jiri's original
patch actually included some real live *code* in addition to the parts that
changed the licensing text... ;)

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply

* Re: 2.6.23-rc4-mm1 OOPS in forcedeth?
From: thunder7 @ 2007-09-02  5:36 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: Jeff Garzik, thunder7, Andrew Morton, Linux Kernel Mailing List,
	netdev
In-Reply-To: <alpine.LFD.0.999.0709020610590.20781@enigma.security.iitk.ac.in>

From: Satyam Sharma <satyam@infradead.org>
Date: Sun, Sep 02, 2007 at 06:24:29AM +0530
> 
> The dmesg you posted below doesn't cover the messages from this oops
> itself. As you mentioned you can reproduce this oops easily, please do so,
> and post the *full* oops log (if it doesn't get logged to disk, you can
> try taking digicam photo, or write down *all* the messages and post here).
> I built an x86_64 kernel as per your .config, but don't see any memory
> dereference at nv_napi_poll+0x108 -- could be toolchain differences.
> 
> Else, can you run:
> $ gdb ./vmlinux
> 
> and then:
> (gdb) l *nv_napi_poll+0x108
> 
> and send us the output?
> 
That seems to be the easier option:

AMD64 :gdb /usr/src/linux-2.6.23-rc4-mm1/vmlinux
GNU gdb 6.6-debian
(gdb) l *nv_napi_poll+0x108
0xffffffff80418f28 is in nv_napi_poll (drivers/net/forcedeth.c:2470).
2465				if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK2)/*ip and tcp */ {
2466					skb->ip_summed = CHECKSUM_UNNECESSARY;
2467				} else {
2468					if ((flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK1 ||
2469					    (flags & NV_RX2_CHECKSUMMASK) == NV_RX2_CHECKSUMOK3) {
2470						skb->ip_summed = CHECKSUM_UNNECESSARY;
2471					}
2472				}
2473	
2474				/* got a valid packet - forward it to the network core */
(gdb) q

as for toolchain differences: this is Debian Unstable, up-to-date as of
yesterday morning.

If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.
 
Linux middle 2.6.23-rc1-mm2 #1 SMP Wed Aug 1 14:58:22 CEST 2007 x86_64 GNU/Linux
 
Gnu C                  4.1.3
Gnu make               3.81
binutils               Binutils
util-linux             2.13
mount                  2.13
module-init-tools      3.3-pre11
e2fsprogs              1.40.2
reiserfsprogs          3.6.19
Linux C Library        6.1
Dynamic linker (ldd)   2.6.1
Procps                 3.2.7
Net-tools              1.60
Console-tools          0.2.3
Sh-utils               5.97
Modules Loaded         nf_nat_ftp nf_nat_irc nf_conntrack_irc nf_conntrack_ftp ipt_MASQUERADE iptable_nat nf_nat ipt_REJECT ipt_LOG xt_limit nf_conntrack_ipv4 xt_state xt_tcpudp iptable_filter ip_tables x_tables snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_emul snd_emu10k1 snd_seq_dummy snd_seq_oss snd_seq_midi snd_seq_midi_event snd_seq snd_rawmidi snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_device snd_timer snd_page_alloc snd_util_mem snd_hwdep snd soundcore k8temp it87 hwmon_vid hwmon i2c_nforce2

Good luck,
Jurriaan
-- 
His pride could withstand anything. He simply wouldn't care.
	Melanie Rawn - Skybowl
Debian (Unstable) GNU/Linux 2.6.23-rc1-mm2 2x2010 bogomips load 0.43
the Jack Vance Integral Edition: http://www.integralarchive.org

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox