Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
f5106b15
Commit
f5106b15
authored
Feb 18, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.6
into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents
ad920594
5b4f4d19
Changes
56
Show whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
915 additions
and
189 deletions
+915
-189
Documentation/networking/bonding.txt
Documentation/networking/bonding.txt
+40
-16
Documentation/networking/sk98lin.txt
Documentation/networking/sk98lin.txt
+3
-3
drivers/net/Kconfig
drivers/net/Kconfig
+3
-0
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.c
+12
-16
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_alb.c
+121
-21
drivers/net/bonding/bond_alb.h
drivers/net/bonding/bond_alb.h
+4
-1
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_main.c
+524
-63
drivers/net/bonding/bonding.h
drivers/net/bonding/bonding.h
+12
-2
drivers/net/depca.c
drivers/net/depca.c
+1
-1
drivers/net/hamradio/6pack.c
drivers/net/hamradio/6pack.c
+10
-10
drivers/net/hp100.c
drivers/net/hp100.c
+16
-3
drivers/net/pcnet32.c
drivers/net/pcnet32.c
+46
-39
drivers/net/sis190.c
drivers/net/sis190.c
+3
-3
drivers/net/sis900.c
drivers/net/sis900.c
+1
-1
drivers/net/sk98lin/h/lm80.h
drivers/net/sk98lin/h/lm80.h
+2
-0
drivers/net/sk98lin/h/skaddr.h
drivers/net/sk98lin/h/skaddr.h
+2
-0
drivers/net/sk98lin/h/skcsum.h
drivers/net/sk98lin/h/skcsum.h
+2
-0
drivers/net/sk98lin/h/skdebug.h
drivers/net/sk98lin/h/skdebug.h
+2
-0
drivers/net/sk98lin/h/skdrv1st.h
drivers/net/sk98lin/h/skdrv1st.h
+2
-0
drivers/net/sk98lin/h/skdrv2nd.h
drivers/net/sk98lin/h/skdrv2nd.h
+9
-1
drivers/net/sk98lin/h/skerror.h
drivers/net/sk98lin/h/skerror.h
+2
-0
drivers/net/sk98lin/h/skgedrv.h
drivers/net/sk98lin/h/skgedrv.h
+2
-0
drivers/net/sk98lin/h/skgehw.h
drivers/net/sk98lin/h/skgehw.h
+2
-0
drivers/net/sk98lin/h/skgehwt.h
drivers/net/sk98lin/h/skgehwt.h
+2
-0
drivers/net/sk98lin/h/skgei2c.h
drivers/net/sk98lin/h/skgei2c.h
+2
-0
drivers/net/sk98lin/h/skgeinit.h
drivers/net/sk98lin/h/skgeinit.h
+2
-0
drivers/net/sk98lin/h/skgepnm2.h
drivers/net/sk98lin/h/skgepnm2.h
+2
-0
drivers/net/sk98lin/h/skgepnmi.h
drivers/net/sk98lin/h/skgepnmi.h
+2
-0
drivers/net/sk98lin/h/skgesirq.h
drivers/net/sk98lin/h/skgesirq.h
+2
-0
drivers/net/sk98lin/h/ski2c.h
drivers/net/sk98lin/h/ski2c.h
+2
-0
drivers/net/sk98lin/h/skqueue.h
drivers/net/sk98lin/h/skqueue.h
+6
-0
drivers/net/sk98lin/h/skrlmt.h
drivers/net/sk98lin/h/skrlmt.h
+2
-0
drivers/net/sk98lin/h/sktimer.h
drivers/net/sk98lin/h/sktimer.h
+2
-0
drivers/net/sk98lin/h/sktypes.h
drivers/net/sk98lin/h/sktypes.h
+2
-0
drivers/net/sk98lin/h/skversion.h
drivers/net/sk98lin/h/skversion.h
+6
-4
drivers/net/sk98lin/h/skvpd.h
drivers/net/sk98lin/h/skvpd.h
+2
-0
drivers/net/sk98lin/h/xmac_ii.h
drivers/net/sk98lin/h/xmac_ii.h
+2
-0
drivers/net/sk98lin/skaddr.c
drivers/net/sk98lin/skaddr.c
+2
-0
drivers/net/sk98lin/skcsum.c
drivers/net/sk98lin/skcsum.c
+2
-0
drivers/net/sk98lin/skdim.c
drivers/net/sk98lin/skdim.c
+2
-0
drivers/net/sk98lin/skge.c
drivers/net/sk98lin/skge.c
+8
-1
drivers/net/sk98lin/skgehwt.c
drivers/net/sk98lin/skgehwt.c
+2
-0
drivers/net/sk98lin/skgeinit.c
drivers/net/sk98lin/skgeinit.c
+2
-1
drivers/net/sk98lin/skgemib.c
drivers/net/sk98lin/skgemib.c
+2
-0
drivers/net/sk98lin/skgepnmi.c
drivers/net/sk98lin/skgepnmi.c
+3
-0
drivers/net/sk98lin/skgesirq.c
drivers/net/sk98lin/skgesirq.c
+2
-0
drivers/net/sk98lin/ski2c.c
drivers/net/sk98lin/ski2c.c
+2
-0
drivers/net/sk98lin/sklm80.c
drivers/net/sk98lin/sklm80.c
+2
-0
drivers/net/sk98lin/skproc.c
drivers/net/sk98lin/skproc.c
+2
-1
drivers/net/sk98lin/skqueue.c
drivers/net/sk98lin/skqueue.c
+3
-0
drivers/net/sk98lin/skrlmt.c
drivers/net/sk98lin/skrlmt.c
+2
-0
drivers/net/sk98lin/sktimer.c
drivers/net/sk98lin/sktimer.c
+3
-0
drivers/net/sk98lin/skvpd.c
drivers/net/sk98lin/skvpd.c
+2
-0
drivers/net/sk98lin/skxmac2.c
drivers/net/sk98lin/skxmac2.c
+2
-0
drivers/net/tokenring/3c359.c
drivers/net/tokenring/3c359.c
+13
-0
drivers/net/tulip/interrupt.c
drivers/net/tulip/interrupt.c
+2
-2
No files found.
Documentation/networking/bonding.txt
View file @
f5106b15
...
...
@@ -31,6 +31,7 @@ Verifying Bond Configuration
Frequently Asked Questions
High Availability
Promiscuous Sniffing notes
8021q VLAN support
Limitations
Resources and Links
...
...
@@ -140,10 +141,6 @@ probeall bond0 eth0 eth1 bonding
Be careful not to reference bond0 itself at the end of the line, or modprobe
will die in an endless recursive loop.
To have device characteristics (such as MTU size) propagate to slave devices,
set the bond characteristics before enslaving the device. The characteristics
are propagated during the enslave process.
If running SNMP agents, the bonding driver should be loaded before any network
drivers participating in a bond. This requirement is due to the the interface
index (ipAdEntIfIndex) being associated to the first interface found with a
...
...
@@ -601,7 +598,7 @@ Frequently Asked Questions
For ethernet cards not supporting MII status, the arp_interval and
arp_ip_target parameters must be specified for bonding to work
correctly. If packets have not been sent or received during the
specified arp_interval dur
r
ation, an ARP request is sent to the
specified arp_interval duration, an ARP request is sent to the
targets to generate send and receive traffic. If after this
interval, either the successful send and/or receive count has not
incremented, the next slave in the sequence will become the active
...
...
@@ -669,16 +666,8 @@ Frequently Asked Questions
that will be added.
To restore your slaves' MAC addresses, you need to detach them
from the bond (`ifenslave -d bond0 eth0'), set them down
(`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for
example) and reload them to get the MAC addresses from their
eeproms. If the driver is shared by several devices, you need
to turn them all down. Another solution is to look for the MAC
address at boot time (dmesg or tail /var/log/messages) and to
reset it by hand with ifconfig :
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:20:40:60:80:A0
from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then
restore the MAC addresses that the slaves had before they were enslaved.
9. Which transmit polices can be used?
...
...
@@ -843,7 +832,7 @@ point of failure" solution.
In this configuration, there is an ISL - Inter Switch Link (could be a trunk),
several servers (host1, host2 ...) attached to both switches each, and one or
more ports to the outside world (port3...). One an only one slave on each host
more ports to the outside world (port3...). One an
d
only one slave on each host
is active at a time, while all links are still monitored (the system can
detect a failure of active and backup links).
...
...
@@ -933,6 +922,41 @@ capacity aggregating; but it works fine for unnumbered interfaces;
just ignore all the warnings it emits.
8021q VLAN support
==================
It is possible to configure VLAN devices over a bond interface using the 8021q
driver. However, only packets coming from the 8021q driver and passing through
bonding will be tagged by default. Self generated packets, like bonding's
learning packets or ARP packets generated by either ALB mode or the ARP
monitor mechanism, are tagged internally by bonding itself. As a result,
bonding has to "learn" what VLAN IDs are configured on top of it, and it uses
those IDs to tag self generated packets.
For simplicity reasons, and to support the use of adapters that can do VLAN
hardware acceleration offloding, the bonding interface declares itself as
fully hardware offloaing capable, it gets the add_vid/kill_vid notifications
to gather the necessary information, and it propagates those actions to the
slaves.
In case of mixed adapter types, hardware accelerated tagged packets that should
go through an adapter that is not offloading capable are "un-accelerated" by the
bonding driver so the VLAN tag sits in the regular location.
VLAN interfaces *must* be added on top of a bonding interface only after
enslaving at least one slave. This is because until the first slave is added the
bonding interface has a HW address of 00:00:00:00:00:00, which will be copied by
the VLAN interface when it is created.
Notice that a problem would occur if all slaves are released from a bond that
still has VLAN interfaces on top of it. When later coming to add new slaves, the
bonding interface would get a HW address from the first slave, which might not
match that of the VLAN interfaces. It is recommended that either all VLANs are
removed and then re-added, or to manually set the bonding interface's HW
address so it matches the VLAN's. (Note: changing a VLAN interface's HW address
would set the underlying device -- i.e. the bonding interface -- to promiscouos
mode, which might not be what you want).
Limitations
===========
The main limitations are :
...
...
Documentation/networking/sk98lin.txt
View file @
f5106b15
(C)Copyright 1999-200
3
Marvell(R).
(C)Copyright 1999-200
4
Marvell(R).
All rights reserved
===========================================================================
sk98lin.txt created 1
5-Dec-2003
sk98lin.txt created 1
3-Feb-2004
Readme File for sk98lin v6.2
1
Readme File for sk98lin v6.2
3
Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
This file contains
...
...
drivers/net/Kconfig
View file @
f5106b15
...
...
@@ -1985,6 +1985,7 @@ config SK98LIN
- Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971T Gigabit Ethernet Adapter
- Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
- DGE-530T Gigabit Ethernet Adapter
- EG1032 v2 Instant Gigabit Network Adapter
- EG1064 v2 Instant Gigabit Network Adapter
...
...
@@ -1996,6 +1997,7 @@ config SK98LIN
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
- Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
- Marvell RDK-8001 Adapter
- Marvell RDK-8002 Adapter
- Marvell RDK-8003 Adapter
...
...
@@ -2007,6 +2009,7 @@ config SK98LIN
- Marvell RDK-8010 Adapter
- Marvell RDK-8011 Adapter
- Marvell RDK-8012 Adapter
- Marvell RDK-8052 Adapter
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
- N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
...
...
drivers/net/bonding/bond_3ad.c
View file @
f5106b15
...
...
@@ -2362,6 +2362,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
int
agg_id
;
int
i
;
struct
ad_info
ad_info
;
int
res
=
1
;
/* make sure that the slaves list will
* not change during tx
...
...
@@ -2369,12 +2370,12 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
read_lock
(
&
bond
->
lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
if
(
bond_3ad_get_active_agg_info
(
bond
,
&
ad_info
))
{
printk
(
KERN_DEBUG
"ERROR: bond_3ad_get_active_agg_info failed
\n
"
);
goto
free_
out
;
goto
out
;
}
slaves_in_agg
=
ad_info
.
ports
;
...
...
@@ -2383,7 +2384,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if
(
slaves_in_agg
==
0
)
{
/*the aggregator is empty*/
printk
(
KERN_DEBUG
"ERROR: active aggregator is empty
\n
"
);
goto
free_
out
;
goto
out
;
}
slave_agg_no
=
(
data
->
h_dest
[
5
]
^
bond
->
dev
->
dev_addr
[
5
])
%
slaves_in_agg
;
...
...
@@ -2401,7 +2402,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if
(
slave_agg_no
>=
0
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: Couldn't find a slave to tx on for aggregator ID %d
\n
"
,
agg_id
);
goto
free_
out
;
goto
out
;
}
start_at
=
slave
;
...
...
@@ -2414,24 +2415,19 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
slave_agg_id
=
agg
->
aggregator_identifier
;
}
if
(
SLAVE_IS_OK
(
slave
)
&&
agg
&&
(
slave_agg_id
==
agg_id
))
{
skb
->
dev
=
slave
->
dev
;
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
goto
out
;
if
(
SLAVE_IS_OK
(
slave
)
&&
agg
&&
(
slave_agg_id
==
agg_id
))
{
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
slave
->
dev
);
break
;
}
}
out:
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
goto
out
;
}
read_unlock
(
&
bond
->
lock
);
return
0
;
}
int
bond_3ad_lacpdu_recv
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
ptype
)
...
...
drivers/net/bonding/bond_alb.c
View file @
f5106b15
...
...
@@ -34,6 +34,9 @@
*
* 2003/12/30 - Amir Noam <amir.noam at intel dot com>
* - Fixed: Cannot remove and re-enslave the original active slave.
*
* 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
* - Add capability to tag self generated packets in ALB/TLB modes.
*/
//#define BONDING_DEBUG 1
...
...
@@ -50,6 +53,7 @@
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_bonding.h>
#include <linux/if_vlan.h>
#include <net/ipx.h>
#include <net/arp.h>
#include <asm/byteorder.h>
...
...
@@ -79,7 +83,7 @@
#define TLB_NULL_INDEX 0xffffffff
#define MAX_LP_
RETRY
3
#define MAX_LP_
BURST
3
/* rlb defs */
#define RLB_HASH_TABLE_SIZE 256
...
...
@@ -498,13 +502,33 @@ static void rlb_update_client(struct rlb_client_info *client_info)
}
for
(
i
=
0
;
i
<
RLB_ARP_BURST_SIZE
;
i
++
)
{
arp_send
(
ARPOP_REPLY
,
ETH_P_ARP
,
struct
sk_buff
*
skb
;
skb
=
arp_create
(
ARPOP_REPLY
,
ETH_P_ARP
,
client_info
->
ip_dst
,
client_info
->
slave
->
dev
,
client_info
->
ip_src
,
client_info
->
mac_dst
,
client_info
->
slave
->
dev
->
dev_addr
,
client_info
->
mac_dst
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to create an ARP packet
\n
"
);
continue
;
}
skb
->
dev
=
client_info
->
slave
->
dev
;
if
(
client_info
->
tag
)
{
skb
=
vlan_put_tag
(
skb
,
client_info
->
vlan_id
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to insert VLAN tag
\n
"
);
continue
;
}
}
arp_xmit
(
skb
);
}
}
...
...
@@ -603,9 +627,10 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
}
/* Caller must hold both bond and ptr locks for read */
struct
slave
*
rlb_choose_channel
(
struct
bonding
*
bond
,
struct
arp_pkt
*
arp
)
struct
slave
*
rlb_choose_channel
(
struct
sk_buff
*
skb
,
struct
bonding
*
bond
)
{
struct
alb_bond_info
*
bond_info
=
&
(
BOND_ALB_INFO
(
bond
));
struct
arp_pkt
*
arp
=
(
struct
arp_pkt
*
)
skb
->
nh
.
raw
;
struct
slave
*
assigned_slave
;
struct
rlb_client_info
*
client_info
;
u32
hash_index
=
0
;
...
...
@@ -661,6 +686,15 @@ struct slave *rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
client_info
->
ntt
=
0
;
}
if
(
!
list_empty
(
&
bond
->
vlan_list
))
{
unsigned
short
vlan_id
;
int
res
=
vlan_get_tag
(
skb
,
&
vlan_id
);
if
(
!
res
)
{
client_info
->
tag
=
1
;
client_info
->
vlan_id
=
vlan_id
;
}
}
if
(
!
client_info
->
assigned
)
{
u32
prev_tbl_head
=
bond_info
->
rx_hashtbl_head
;
bond_info
->
rx_hashtbl_head
=
hash_index
;
...
...
@@ -691,7 +725,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
/* the arp must be sent on the selected
* rx channel
*/
tx_slave
=
rlb_choose_channel
(
bond
,
arp
);
tx_slave
=
rlb_choose_channel
(
skb
,
bond
);
if
(
tx_slave
)
{
memcpy
(
arp
->
mac_src
,
tx_slave
->
dev
->
dev_addr
,
ETH_ALEN
);
}
...
...
@@ -702,7 +736,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
* When the arp reply is received the entry will be updated
* with the correct unicast address of the client.
*/
rlb_choose_channel
(
bond
,
arp
);
rlb_choose_channel
(
skb
,
bond
);
/* The ARP relpy packets must be delayed so that
* they can cancel out the influence of the ARP request.
...
...
@@ -808,6 +842,40 @@ static void rlb_deinitialize(struct bonding *bond)
kfree
(
bond_info
->
rx_hashtbl
);
bond_info
->
rx_hashtbl
=
NULL
;
bond_info
->
rx_hashtbl_head
=
RLB_NULL_INDEX
;
_unlock_rx_hashtbl
(
bond
);
}
static
void
rlb_clear_vlan
(
struct
bonding
*
bond
,
unsigned
short
vlan_id
)
{
struct
alb_bond_info
*
bond_info
=
&
(
BOND_ALB_INFO
(
bond
));
u32
curr_index
;
_lock_rx_hashtbl
(
bond
);
curr_index
=
bond_info
->
rx_hashtbl_head
;
while
(
curr_index
!=
RLB_NULL_INDEX
)
{
struct
rlb_client_info
*
curr
=
&
(
bond_info
->
rx_hashtbl
[
curr_index
]);
u32
next_index
=
bond_info
->
rx_hashtbl
[
curr_index
].
next
;
u32
prev_index
=
bond_info
->
rx_hashtbl
[
curr_index
].
prev
;
if
(
curr
->
tag
&&
(
curr
->
vlan_id
==
vlan_id
))
{
if
(
curr_index
==
bond_info
->
rx_hashtbl_head
)
{
bond_info
->
rx_hashtbl_head
=
next_index
;
}
if
(
prev_index
!=
RLB_NULL_INDEX
)
{
bond_info
->
rx_hashtbl
[
prev_index
].
next
=
next_index
;
}
if
(
next_index
!=
RLB_NULL_INDEX
)
{
bond_info
->
rx_hashtbl
[
next_index
].
prev
=
prev_index
;
}
rlb_init_table_entry
(
curr
);
}
curr_index
=
next_index
;
}
_unlock_rx_hashtbl
(
bond
);
}
...
...
@@ -816,6 +884,7 @@ static void rlb_deinitialize(struct bonding *bond)
static
void
alb_send_learning_packets
(
struct
slave
*
slave
,
u8
mac_addr
[])
{
struct
bonding
*
bond
=
bond_get_bond_by_slave
(
slave
);
struct
learning_pkt
pkt
;
int
size
=
sizeof
(
struct
learning_pkt
);
int
i
;
...
...
@@ -825,7 +894,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
memcpy
(
pkt
.
mac_src
,
mac_addr
,
ETH_ALEN
);
pkt
.
type
=
__constant_htons
(
ETH_P_LOOP
);
for
(
i
=
0
;
i
<
MAX_LP_
RETRY
;
i
++
)
{
for
(
i
=
0
;
i
<
MAX_LP_
BURST
;
i
++
)
{
struct
sk_buff
*
skb
;
char
*
data
;
...
...
@@ -843,6 +912,26 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb
->
priority
=
TC_PRIO_CONTROL
;
skb
->
dev
=
slave
->
dev
;
if
(
!
list_empty
(
&
bond
->
vlan_list
))
{
struct
vlan_entry
*
vlan
;
vlan
=
bond_next_vlan
(
bond
,
bond
->
alb_info
.
current_alb_vlan
);
bond
->
alb_info
.
current_alb_vlan
=
vlan
;
if
(
!
vlan
)
{
kfree_skb
(
skb
);
continue
;
}
skb
=
vlan_put_tag
(
skb
,
vlan
->
vlan_id
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to insert VLAN tag
\n
"
);
continue
;
}
}
dev_queue_xmit
(
skb
);
}
}
...
...
@@ -1193,6 +1282,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
int
do_tx_balance
=
1
;
u32
hash_index
=
0
;
u8
*
hash_start
=
NULL
;
int
res
=
1
;
/* make sure that the curr_active_slave and the slaves list do
* not change during tx
...
...
@@ -1201,7 +1291,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
read_lock
(
&
bond
->
curr_slave_lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
switch
(
ntohs
(
skb
->
protocol
))
{
...
...
@@ -1266,29 +1356,27 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
if
(
tx_slave
&&
SLAVE_IS_OK
(
tx_slave
))
{
skb
->
dev
=
tx_slave
->
dev
;
if
(
tx_slave
!=
bond
->
curr_active_slave
)
{
memcpy
(
eth_data
->
h_source
,
tx_slave
->
dev
->
dev_addr
,
ETH_ALEN
);
}
dev_queue_xmit
(
skb
);
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
tx_slave
->
dev
);
}
else
{
/* no suitable interface, frame not sent */
if
(
tx_slave
)
{
tlb_clear_slave
(
bond
,
tx_slave
,
0
);
}
goto
free_out
;
}
out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
}
read_unlock
(
&
bond
->
curr_slave_lock
);
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
dev_kfree_skb
(
skb
);
goto
out
;
}
void
bond_alb_monitor
(
struct
bonding
*
bond
)
...
...
@@ -1589,3 +1677,15 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
return
0
;
}
void
bond_alb_clear_vlan
(
struct
bonding
*
bond
,
unsigned
short
vlan_id
)
{
if
(
bond
->
alb_info
.
current_alb_vlan
&&
(
bond
->
alb_info
.
current_alb_vlan
->
vlan_id
==
vlan_id
))
{
bond
->
alb_info
.
current_alb_vlan
=
NULL
;
}
if
(
bond
->
alb_info
.
rlb_enabled
)
{
rlb_clear_vlan
(
bond
,
vlan_id
);
}
}
drivers/net/bonding/bond_alb.h
View file @
f5106b15
...
...
@@ -77,6 +77,8 @@ struct rlb_client_info {
u8
assigned
;
/* checking whether this entry is assigned */
u8
ntt
;
/* flag - need to transmit client info */
struct
slave
*
slave
;
/* the slave assigned to this client */
u8
tag
;
/* flag - need to tag skb */
unsigned
short
vlan_id
;
/* VLAN tag associated with IP address */
};
struct
tlb_slave_info
{
...
...
@@ -122,6 +124,7 @@ struct alb_bond_info {
* rx traffic should be
* rebalanced
*/
struct
vlan_entry
*
current_alb_vlan
;
};
int
bond_alb_initialize
(
struct
bonding
*
bond
,
int
rlb_enabled
);
...
...
@@ -133,6 +136,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
int
bond_alb_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
bond_dev
);
void
bond_alb_monitor
(
struct
bonding
*
bond
);
int
bond_alb_set_mac_address
(
struct
net_device
*
bond_dev
,
void
*
addr
);
void
bond_alb_clear_vlan
(
struct
bonding
*
bond
,
unsigned
short
vlan_id
);
#endif
/* __BOND_ALB_H__ */
drivers/net/bonding/bond_main.c
View file @
f5106b15
...
...
@@ -455,12 +455,20 @@
*
* 2003/12/30 - Amir Noam <amir.noam at intel dot com>
* - Fixed: Cannot remove and re-enslave the original active slave.
* - Fixed: Releasing the original active slave causes mac address duplication.
* - Fixed: Releasing the original active slave causes mac address
* duplication.
* - Add support for slaves that use ethtool_ops.
* Set version to 2.5.3.
*
* 2004/01/05 - Amir Noam <amir.noam at intel dot com>
* - Save bonding parameters per bond instead of using the global values.
* Set version to 2.5.4.
*
* 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
* - Enhance VLAN support:
* * Add support for VLAN hardware acceleration capable slaves.
* * Add capability to tag self generated packets in ALB/TLB modes.
* Set version to 2.6.0.
*/
//#define BONDING_DEBUG 1
...
...
@@ -502,6 +510,7 @@
#include <net/arp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_bonding.h>
#include "bonding.h"
#include "bond_3ad.h"
...
...
@@ -620,6 +629,371 @@ static const char *bond_mode_name(int mode)
}
}
/*---------------------------------- VLAN -----------------------------------*/
/**
* bond_add_vlan - add a new vlan id on bond
* @bond: bond that got the notification
* @vlan_id: the vlan id to add
*
* Returns -ENOMEM if allocation failed.
*/
static
int
bond_add_vlan
(
struct
bonding
*
bond
,
unsigned
short
vlan_id
)
{
struct
vlan_entry
*
vlan
;
dprintk
(
"bond: %s, vlan id %d
\n
"
,
(
bond
?
bond
->
dev
->
name
:
"None"
),
vlan_id
);
vlan
=
kmalloc
(
sizeof
(
struct
vlan_entry
),
GFP_KERNEL
);
if
(
!
vlan
)
{
return
-
ENOMEM
;
}
INIT_LIST_HEAD
(
&
vlan
->
vlan_list
);
vlan
->
vlan_id
=
vlan_id
;
write_lock_bh
(
&
bond
->
lock
);
list_add_tail
(
&
vlan
->
vlan_list
,
&
bond
->
vlan_list
);
write_unlock_bh
(
&
bond
->
lock
);
dprintk
(
"added VLAN ID %d on bond %s
\n
"
,
vlan_id
,
bond
->
dev
->
name
);
return
0
;
}
/**
* bond_del_vlan - delete a vlan id from bond
* @bond: bond that got the notification
* @vlan_id: the vlan id to delete
*
* returns -ENODEV if @vlan_id was not found in @bond.
*/
static
int
bond_del_vlan
(
struct
bonding
*
bond
,
unsigned
short
vlan_id
)
{
struct
vlan_entry
*
vlan
,
*
next
;
int
res
=
-
ENODEV
;
dprintk
(
"bond: %s, vlan id %d
\n
"
,
bond
->
dev
->
name
,
vlan_id
);
write_lock_bh
(
&
bond
->
lock
);
list_for_each_entry_safe
(
vlan
,
next
,
&
bond
->
vlan_list
,
vlan_list
)
{
if
(
vlan
->
vlan_id
==
vlan_id
)
{
list_del
(
&
vlan
->
vlan_list
);
if
((
bond
->
params
.
mode
==
BOND_MODE_TLB
)
||
(
bond
->
params
.
mode
==
BOND_MODE_ALB
))
{
bond_alb_clear_vlan
(
bond
,
vlan_id
);
}
dprintk
(
"removed VLAN ID %d from bond %s
\n
"
,
vlan_id
,
bond
->
dev
->
name
);
kfree
(
vlan
);
if
(
list_empty
(
&
bond
->
vlan_list
)
&&
(
bond
->
slave_cnt
==
0
))
{
/* Last VLAN removed and no slaves, so
* restore block on adding VLANs. This will
* be removed once new slaves that are not
* VLAN challenged will be added.
*/
bond
->
dev
->
features
|=
NETIF_F_VLAN_CHALLENGED
;
}
res
=
0
;
goto
out
;
}
}
dprintk
(
"couldn't find VLAN ID %d in bond %s
\n
"
,
vlan_id
,
bond
->
dev
->
name
);
out:
write_unlock_bh
(
&
bond
->
lock
);
return
res
;
}
/**
* bond_has_challenged_slaves
* @bond: the bond we're working on
*
* Searches the slave list. Returns 1 if a vlan challenged slave
* was found, 0 otherwise.
*
* Assumes bond->lock is held.
*/
static
int
bond_has_challenged_slaves
(
struct
bonding
*
bond
)
{
struct
slave
*
slave
;
int
i
;
bond_for_each_slave
(
bond
,
slave
,
i
)
{
if
(
slave
->
dev
->
features
&
NETIF_F_VLAN_CHALLENGED
)
{
dprintk
(
"found VLAN challenged slave - %s
\n
"
,
slave
->
dev
->
name
);
return
1
;
}
}
dprintk
(
"no VLAN challenged slaves found
\n
"
);
return
0
;
}
/**
* bond_next_vlan - safely skip to the next item in the vlans list.
* @bond: the bond we're working on
* @curr: item we're advancing from
*
* Returns %NULL if list is empty, bond->next_vlan if @curr is %NULL,
* or @curr->next otherwise (even if it is @curr itself again).
*
* Caller must hold bond->lock
*/
struct
vlan_entry
*
bond_next_vlan
(
struct
bonding
*
bond
,
struct
vlan_entry
*
curr
)
{
struct
vlan_entry
*
next
,
*
last
;
if
(
list_empty
(
&
bond
->
vlan_list
))
{
return
NULL
;
}
if
(
!
curr
)
{
next
=
list_entry
(
bond
->
vlan_list
.
next
,
struct
vlan_entry
,
vlan_list
);
}
else
{
last
=
list_entry
(
bond
->
vlan_list
.
prev
,
struct
vlan_entry
,
vlan_list
);
if
(
last
==
curr
)
{
next
=
list_entry
(
bond
->
vlan_list
.
next
,
struct
vlan_entry
,
vlan_list
);
}
else
{
next
=
list_entry
(
curr
->
vlan_list
.
next
,
struct
vlan_entry
,
vlan_list
);
}
}
return
next
;
}
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
* @bond: bond device that got this skb for tx.
* @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff
*
* When the bond gets an skb to tarnsmit that is
* already hardware accelerated VLAN tagged, and it
* needs to relay this skb to a slave that is not
* hw accel capable, the skb needs to be "unaccelerated",
* i.e. strip the hwaccel tag and re-insert it as part
* of the payload.
*
* Assumption - once a VLAN device is created over the bond device, all
* packets are going to be hardware accelerated VLAN tagged since the IP
* binding is done over the VLAN device
*/
int
bond_dev_queue_xmit
(
struct
bonding
*
bond
,
struct
sk_buff
*
skb
,
struct
net_device
*
slave_dev
)
{
unsigned
short
vlan_id
;
int
res
;
if
(
!
list_empty
(
&
bond
->
vlan_list
)
&&
!
(
slave_dev
->
features
&
NETIF_F_HW_VLAN_TX
))
{
res
=
vlan_get_tag
(
skb
,
&
vlan_id
);
if
(
res
)
{
return
-
EINVAL
;
}
skb
->
dev
=
slave_dev
;
skb
=
vlan_put_tag
(
skb
,
vlan_id
);
if
(
!
skb
)
{
/* vlan_put_tag() frees the skb in case of error,
* so return success here so the calling functions
* won't attempt to free is again.
*/
return
0
;
}
}
else
{
skb
->
dev
=
slave_dev
;
}
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
return
0
;
}
/*
* In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid
* and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a
* lock because:
* a. This operation is performed in IOCTL context,
* b. The operation is protected by the RTNL semaphore in the 8021q code,
* c. Holding a lock with BH disabled while directly calling a base driver
* entry point is generally a BAD idea.
*
* The design of synchronization/protection for this operation in the 8021q
* module is good for one or more VLAN devices over a single physical device
* and cannot be extended for a teaming solution like bonding, so there is a
* potential race condition here where a net device from the vlan group might
* be referenced (either by a base driver or the 8021q code) while it is being
* removed from the system. However, it turns out we're not making matters
* worse, and if it works for regular VLAN usage it will work here too.
*/
/**
* bond_vlan_rx_register - Propagates registration to slaves
* @bond_dev: bonding net device that got called
* @grp: vlan group being registered
*/
static
void
bond_vlan_rx_register
(
struct
net_device
*
bond_dev
,
struct
vlan_group
*
grp
)
{
struct
bonding
*
bond
=
bond_dev
->
priv
;
struct
slave
*
slave
;
int
i
;
bond
->
vlgrp
=
grp
;
bond_for_each_slave
(
bond
,
slave
,
i
)
{
struct
net_device
*
slave_dev
=
slave
->
dev
;
if
((
slave_dev
->
features
&
NETIF_F_HW_VLAN_RX
)
&&
slave_dev
->
vlan_rx_register
)
{
slave_dev
->
vlan_rx_register
(
slave_dev
,
grp
);
}
}
}
/**
* bond_vlan_rx_add_vid - Propagates adding an id to slaves
* @bond_dev: bonding net device that got called
* @vid: vlan id being added
*/
static
void
bond_vlan_rx_add_vid
(
struct
net_device
*
bond_dev
,
uint16_t
vid
)
{
struct
bonding
*
bond
=
bond_dev
->
priv
;
struct
slave
*
slave
;
int
i
,
res
;
bond_for_each_slave
(
bond
,
slave
,
i
)
{
struct
net_device
*
slave_dev
=
slave
->
dev
;
if
((
slave_dev
->
features
&
NETIF_F_HW_VLAN_FILTER
)
&&
slave_dev
->
vlan_rx_add_vid
)
{
slave_dev
->
vlan_rx_add_vid
(
slave_dev
,
vid
);
}
}
res
=
bond_add_vlan
(
bond
,
vid
);
if
(
res
)
{
printk
(
KERN_ERR
DRV_NAME
": %s: Failed to add vlan id %d
\n
"
,
bond_dev
->
name
,
vid
);
}
}
/**
* bond_vlan_rx_kill_vid - Propagates deleting an id to slaves
* @bond_dev: bonding net device that got called
* @vid: vlan id being removed
*/
static
void
bond_vlan_rx_kill_vid
(
struct
net_device
*
bond_dev
,
uint16_t
vid
)
{
struct
bonding
*
bond
=
bond_dev
->
priv
;
struct
slave
*
slave
;
struct
net_device
*
vlan_dev
;
int
i
,
res
;
bond_for_each_slave
(
bond
,
slave
,
i
)
{
struct
net_device
*
slave_dev
=
slave
->
dev
;
if
((
slave_dev
->
features
&
NETIF_F_HW_VLAN_FILTER
)
&&
slave_dev
->
vlan_rx_kill_vid
)
{
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev
=
bond
->
vlgrp
->
vlan_devices
[
vid
];
slave_dev
->
vlan_rx_kill_vid
(
slave_dev
,
vid
);
bond
->
vlgrp
->
vlan_devices
[
vid
]
=
vlan_dev
;
}
}
res
=
bond_del_vlan
(
bond
,
vid
);
if
(
res
)
{
printk
(
KERN_ERR
DRV_NAME
": %s: Failed to remove vlan id %d
\n
"
,
bond_dev
->
name
,
vid
);
}
}
static
void
bond_add_vlans_on_slave
(
struct
bonding
*
bond
,
struct
net_device
*
slave_dev
)
{
struct
vlan_entry
*
vlan
;
write_lock_bh
(
&
bond
->
lock
);
if
(
list_empty
(
&
bond
->
vlan_list
))
{
goto
out
;
}
if
((
slave_dev
->
features
&
NETIF_F_HW_VLAN_RX
)
&&
slave_dev
->
vlan_rx_register
)
{
slave_dev
->
vlan_rx_register
(
slave_dev
,
bond
->
vlgrp
);
}
if
(
!
(
slave_dev
->
features
&
NETIF_F_HW_VLAN_FILTER
)
||
!
(
slave_dev
->
vlan_rx_add_vid
))
{
goto
out
;
}
list_for_each_entry
(
vlan
,
&
bond
->
vlan_list
,
vlan_list
)
{
slave_dev
->
vlan_rx_add_vid
(
slave_dev
,
vlan
->
vlan_id
);
}
out:
write_unlock_bh
(
&
bond
->
lock
);
}
static
void
bond_del_vlans_from_slave
(
struct
bonding
*
bond
,
struct
net_device
*
slave_dev
)
{
struct
vlan_entry
*
vlan
;
struct
net_device
*
vlan_dev
;
write_lock_bh
(
&
bond
->
lock
);
if
(
list_empty
(
&
bond
->
vlan_list
))
{
goto
out
;
}
if
(
!
(
slave_dev
->
features
&
NETIF_F_HW_VLAN_FILTER
)
||
!
(
slave_dev
->
vlan_rx_kill_vid
))
{
goto
unreg
;
}
list_for_each_entry
(
vlan
,
&
bond
->
vlan_list
,
vlan_list
)
{
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev
=
bond
->
vlgrp
->
vlan_devices
[
vlan
->
vlan_id
];
slave_dev
->
vlan_rx_kill_vid
(
slave_dev
,
vlan
->
vlan_id
);
bond
->
vlgrp
->
vlan_devices
[
vlan
->
vlan_id
]
=
vlan_dev
;
}
unreg:
if
((
slave_dev
->
features
&
NETIF_F_HW_VLAN_RX
)
&&
slave_dev
->
vlan_rx_register
)
{
slave_dev
->
vlan_rx_register
(
slave_dev
,
NULL
);
}
out:
write_unlock_bh
(
&
bond
->
lock
);
}
/*------------------------------- Link status -------------------------------*/
/*
...
...
@@ -1214,6 +1588,7 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
struct
dev_mc_list
*
dmi
;
struct
sockaddr
addr
;
int
link_reporting
;
int
old_features
=
bond_dev
->
features
;
int
res
=
0
;
if
(
slave_dev
->
do_ioctl
==
NULL
)
{
...
...
@@ -1234,6 +1609,36 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
return
-
EBUSY
;
}
/* vlan challenged mutual exclusion */
/* no need to lock since we're protected by rtnl_lock */
if
(
slave_dev
->
features
&
NETIF_F_VLAN_CHALLENGED
)
{
dprintk
(
"%s: NETIF_F_VLAN_CHALLENGED
\n
"
,
slave_dev
->
name
);
if
(
!
list_empty
(
&
bond
->
vlan_list
))
{
printk
(
KERN_ERR
DRV_NAME
": Error: cannot enslave VLAN "
"challenged slave %s on VLAN enabled "
"bond %s
\n
"
,
slave_dev
->
name
,
bond_dev
->
name
);
return
-
EPERM
;
}
else
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: enslaved VLAN challenged "
"slave %s. Adding VLANs will be blocked as "
"long as %s is part of bond %s
\n
"
,
slave_dev
->
name
,
slave_dev
->
name
,
bond_dev
->
name
);
bond_dev
->
features
|=
NETIF_F_VLAN_CHALLENGED
;
}
}
else
{
dprintk
(
"%s: ! NETIF_F_VLAN_CHALLENGED
\n
"
,
slave_dev
->
name
);
if
(
bond
->
slave_cnt
==
0
)
{
/* First slave, and it is not VLAN challenged,
* so remove the block of adding VLANs over the bond.
*/
bond_dev
->
features
&=
~
NETIF_F_VLAN_CHALLENGED
;
}
}
if
(
app_abi_ver
>=
1
)
{
/* The application is using an ABI, which requires the
* slave interface to be closed.
...
...
@@ -1242,7 +1647,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
printk
(
KERN_ERR
DRV_NAME
": Error: %s is up
\n
"
,
slave_dev
->
name
);
return
-
EPERM
;
res
=
-
EPERM
;
goto
err_undo_flags
;
}
if
(
slave_dev
->
set_mac_address
==
NULL
)
{
...
...
@@ -1253,7 +1659,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
"Your kernel likely does not support slave "
"devices.
\n
"
);
return
-
EOPNOTSUPP
;
res
=
-
EOPNOTSUPP
;
goto
err_undo_flags
;
}
}
else
{
/* The application is not using an ABI, which requires the
...
...
@@ -1263,7 +1670,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
printk
(
KERN_ERR
DRV_NAME
": Error: %s is not running
\n
"
,
slave_dev
->
name
);
return
-
EINVAL
;
res
=
-
EINVAL
;
goto
err_undo_flags
;
}
if
((
bond
->
params
.
mode
==
BOND_MODE_8023AD
)
||
...
...
@@ -1273,13 +1681,15 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
": Error: to use %s mode, you must upgrade "
"ifenslave.
\n
"
,
bond_mode_name
(
bond
->
params
.
mode
));
return
-
EOPNOTSUPP
;
res
=
-
EOPNOTSUPP
;
goto
err_undo_flags
;
}
}
new_slave
=
kmalloc
(
sizeof
(
struct
slave
),
GFP_KERNEL
);
if
(
!
new_slave
)
{
return
-
ENOMEM
;
res
=
-
ENOMEM
;
goto
err_undo_flags
;
}
memset
(
new_slave
,
0
,
sizeof
(
struct
slave
));
...
...
@@ -1368,6 +1778,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
dev_mc_add
(
slave_dev
,
lacpdu_multicast
,
ETH_ALEN
,
0
);
}
bond_add_vlans_on_slave
(
bond
,
slave_dev
);
write_lock_bh
(
&
bond
->
lock
);
bond_attach_slave
(
bond
,
new_slave
);
...
...
@@ -1576,6 +1988,10 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
err_free:
kfree
(
new_slave
);
err_undo_flags:
bond_dev
->
features
=
old_features
;
return
res
;
}
...
...
@@ -1689,8 +2105,37 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
}
}
if
(
bond
->
slave_cnt
==
0
)
{
/* if the last slave was removed, zero the mac address
* of the master so it will be set by the application
* to the mac address of the first slave
*/
memset
(
bond_dev
->
dev_addr
,
0
,
bond_dev
->
addr_len
);
if
(
list_empty
(
&
bond
->
vlan_list
))
{
bond_dev
->
features
|=
NETIF_F_VLAN_CHALLENGED
;
}
else
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: clearing HW address of %s while it "
"still has VLANs.
\n
"
,
bond_dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": When re-adding slaves, make sure the bond's "
"HW address matches its VLANs'.
\n
"
);
}
}
else
if
((
bond_dev
->
features
&
NETIF_F_VLAN_CHALLENGED
)
&&
!
bond_has_challenged_slaves
(
bond
))
{
printk
(
KERN_INFO
DRV_NAME
": last VLAN challenged slave %s "
"left bond %s. VLAN blocking is removed
\n
"
,
slave_dev
->
name
,
bond_dev
->
name
);
bond_dev
->
features
&=
~
NETIF_F_VLAN_CHALLENGED
;
}
write_unlock_bh
(
&
bond
->
lock
);
bond_del_vlans_from_slave
(
bond
,
slave_dev
);
/* If the mode USES_PRIMARY, then we should only remove its
* promisc and mc settings if it was the curr_active_slave, but that was
* already taken care of above when we detached the slave
...
...
@@ -1732,14 +2177,6 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
kfree
(
slave
);
/* if the last slave was removed, zero the mac address
* of the master so it will be set by the application
* to the mac address of the first slave
*/
if
(
bond
->
slave_cnt
==
0
)
{
memset
(
bond_dev
->
dev_addr
,
0
,
bond_dev
->
addr_len
);
}
return
0
;
/* deletion OK */
}
...
...
@@ -1788,6 +2225,8 @@ static int bond_release_all(struct net_device *bond_dev)
*/
write_unlock_bh
(
&
bond
->
lock
);
bond_del_vlans_from_slave
(
bond
,
slave_dev
);
/* If the mode USES_PRIMARY, then we should only remove its
* promisc and mc settings if it was the curr_active_slave, but that was
* already taken care of above when we detached the slave
...
...
@@ -1838,6 +2277,18 @@ static int bond_release_all(struct net_device *bond_dev)
*/
memset
(
bond_dev
->
dev_addr
,
0
,
bond_dev
->
addr_len
);
if
(
list_empty
(
&
bond
->
vlan_list
))
{
bond_dev
->
features
|=
NETIF_F_VLAN_CHALLENGED
;
}
else
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: clearing HW address of %s while it "
"still has VLANs.
\n
"
,
bond_dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": When re-adding slaves, make sure the bond's "
"HW address matches its VLANs'.
\n
"
);
}
printk
(
KERN_INFO
DRV_NAME
": %s: released all slaves
\n
"
,
bond_dev
->
name
);
...
...
@@ -3569,11 +4020,12 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
struct
bonding
*
bond
=
bond_dev
->
priv
;
struct
slave
*
slave
,
*
start_at
;
int
i
;
int
res
=
1
;
read_lock
(
&
bond
->
lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
read_lock
(
&
bond
->
curr_slave_lock
);
...
...
@@ -3581,33 +4033,31 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
read_unlock
(
&
bond
->
curr_slave_lock
);
if
(
!
slave
)
{
goto
free_
out
;
goto
out
;
}
bond_for_each_slave_from
(
bond
,
slave
,
i
,
start_at
)
{
if
(
IS_UP
(
slave
->
dev
)
&&
(
slave
->
link
==
BOND_LINK_UP
)
&&
(
slave
->
state
==
BOND_STATE_ACTIVE
))
{
skb
->
dev
=
slave
->
dev
;
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
slave
->
dev
);
write_lock
(
&
bond
->
curr_slave_lock
);
bond
->
curr_active_slave
=
slave
->
next
;
write_unlock
(
&
bond
->
curr_slave_lock
);
goto
out
;
break
;
}
}
out:
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
goto
out
;
}
read_unlock
(
&
bond
->
lock
);
return
0
;
}
/*
...
...
@@ -3617,6 +4067,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
static
int
bond_xmit_activebackup
(
struct
sk_buff
*
skb
,
struct
net_device
*
bond_dev
)
{
struct
bonding
*
bond
=
bond_dev
->
priv
;
int
res
=
1
;
/* if we are sending arp packets, try to at least
identify our own ip address */
...
...
@@ -3633,26 +4084,21 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
read_lock
(
&
bond
->
curr_slave_lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
if
(
bond
->
curr_active_slave
)
{
/* one usable interface */
skb
->
dev
=
bond
->
curr_active_slave
->
dev
;
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
goto
out
;
}
else
{
goto
free_out
;
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
bond
->
curr_active_slave
->
dev
);
}
out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
}
read_unlock
(
&
bond
->
curr_slave_lock
);
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
goto
out
;
}
/*
...
...
@@ -3667,11 +4113,12 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
struct
slave
*
slave
,
*
start_at
;
int
slave_no
;
int
i
;
int
res
=
1
;
read_lock
(
&
bond
->
lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
slave_no
=
(
data
->
h_dest
[
5
]
^
bond_dev
->
dev_addr
[
5
])
%
bond
->
slave_cnt
;
...
...
@@ -3689,22 +4136,18 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
if
(
IS_UP
(
slave
->
dev
)
&&
(
slave
->
link
==
BOND_LINK_UP
)
&&
(
slave
->
state
==
BOND_STATE_ACTIVE
))
{
skb
->
dev
=
slave
->
dev
;
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
goto
out
;
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
slave
->
dev
);
break
;
}
}
out:
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
goto
out
;
}
read_unlock
(
&
bond
->
lock
);
return
0
;
}
/*
...
...
@@ -3716,11 +4159,12 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
struct
slave
*
slave
,
*
start_at
;
struct
net_device
*
tx_dev
=
NULL
;
int
i
;
int
res
=
1
;
read_lock
(
&
bond
->
lock
);
if
(
!
BOND_IS_OK
(
bond
))
{
goto
free_
out
;
goto
out
;
}
read_lock
(
&
bond
->
curr_slave_lock
);
...
...
@@ -3728,7 +4172,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
read_unlock
(
&
bond
->
curr_slave_lock
);
if
(
!
start_at
)
{
goto
free_
out
;
goto
out
;
}
bond_for_each_slave_from
(
bond
,
slave
,
i
,
start_at
)
{
...
...
@@ -3744,31 +4188,28 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
continue
;
}
skb2
->
dev
=
tx_dev
;
skb2
->
priority
=
1
;
dev_queue_xmit
(
skb2
);
res
=
bond_dev_queue_xmit
(
bond
,
skb2
,
tx_dev
);
if
(
res
)
{
dev_kfree_skb
(
skb2
);
continue
;
}
}
tx_dev
=
slave
->
dev
;
}
}
if
(
tx_dev
)
{
skb
->
dev
=
tx_dev
;
skb
->
priority
=
1
;
dev_queue_xmit
(
skb
);
}
else
{
goto
free_out
;
res
=
bond_dev_queue_xmit
(
bond
,
skb
,
tx_dev
);
}
out:
if
(
res
)
{
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
}
/* frame sent to all suitable interfaces */
read_unlock
(
&
bond
->
lock
);
return
0
;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb
(
skb
);
goto
out
;
}
#ifdef CONFIG_NET_FASTROUTE
...
...
@@ -3837,6 +4278,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
bond
->
current_arp_slave
=
NULL
;
bond
->
primary_slave
=
NULL
;
bond
->
dev
=
bond_dev
;
INIT_LIST_HEAD
(
&
bond
->
vlan_list
);
/* Initialize the device entry points */
bond_dev
->
open
=
bond_open
;
...
...
@@ -3858,6 +4300,25 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
bond_dev
->
tx_queue_len
=
0
;
bond_dev
->
flags
|=
IFF_MASTER
|
IFF_MULTICAST
;
/* At first, we block adding VLANs. That's the only way to
* prevent problems that occur when adding VLANs over an
* empty bond. The block will be removed once non-challenged
* slaves are enslaved.
*/
bond_dev
->
features
|=
NETIF_F_VLAN_CHALLENGED
;
/* By default, we declare the bond to be fully
* VLAN hardware accelerated capable. Special
* care is taken in the various xmit functions
* when there are slaves that are not hw accel
* capable
*/
bond_dev
->
vlan_rx_register
=
bond_vlan_rx_register
;
bond_dev
->
vlan_rx_add_vid
=
bond_vlan_rx_add_vid
;
bond_dev
->
vlan_rx_kill_vid
=
bond_vlan_rx_kill_vid
;
bond_dev
->
features
|=
(
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
|
NETIF_F_HW_VLAN_FILTER
);
#ifdef CONFIG_PROC_FS
bond_create_proc_entry
(
bond
);
...
...
drivers/net/bonding/bonding.h
View file @
f5106b15
...
...
@@ -36,8 +36,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "2.
5.4
"
#define DRV_RELDATE "
December 30, 2003
"
#define DRV_VERSION "2.
6.0
"
#define DRV_RELDATE "
January 14, 2004
"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
...
...
@@ -147,6 +147,11 @@ struct bond_params {
u32
arp_targets
[
BOND_MAX_ARP_TARGETS
];
};
struct
vlan_entry
{
struct
list_head
vlan_list
;
unsigned
short
vlan_id
;
};
struct
slave
{
struct
net_device
*
dev
;
/* first - usefull for panic debug */
struct
slave
*
next
;
...
...
@@ -196,6 +201,8 @@ struct bonding {
struct
ad_bond_info
ad_info
;
struct
alb_bond_info
alb_info
;
struct
bond_params
params
;
struct
list_head
vlan_list
;
struct
vlan_group
*
vlgrp
;
};
/**
...
...
@@ -238,5 +245,8 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
slave
->
dev
->
flags
&=
~
IFF_NOARP
;
}
struct
vlan_entry
*
bond_next_vlan
(
struct
bonding
*
bond
,
struct
vlan_entry
*
curr
);
int
bond_dev_queue_xmit
(
struct
bonding
*
bond
,
struct
sk_buff
*
skb
,
struct
net_device
*
slave_dev
);
#endif
/* _LINUX_BONDING_H */
drivers/net/depca.c
View file @
f5106b15
...
...
@@ -1461,7 +1461,7 @@ static int __init depca_mca_probe(struct device *device)
out_unclaim:
mca_device_set_claim
(
mdev
,
0
);
return
err
;
;
return
err
;
}
#endif
...
...
drivers/net/hamradio/6pack.c
View file @
f5106b15
...
...
@@ -178,6 +178,7 @@ static inline struct sixpack *sp_alloc(void)
(
sixpack_ctrls
[
i
]
=
(
sixpack_ctrl_t
*
)
kmalloc
(
sizeof
(
sixpack_ctrl_t
),
GFP_KERNEL
))
!=
NULL
)
{
spp
=
sixpack_ctrls
[
i
];
}
memset
(
spp
,
0
,
sizeof
(
sixpack_ctrl_t
));
/* Initialize channel control data */
...
...
@@ -188,7 +189,6 @@ static inline struct sixpack *sp_alloc(void)
spp
->
dev
.
priv
=
(
void
*
)
&
spp
->
ctrl
;
spp
->
dev
.
next
=
NULL
;
spp
->
dev
.
init
=
sixpack_init
;
}
if
(
spp
!=
NULL
)
{
/* register device so that it can be ifconfig'ed */
...
...
drivers/net/hp100.c
View file @
f5106b15
...
...
@@ -3043,14 +3043,27 @@ static int __init hp100_module_init(void)
int
err
;
err
=
hp100_isa_init
();
if
(
err
&&
err
!=
-
ENODEV
)
goto
out
;
#ifdef CONFIG_EISA
err
|=
eisa_driver_register
(
&
hp100_eisa_driver
);
err
=
eisa_driver_register
(
&
hp100_eisa_driver
);
if
(
err
&&
err
!=
-
ENODEV
)
goto
out2
;
#endif
#ifdef CONFIG_PCI
err
|=
pci_module_init
(
&
hp100_pci_driver
);
err
=
pci_module_init
(
&
hp100_pci_driver
);
if
(
err
&&
err
!=
-
ENODEV
)
goto
out3
;
#endif
out:
return
err
;
out3:
#ifdef CONFIG_EISA
eisa_driver_unregister
(
&
hp100_eisa_driver
);
out2:
#endif
hp100_isa_cleanup
();
goto
out
;
}
...
...
drivers/net/pcnet32.c
View file @
f5106b15
...
...
@@ -720,6 +720,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
lp
->
name
=
chipname
;
lp
->
shared_irq
=
shared
;
lp
->
mii_if
.
full_duplex
=
fdx
;
lp
->
mii_if
.
phy_id_mask
=
0x1f
;
lp
->
mii_if
.
reg_num_mask
=
0x1f
;
lp
->
dxsuflo
=
dxsuflo
;
lp
->
ltint
=
ltint
;
lp
->
mii
=
mii
;
...
...
@@ -1006,9 +1008,10 @@ pcnet32_init_ring(struct net_device *dev)
}
if
(
lp
->
rx_dma_addr
[
i
]
==
0
)
lp
->
rx_dma_addr
[
i
]
=
pci_map_single
(
lp
->
pci_dev
,
rx_skbuff
->
tail
,
rx_skbuff
->
len
,
PCI_DMA_FROMDEVICE
);
lp
->
rx_dma_addr
[
i
]
=
pci_map_single
(
lp
->
pci_dev
,
rx_skbuff
->
tail
,
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
lp
->
rx_ring
[
i
].
base
=
(
u32
)
le32_to_cpu
(
lp
->
rx_dma_addr
[
i
]);
lp
->
rx_ring
[
i
].
buf_length
=
le16_to_cpu
(
-
PKT_BUF_SZ
);
lp
->
rx_ring
[
i
].
buf_length
=
le16_to_cpu
(
2
-
PKT_BUF_SZ
);
lp
->
rx_ring
[
i
].
status
=
le16_to_cpu
(
0x8000
);
}
/* The Tx buffer address is filled in as needed, but we do need to clear
...
...
@@ -1079,7 +1082,7 @@ pcnet32_tx_timeout (struct net_device *dev)
pcnet32_restart
(
dev
,
0x0042
);
dev
->
trans_start
=
jiffies
;
netif_
start
_queue
(
dev
);
netif_
wake
_queue
(
dev
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
}
...
...
@@ -1105,9 +1108,10 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt when that option is available to us.
*/
status
=
0x8300
;
entry
=
(
lp
->
cur_tx
-
lp
->
dirty_tx
)
&
TX_RING_MOD_MASK
;
if
((
lp
->
ltint
)
&&
((
lp
->
cur_tx
-
lp
->
dirty_tx
==
TX_RING_SIZE
/
2
)
||
(
lp
->
cur_tx
-
lp
->
dirty_tx
>=
TX_RING_SIZE
-
2
)))
((
entry
==
TX_RING_SIZE
/
2
)
||
(
entry
>=
TX_RING_SIZE
-
2
)))
{
/* Enable Successful-TxDone interrupt if we have
* 1/2 of, or nearly all of, our ring buffer Tx'd
...
...
@@ -1122,7 +1126,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Mask to ring buffer boundary. */
entry
=
lp
->
cur_tx
&
TX_RING_MOD_MASK
;
/* Caution: the write order is important here, set the
base addres
s
/* Caution: the write order is important here, set the
statu
s
with the "ownership" bits last. */
lp
->
tx_ring
[
entry
].
length
=
le16_to_cpu
(
-
skb
->
len
);
...
...
@@ -1144,7 +1148,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev
->
trans_start
=
jiffies
;
if
(
lp
->
tx_ring
[(
entry
+
1
)
&
TX_RING_MOD_MASK
].
base
==
0
)
netif_
start
_queue
(
dev
);
netif_
wake
_queue
(
dev
);
else
{
lp
->
tx_full
=
1
;
netif_stop_queue
(
dev
);
...
...
@@ -1191,8 +1195,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if
(
csr0
&
0x0200
)
{
/* Tx-done interrupt */
unsigned
int
dirty_tx
=
lp
->
dirty_tx
;
int
delta
;
while
(
dirty_tx
<
lp
->
cur_tx
)
{
while
(
dirty_tx
!=
lp
->
cur_tx
)
{
int
entry
=
dirty_tx
&
TX_RING_MOD_MASK
;
int
status
=
(
short
)
le16_to_cpu
(
lp
->
tx_ring
[
entry
].
status
);
...
...
@@ -1246,15 +1251,17 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
dirty_tx
++
;
}
if
(
lp
->
cur_tx
-
dirty_tx
>=
TX_RING_SIZE
)
{
delta
=
(
lp
->
cur_tx
-
dirty_tx
)
&
(
TX_RING_MOD_MASK
+
TX_RING_SIZE
);
if
(
delta
>=
TX_RING_SIZE
)
{
printk
(
KERN_ERR
"%s: out-of-sync dirty pointer, %d vs. %d, full=%d.
\n
"
,
dev
->
name
,
dirty_tx
,
lp
->
cur_tx
,
lp
->
tx_full
);
dirty_tx
+=
TX_RING_SIZE
;
delta
-=
TX_RING_SIZE
;
}
if
(
lp
->
tx_full
&&
netif_queue_stopped
(
dev
)
&&
d
irty_tx
>
lp
->
cur_tx
-
TX_RING_SIZE
+
2
)
{
d
elta
<
TX_RING_SIZE
-
2
)
{
/* The ring is no longer full, clear tbusy. */
lp
->
tx_full
=
0
;
netif_wake_queue
(
dev
);
...
...
@@ -1344,13 +1351,14 @@ pcnet32_rx(struct net_device *dev)
if
((
newskb
=
dev_alloc_skb
(
PKT_BUF_SZ
)))
{
skb_reserve
(
newskb
,
2
);
skb
=
lp
->
rx_skbuff
[
entry
];
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
entry
],
skb
->
len
,
PCI_DMA_FROMDEVICE
);
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
entry
],
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
skb_put
(
skb
,
pkt_len
);
lp
->
rx_skbuff
[
entry
]
=
newskb
;
newskb
->
dev
=
dev
;
lp
->
rx_dma_addr
[
entry
]
=
pci_map_single
(
lp
->
pci_dev
,
newskb
->
tail
,
newskb
->
len
,
PCI_DMA_FROMDEVICE
);
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
lp
->
rx_ring
[
entry
].
base
=
le32_to_cpu
(
lp
->
rx_dma_addr
[
entry
]);
rx_in_place
=
1
;
}
else
...
...
@@ -1379,7 +1387,7 @@ pcnet32_rx(struct net_device *dev)
skb_put
(
skb
,
pkt_len
);
/* Make room */
pci_dma_sync_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
entry
],
PKT_BUF_SZ
,
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
eth_copy_and_sum
(
skb
,
(
unsigned
char
*
)(
lp
->
rx_skbuff
[
entry
]
->
tail
),
...
...
@@ -1396,7 +1404,7 @@ pcnet32_rx(struct net_device *dev)
* The docs say that the buffer length isn't touched, but Andrew Boyd
* of QNX reports that some revs of the 79C965 clear it.
*/
lp
->
rx_ring
[
entry
].
buf_length
=
le16_to_cpu
(
-
PKT_BUF_SZ
);
lp
->
rx_ring
[
entry
].
buf_length
=
le16_to_cpu
(
2
-
PKT_BUF_SZ
);
lp
->
rx_ring
[
entry
].
status
|=
le16_to_cpu
(
0x8000
);
entry
=
(
++
lp
->
cur_rx
)
&
RX_RING_MOD_MASK
;
}
...
...
@@ -1436,7 +1444,8 @@ pcnet32_close(struct net_device *dev)
for
(
i
=
0
;
i
<
RX_RING_SIZE
;
i
++
)
{
lp
->
rx_ring
[
i
].
status
=
0
;
if
(
lp
->
rx_skbuff
[
i
])
{
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
i
],
lp
->
rx_skbuff
[
i
]
->
len
,
PCI_DMA_FROMDEVICE
);
pci_unmap_single
(
lp
->
pci_dev
,
lp
->
rx_dma_addr
[
i
],
PKT_BUF_SZ
-
2
,
PCI_DMA_FROMDEVICE
);
dev_kfree_skb
(
lp
->
rx_skbuff
[
i
]);
}
lp
->
rx_skbuff
[
i
]
=
NULL
;
...
...
@@ -1625,12 +1634,18 @@ static int pcnet32_ethtool_ioctl (struct net_device *dev, void *useraddr)
}
/* restart autonegotiation */
case
ETHTOOL_NWAY_RST
:
{
return
mii_nway_restart
(
&
lp
->
mii_if
);
int
r
;
spin_lock_irq
(
&
lp
->
lock
);
r
=
mii_nway_restart
(
&
lp
->
mii_if
);
spin_unlock_irq
(
&
lp
->
lock
);
return
r
;
}
/* get link status */
case
ETHTOOL_GLINK
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GLINK
};
spin_lock_irq
(
&
lp
->
lock
);
edata
.
data
=
mii_link_ok
(
&
lp
->
mii_if
);
spin_unlock_irq
(
&
lp
->
lock
);
if
(
copy_to_user
(
useraddr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
...
...
@@ -1661,45 +1676,37 @@ static int pcnet32_ethtool_ioctl (struct net_device *dev, void *useraddr)
static
int
pcnet32_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
{
unsigned
long
ioaddr
=
dev
->
base_addr
;
struct
pcnet32_private
*
lp
=
dev
->
priv
;
struct
mii_ioctl_data
*
data
=
(
struct
mii_ioctl_data
*
)
&
rq
->
ifr_data
;
int
phyaddr
=
lp
->
a
.
read_bcr
(
ioaddr
,
33
);
int
rc
;
unsigned
long
flags
;
if
(
cmd
==
SIOCETHTOOL
)
return
pcnet32_ethtool_ioctl
(
dev
,
(
void
*
)
rq
->
ifr_data
);
/* SIOC[GS]MIIxxx ioctls */
if
(
lp
->
mii
)
{
switch
(
cmd
)
{
case
SIOCGMIIPHY
:
/* Get address of MII PHY in use. */
data
->
phy_id
=
(
phyaddr
>>
5
)
&
0x1f
;
/* Fall Through */
case
SIOCGMIIREG
:
/* Read MII PHY register. */
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
((
data
->
phy_id
&
0x1f
)
<<
5
)
|
(
data
->
reg_num
&
0x1f
));
data
->
val_out
=
lp
->
a
.
read_bcr
(
ioaddr
,
34
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
phyaddr
);
return
0
;
case
SIOCSMIIREG
:
/* Write MII PHY register. */
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
((
data
->
phy_id
&
0x1f
)
<<
5
)
|
(
data
->
reg_num
&
0x1f
));
lp
->
a
.
write_bcr
(
ioaddr
,
34
,
data
->
val_in
);
lp
->
a
.
write_bcr
(
ioaddr
,
33
,
phyaddr
);
return
0
;
default:
return
-
EOPNOTSUPP
;
}
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
rc
=
generic_mii_ioctl
(
&
lp
->
mii_if
,
data
,
cmd
,
NULL
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
}
else
{
rc
=
-
EOPNOTSUPP
;
}
return
-
EOPNOTSUPP
;
return
rc
;
}
static
void
pcnet32_watchdog
(
struct
net_device
*
dev
)
{
struct
pcnet32_private
*
lp
=
dev
->
priv
;
unsigned
long
flags
;
/* Print the link status if it has changed */
if
(
lp
->
mii
)
if
(
lp
->
mii
)
{
spin_lock_irqsave
(
&
lp
->
lock
,
flags
);
mii_check_media
(
&
lp
->
mii_if
,
1
,
0
);
spin_unlock_irqrestore
(
&
lp
->
lock
,
flags
);
}
mod_timer
(
&
(
lp
->
watchdog_timer
),
PCNET32_WATCHDOG_TIMEOUT
);
}
...
...
drivers/net/sis190.c
View file @
f5106b15
...
...
@@ -954,8 +954,7 @@ static void
SiS190_tx_interrupt
(
struct
net_device
*
dev
,
struct
sis190_private
*
tp
,
void
*
ioaddr
)
{
unsigned
long
dirty_tx
,
tx_left
=
0
;
int
entry
=
tp
->
cur_tx
%
NUM_TX_DESC
;
unsigned
long
dirty_tx
,
tx_left
;
assert
(
dev
!=
NULL
);
assert
(
tp
!=
NULL
);
...
...
@@ -965,6 +964,8 @@ SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp,
tx_left
=
tp
->
cur_tx
-
dirty_tx
;
while
(
tx_left
>
0
)
{
int
entry
=
dirty_tx
%
NUM_TX_DESC
;
if
((
le32_to_cpu
(
tp
->
TxDescArray
[
entry
].
status
)
&
OWNbit
)
==
0
)
{
struct
sk_buff
*
skb
;
...
...
@@ -980,7 +981,6 @@ SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp,
tp
->
stats
.
tx_packets
++
;
dirty_tx
++
;
tx_left
--
;
entry
++
;
}
}
...
...
drivers/net/sis900.c
View file @
f5106b15
...
...
@@ -2093,7 +2093,7 @@ static void set_rx_mode(struct net_device *net_dev)
i
++
,
mclist
=
mclist
->
next
)
{
unsigned
int
bit_nr
=
sis900_mcast_bitnr
(
mclist
->
dmi_addr
,
revision
);
mc_filter
[
bit_nr
>>
4
]
|=
(
1
<<
bit_nr
);
mc_filter
[
bit_nr
>>
4
]
|=
(
1
<<
(
bit_nr
&
0xf
)
);
}
}
...
...
drivers/net/sk98lin/h/lm80.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: lm80.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.6 $
* Date: $Date: 2003/05/13 17:26:52 $
* Purpose: Contains all defines for the LM80 Chip
* (National Semiconductor).
*
...
...
drivers/net/sk98lin/h/skaddr.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skaddr.h
* Project: Gigabit Ethernet Adapters, ADDR-Modul
* Version: $Revision: 1.29 $
* Date: $Date: 2003/05/13 16:57:24 $
* Purpose: Header file for Address Management (MC, UC, Prom).
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skcsum.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skcsum.h
* Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
* Version: $Revision: 1.10 $
* Date: $Date: 2003/08/20 13:59:57 $
* Purpose: Store/verify Internet checksum in send/receive packets.
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skdebug.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skdebug.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.14 $
* Date: $Date: 2003/05/13 17:26:00 $
* Purpose: SK specific DEBUG support
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skdrv1st.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skdrv1st.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.4 $
* Date: $Date: 2003/11/12 14:28:14 $
* Purpose: First header file for driver and all other modules
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skdrv2nd.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skdrv2nd.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.10 $
* Date: $Date: 2003/12/11 16:04:45 $
* Purpose: Second header file for driver and all other modules
*
******************************************************************************/
...
...
@@ -76,7 +78,13 @@
/* Marvell (0x11ab) */
\
} else if (pdev->vendor == 0x11ab) { \
/* Gigabit Ethernet Adapter (0x4320) */
\
if ((pdev->device == 0x4320)) { \
/* Gigabit Ethernet Adapter (0x4360) */
\
/* Gigabit Ethernet Adapter (0x4361) */
\
/* Belkin (0x5005) */
\
if ((pdev->device == 0x4320) || \
(pdev->device == 0x4360) || \
(pdev->device == 0x4361) || \
(pdev->device == 0x5005)) { \
result = SK_TRUE; \
} \
/* CNet (0x1371) */
\
...
...
drivers/net/sk98lin/h/skerror.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skerror.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.7 $
* Date: $Date: 2003/05/13 17:25:13 $
* Purpose: SK specific Error log support
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgedrv.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgedrv.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.10 $
* Date: $Date: 2003/07/04 12:25:01 $
* Purpose: Interface with the driver
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgehw.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgehw.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.56 $
* Date: $Date: 2003/09/23 09:01:00 $
* Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgehwt.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skhwt.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.7 $
* Date: $Date: 2003/09/16 12:55:08 $
* Purpose: Defines for the hardware timer functions
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgei2c.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgei2c.h
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.25 $
* Date: $Date: 2003/10/20 09:06:05 $
* Purpose: Special defines for TWSI
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgeinit.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgeinit.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.83 $
* Date: $Date: 2003/09/16 14:07:37 $
* Purpose: Structures and prototypes for the GE Init Module
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skgepnm2.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgepnm2.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.36 $
* Date: $Date: 2003/05/23 12:45:13 $
* Purpose: Defines for Private Network Management Interface
*
****************************************************************************/
...
...
drivers/net/sk98lin/h/skgepnmi.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgepnmi.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.62 $
* Date: $Date: 2003/08/15 12:31:52 $
* Purpose: Defines for Private Network Management Interface
*
****************************************************************************/
...
...
drivers/net/sk98lin/h/skgesirq.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgesirq.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.30 $
* Date: $Date: 2003/07/04 12:34:13 $
* Purpose: SK specific Gigabit Ethernet special IRQ functions
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/ski2c.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: ski2c.h
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.35 $
* Date: $Date: 2003/10/20 09:06:30 $
* Purpose: Defines to access Voltage and Temperature Sensor
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skqueue.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skqueue.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.16 $
* Date: $Date: 2003/09/16 12:50:32 $
* Purpose: Defines for the Event queue
*
******************************************************************************/
...
...
@@ -20,6 +22,10 @@
*
******************************************************************************/
/*
* SKQUEUE.H contains all defines and types for the event queue
*/
#ifndef _SKQUEUE_H_
#define _SKQUEUE_H_
...
...
drivers/net/sk98lin/h/skrlmt.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skrlmt.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.37 $
* Date: $Date: 2003/04/15 09:43:43 $
* Purpose: Header file for Redundant Link ManagemenT.
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/sktimer.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: sktimer.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.11 $
* Date: $Date: 2003/09/16 12:58:18 $
* Purpose: Defines for the timer functions
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/sktypes.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: sktypes.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.2 $
* Date: $Date: 2003/10/07 08:16:51 $
* Purpose: Define data types for Linux
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/skversion.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: version.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.5 $
* Date: $Date: 2003/10/07 08:16:51 $
* Purpose: SK specific Error log support
*
******************************************************************************/
...
...
@@ -23,14 +25,14 @@
#ifdef lint
static
const
char
SysKonnectFileId
[]
=
"@(#) (C) SysKonnect GmbH."
;
static
const
char
SysKonnectBuildNumber
[]
=
"@(#)SK-BUILD: 6.2
2
PL: 01"
;
"@(#)SK-BUILD: 6.2
3
PL: 01"
;
#endif
/* !defined(lint) */
#define BOOT_STRING "sk98lin: Network Device Driver v6.2
2
\n" \
#define BOOT_STRING "sk98lin: Network Device Driver v6.2
3
\n" \
"(C)Copyright 1999-2004 Marvell(R)."
#define VER_STRING "6.2
2
"
#define VER_STRING "6.2
3
"
#define DRIVER_FILE_NAME "sk98lin"
#define DRIVER_REL_DATE "
Jan-30
-2004"
#define DRIVER_REL_DATE "
Feb-13
-2004"
drivers/net/sk98lin/h/skvpd.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skvpd.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.15 $
* Date: $Date: 2003/01/13 10:39:38 $
* Purpose: Defines and Macros for VPD handling
*
******************************************************************************/
...
...
drivers/net/sk98lin/h/xmac_ii.h
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: xmac_ii.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.52 $
* Date: $Date: 2003/10/02 16:35:50 $
* Purpose: Defines and Macros for Gigabit Ethernet Controller
*
******************************************************************************/
...
...
drivers/net/sk98lin/skaddr.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skaddr.c
* Project: Gigabit Ethernet Adapters, ADDR-Module
* Version: $Revision: 1.52 $
* Date: $Date: 2003/06/02 13:46:15 $
* Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
*
******************************************************************************/
...
...
drivers/net/sk98lin/skcsum.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skcsum.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.12 $
* Date: $Date: 2003/08/20 13:55:53 $
* Purpose: Store/verify Internet checksum in send/receive packets.
*
******************************************************************************/
...
...
drivers/net/sk98lin/skdim.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skdim.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.5 $
* Date: $Date: 2003/11/28 12:55:40 $
* Purpose: All functions to maintain interrupt moderation
*
******************************************************************************/
...
...
drivers/net/sk98lin/skge.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skge.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.45 $
* Date: $Date: 2004/02/12 14:41:02 $
* Purpose: The main driver source module
*
******************************************************************************/
...
...
@@ -294,7 +296,6 @@ static int __init skge_probe (void)
SK_BOOL
BootStringCount
=
SK_FALSE
;
int
retval
;
#ifdef CONFIG_PROC_FS
int
proc_root_initialized
=
0
;
struct
proc_dir_entry
*
pProcFile
;
#endif
...
...
@@ -311,6 +312,12 @@ static int __init skge_probe (void)
dev
=
NULL
;
pNet
=
NULL
;
/* Don't handle Yukon2 cards at the moment */
/* 12-feb-2004 ---- mlindner@syskonnect.de */
if
(
pdev
->
vendor
==
0x11ab
)
{
if
(
(
pdev
->
device
==
0x4360
)
||
(
pdev
->
device
==
0x4361
)
)
continue
;
}
SK_PCI_ISCOMPLIANT
(
vendor_flag
,
pdev
);
if
(
!
vendor_flag
)
...
...
drivers/net/sk98lin/skgehwt.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgehwt.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.15 $
* Date: $Date: 2003/09/16 13:41:23 $
* Purpose: Hardware Timer
*
******************************************************************************/
...
...
drivers/net/sk98lin/skgeinit.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgeinit.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.97 $
* Date: $Date: 2003/10/02 16:45:31 $
* Purpose: Contains functions to initialize the adapter
*
******************************************************************************/
...
...
@@ -20,7 +22,6 @@
*
******************************************************************************/
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
...
...
drivers/net/sk98lin/skgemib.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgemib.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.11 $
* Date: $Date: 2003/09/15 13:38:12 $
* Purpose: Private Network Management Interface Management Database
*
****************************************************************************/
...
...
drivers/net/sk98lin/skgepnmi.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgepnmi.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.111 $
* Date: $Date: 2003/09/15 13:35:35 $
* Purpose: Private Network Management Interface
*
****************************************************************************/
...
...
@@ -20,6 +22,7 @@
*
******************************************************************************/
#ifndef _lint
static
const
char
SysKonnectFileId
[]
=
"@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell."
;
...
...
drivers/net/sk98lin/skgesirq.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skgesirq.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.92 $
* Date: $Date: 2003/09/16 14:37:07 $
* Purpose: Special IRQ module
*
******************************************************************************/
...
...
drivers/net/sk98lin/ski2c.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: ski2c.c
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.59 $
* Date: $Date: 2003/10/20 09:07:25 $
* Purpose: Functions to access Voltage and Temperature Sensor
*
******************************************************************************/
...
...
drivers/net/sk98lin/sklm80.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: sklm80.c
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.22 $
* Date: $Date: 2003/10/20 09:08:21 $
* Purpose: Functions to access Voltage and Temperature Sensor (LM80)
*
******************************************************************************/
...
...
drivers/net/sk98lin/skproc.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skproc.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.11 $
* Date: $Date: 2003/12/11 16:03:57 $
* Purpose: Funktions to display statictic data
*
******************************************************************************/
...
...
@@ -22,7 +24,6 @@
* The information in this file is provided "AS IS" without warranty.
*
******************************************************************************/
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
...
...
drivers/net/sk98lin/skqueue.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skqueue.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.20 $
* Date: $Date: 2003/09/16 13:44:00 $
* Purpose: Management of an event queue.
*
******************************************************************************/
...
...
@@ -20,6 +22,7 @@
*
******************************************************************************/
/*
* Event queue and dispatcher
*/
...
...
drivers/net/sk98lin/skrlmt.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skrlmt.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.69 $
* Date: $Date: 2003/04/15 09:39:22 $
* Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
*
******************************************************************************/
...
...
drivers/net/sk98lin/sktimer.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: sktimer.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.14 $
* Date: $Date: 2003/09/16 13:46:51 $
* Purpose: High level timer functions.
*
******************************************************************************/
...
...
@@ -20,6 +22,7 @@
*
******************************************************************************/
/*
* Event queue and dispatcher
*/
...
...
drivers/net/sk98lin/skvpd.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skvpd.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.37 $
* Date: $Date: 2003/01/13 10:42:45 $
* Purpose: Shared software to read and write VPD data
*
******************************************************************************/
...
...
drivers/net/sk98lin/skxmac2.c
View file @
f5106b15
...
...
@@ -2,6 +2,8 @@
*
* Name: skxmac2.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.102 $
* Date: $Date: 2003/10/02 16:53:58 $
* Purpose: Contains functions to initialize the MACs and PHYs
*
******************************************************************************/
...
...
drivers/net/tokenring/3c359.c
View file @
f5106b15
...
...
@@ -641,7 +641,20 @@ static int xl_open(struct net_device *dev)
*/
/* These MUST be on 8 byte boundaries */
xl_priv
->
xl_tx_ring
=
kmalloc
((
sizeof
(
struct
xl_tx_desc
)
*
XL_TX_RING_SIZE
)
+
7
,
GFP_DMA
|
GFP_KERNEL
)
;
if
(
xl_priv
->
xl_tx_ring
==
NULL
)
{
printk
(
KERN_WARNING
"%s: Not enough memory to allocate rx buffers.
\n
"
,
dev
->
name
);
free_irq
(
dev
->
irq
,
dev
);
return
-
ENOMEM
;
}
xl_priv
->
xl_rx_ring
=
kmalloc
((
sizeof
(
struct
xl_rx_desc
)
*
XL_RX_RING_SIZE
)
+
7
,
GFP_DMA
|
GFP_KERNEL
)
;
if
(
xl_priv
->
xl_tx_ring
==
NULL
)
{
printk
(
KERN_WARNING
"%s: Not enough memory to allocate rx buffers.
\n
"
,
dev
->
name
);
free_irq
(
dev
->
irq
,
dev
);
kfree
(
xl_priv
->
xl_tx_ring
);
return
-
ENOMEM
;
}
memset
(
xl_priv
->
xl_tx_ring
,
0
,
sizeof
(
struct
xl_tx_desc
)
*
XL_TX_RING_SIZE
)
;
memset
(
xl_priv
->
xl_rx_ring
,
0
,
sizeof
(
struct
xl_rx_desc
)
*
XL_RX_RING_SIZE
)
;
...
...
drivers/net/tulip/interrupt.c
View file @
f5106b15
...
...
@@ -211,10 +211,10 @@ int tulip_poll(struct net_device *dev, int *budget)
if
(
tp
->
rx_buffers
[
entry
].
mapping
!=
le32_to_cpu
(
tp
->
rx_ring
[
entry
].
buffer1
))
{
printk
(
KERN_ERR
"%s: Internal fault: The skbuff addresses "
"do not match in tulip_rx: %08x vs. %
08
x %p / %p.
\n
"
,
"do not match in tulip_rx: %08x vs. %
ll
x %p / %p.
\n
"
,
dev
->
name
,
le32_to_cpu
(
tp
->
rx_ring
[
entry
].
buffer1
),
tp
->
rx_buffers
[
entry
].
mapping
,
(
unsigned
long
long
)
tp
->
rx_buffers
[
entry
].
mapping
,
skb
->
head
,
temp
);
}
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment