Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
matisse
android_kernel_samsung_matisse
Commits
d779188d
Commit
d779188d
authored
19 years ago
by
Linus Torvalds
Browse files
Options
Download
Plain Diff
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
parents
f61ea1b0
ac67c624
Changes
67
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2114 additions
and
966 deletions
+2114
-966
Documentation/networking/gianfar.txt
Documentation/networking/gianfar.txt
+72
-0
drivers/net/8139too.c
drivers/net/8139too.c
+32
-54
drivers/net/Kconfig
drivers/net/Kconfig
+15
-2
drivers/net/Makefile
drivers/net/Makefile
+6
-1
drivers/net/bonding/Makefile
drivers/net/bonding/Makefile
+1
-1
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.c
+47
-59
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_3ad.h
+0
-13
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_alb.c
+32
-43
drivers/net/bonding/bond_alb.h
drivers/net/bonding/bond_alb.h
+0
-9
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_main.c
+197
-584
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bond_sysfs.c
+1358
-0
drivers/net/bonding/bonding.h
drivers/net/bonding/bonding.h
+29
-23
drivers/net/chelsio/sge.c
drivers/net/chelsio/sge.c
+10
-9
drivers/net/chelsio/sge.h
drivers/net/chelsio/sge.h
+0
-2
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000.h
+3
-1
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_ethtool.c
+85
-26
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.c
+48
-19
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_hw.h
+3
-1
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_main.c
+24
-40
drivers/net/gianfar.c
drivers/net/gianfar.c
+152
-79
No files found.
Documentation/networking/gianfar.txt
0 → 100644
View file @
d779188d
The Gianfar Ethernet Driver
Sysfs File description
Author: Andy Fleming <afleming@freescale.com>
Updated: 2005-07-28
SYSFS
Several of the features of the gianfar driver are controlled
through sysfs files. These are:
bd_stash:
To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
bd_stash, echo 'off' or '0' to disable
rx_stash_len:
To stash the first n bytes of the packet in L2, echo the number
of bytes to buf_stash_len. echo 0 to disable.
WARNING: You could really screw these up if you set them too low or high!
fifo_threshold:
To change the number of bytes the controller needs in the
fifo before it starts transmission, echo the number of bytes to
fifo_thresh. Range should be 0-511.
fifo_starve:
When the FIFO has less than this many bytes during a transmit, it
enters starve mode, and increases the priority of TX memory
transactions. To change, echo the number of bytes to
fifo_starve. Range should be 0-511.
fifo_starve_off:
Once in starve mode, the FIFO remains there until it has this
many bytes. To change, echo the number of bytes to
fifo_starve_off. Range should be 0-511.
CHECKSUM OFFLOADING
The eTSEC controller (first included in parts from late 2005 like
the 8548) has the ability to perform TCP, UDP, and IP checksums
in hardware. The Linux kernel only offloads the TCP and UDP
checksums (and always performs the pseudo header checksums), so
the driver only supports checksumming for TCP/IP and UDP/IP
packets. Use ethtool to enable or disable this feature for RX
and TX.
VLAN
In order to use VLAN, please consult Linux documentation on
configuring VLANs. The gianfar driver supports hardware insertion and
extraction of VLAN headers, but not filtering. Filtering will be
done by the kernel.
MULTICASTING
The gianfar driver supports using the group hash table on the
TSEC (and the extended hash table on the eTSEC) for multicast
filtering. On the eTSEC, the exact-match MAC registers are used
before the hash tables. See Linux documentation on how to join
multicast groups.
PADDING
The gianfar driver supports padding received frames with 2 bytes
to align the IP header to a 16-byte boundary, when supported by
hardware.
ETHTOOL
The gianfar driver supports the use of ethtool for many
configuration options. You must run ethtool only on currently
open interfaces. See ethtool documentation for details.
This diff is collapsed.
Click to expand it.
drivers/net/8139too.c
View file @
d779188d
...
...
@@ -586,16 +586,16 @@ struct rtl8139_private {
dma_addr_t
tx_bufs_dma
;
signed
char
phys
[
4
];
/* MII device addresses. */
char
twistie
,
twist_row
,
twist_col
;
/* Twister tune state. */
unsigned
int
default_port
:
4
;
/* Last dev->if_port value. */
unsigned
int
default_port
:
4
;
/* Last dev->if_port value. */
unsigned
int
have_thread
:
1
;
spinlock_t
lock
;
spinlock_t
rx_lock
;
chip_t
chipset
;
pid_t
thr_pid
;
wait_queue_head_t
thr_wait
;
struct
completion
thr_exited
;
u32
rx_config
;
struct
rtl_extra_stats
xstats
;
int
time_to_die
;
struct
work_struct
thread
;
struct
mii_if_info
mii
;
unsigned
int
regs_len
;
unsigned
long
fifo_copy_timeout
;
...
...
@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev);
static
int
mdio_read
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
);
static
void
mdio_write
(
struct
net_device
*
dev
,
int
phy_id
,
int
location
,
int
val
);
static
void
rtl8139_start_thread
(
struct
net_device
*
dev
);
static
void
rtl8139_start_thread
(
struct
rtl8139_private
*
tp
);
static
void
rtl8139_tx_timeout
(
struct
net_device
*
dev
);
static
void
rtl8139_init_ring
(
struct
net_device
*
dev
);
static
int
rtl8139_start_xmit
(
struct
sk_buff
*
skb
,
...
...
@@ -637,6 +637,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static
void
rtl8139_set_rx_mode
(
struct
net_device
*
dev
);
static
void
__set_rx_mode
(
struct
net_device
*
dev
);
static
void
rtl8139_hw_start
(
struct
net_device
*
dev
);
static
void
rtl8139_thread
(
void
*
_data
);
static
struct
ethtool_ops
rtl8139_ethtool_ops
;
/* write MMIO register, with flush */
...
...
@@ -1007,8 +1008,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
(
debug
<
0
?
RTL8139_DEF_MSG_ENABLE
:
((
1
<<
debug
)
-
1
));
spin_lock_init
(
&
tp
->
lock
);
spin_lock_init
(
&
tp
->
rx_lock
);
init_waitqueue_head
(
&
tp
->
thr_wait
);
init_completion
(
&
tp
->
thr_exited
);
INIT_WORK
(
&
tp
->
thread
,
rtl8139_thread
,
dev
);
tp
->
mii
.
dev
=
dev
;
tp
->
mii
.
mdio_read
=
mdio_read
;
tp
->
mii
.
mdio_write
=
mdio_write
;
...
...
@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev)
dev
->
irq
,
RTL_R8
(
MediaStatus
),
tp
->
mii
.
full_duplex
?
"full"
:
"half"
);
rtl8139_start_thread
(
dev
);
rtl8139_start_thread
(
tp
);
return
0
;
}
...
...
@@ -1594,55 +1594,43 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
RTL_R8
(
Config1
));
}
static
int
rtl8139_thread
(
void
*
data
)
static
void
rtl8139_thread
(
void
*
_
data
)
{
struct
net_device
*
dev
=
data
;
struct
net_device
*
dev
=
_
data
;
struct
rtl8139_private
*
tp
=
netdev_priv
(
dev
);
unsigned
long
timeout
;
daemonize
(
"%s"
,
dev
->
name
);
allow_signal
(
SIGTERM
);
while
(
1
)
{
timeout
=
next_tick
;
do
{
timeout
=
interruptible_sleep_on_timeout
(
&
tp
->
thr_wait
,
timeout
);
/* make swsusp happy with our thread */
try_to_freeze
();
}
while
(
!
signal_pending
(
current
)
&&
(
timeout
>
0
));
if
(
signal_pending
(
current
))
{
flush_signals
(
current
);
}
unsigned
long
thr_delay
;
if
(
tp
->
time_to_die
)
break
;
if
(
rtnl_lock_interruptible
())
break
;
if
(
rtnl_shlock_nowait
()
==
0
)
{
rtl8139_thread_iter
(
dev
,
tp
,
tp
->
mmio_addr
);
rtnl_unlock
();
thr_delay
=
next_tick
;
}
else
{
/* unlikely race. mitigate with fast poll. */
thr_delay
=
HZ
/
2
;
}
complete_and_exit
(
&
tp
->
thr_exited
,
0
);
schedule_delayed_work
(
&
tp
->
thread
,
thr_delay
);
}
static
void
rtl8139_start_thread
(
struct
net_device
*
dev
)
static
void
rtl8139_start_thread
(
struct
rtl8139_private
*
tp
)
{
struct
rtl8139_private
*
tp
=
netdev_priv
(
dev
);
tp
->
thr_pid
=
-
1
;
tp
->
twistie
=
0
;
tp
->
time_to_die
=
0
;
if
(
tp
->
chipset
==
CH_8139_K
)
tp
->
twistie
=
1
;
else
if
(
tp
->
drv_flags
&
HAS_LNK_CHNG
)
return
;
tp
->
thr_pid
=
kernel_thread
(
rtl8139_thread
,
dev
,
CLONE_FS
|
CLONE_FILES
);
if
(
tp
->
thr_pid
<
0
)
{
printk
(
KERN_WARNING
"%s: unable to start kernel thread
\n
"
,
dev
->
name
);
tp
->
have_thread
=
1
;
schedule_delayed_work
(
&
tp
->
thread
,
next_tick
);
}
static
void
rtl8139_stop_thread
(
struct
rtl8139_private
*
tp
)
{
if
(
tp
->
have_thread
)
{
cancel_rearming_delayed_work
(
&
tp
->
thread
);
tp
->
have_thread
=
0
;
}
}
...
...
@@ -2224,22 +2212,12 @@ static int rtl8139_close (struct net_device *dev)
{
struct
rtl8139_private
*
tp
=
netdev_priv
(
dev
);
void
__iomem
*
ioaddr
=
tp
->
mmio_addr
;
int
ret
=
0
;
unsigned
long
flags
;
netif_stop_queue
(
dev
);
if
(
tp
->
thr_pid
>=
0
)
{
tp
->
time_to_die
=
1
;
wmb
();
ret
=
kill_proc
(
tp
->
thr_pid
,
SIGTERM
,
1
);
if
(
ret
)
{
printk
(
KERN_ERR
"%s: unable to signal thread
\n
"
,
dev
->
name
);
return
ret
;
}
wait_for_completion
(
&
tp
->
thr_exited
);
}
rtl8139_stop_thread
(
tp
);
if
(
netif_msg_ifdown
(
tp
))
printk
(
KERN_DEBUG
"%s: Shutting down ethercard, status was 0x%4.4x.
\n
"
,
dev
->
name
,
RTL_R16
(
IntrStatus
));
...
...
This diff is collapsed.
Click to expand it.
drivers/net/Kconfig
View file @
d779188d
...
...
@@ -1901,6 +1901,8 @@ config E1000_NAPI
If in doubt, say N.
source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS
tristate "MyriCOM Gigabit Ethernet support"
depends on SBUS
...
...
@@ -2008,7 +2010,18 @@ config SKGE
It does not support the link failover and network management
features that "portable" vendor supplied sk98lin driver does.
config SKY2
tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
select CRC32
---help---
This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
To compile this driver as a module, choose M here: the module
will be called sky2. This is recommended.
config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
depends on PCI
...
...
@@ -2120,7 +2133,7 @@ config BNX2
config SPIDER_NET
tristate "Spider Gigabit Ethernet driver"
depends on PCI && PPC_
BPA
depends on PCI && PPC_
CELL
help
This driver supports the Gigabit Ethernet chips present on the
Cell Processor-Based Blades from IBM.
...
...
This diff is collapsed.
Click to expand it.
drivers/net/Makefile
View file @
d779188d
...
...
@@ -13,7 +13,10 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING)
+=
bonding/
obj-$(CONFIG_GIANFAR)
+=
gianfar_driver.o
gianfar_driver-objs
:=
gianfar.o gianfar_ethtool.o gianfar_mii.o
gianfar_driver-objs
:=
gianfar.o
\
gianfar_ethtool.o
\
gianfar_mii.o
\
gianfar_sysfs.o
#
# link order important here
...
...
@@ -59,6 +62,7 @@ spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o
obj-$(CONFIG_SPIDER_NET)
+=
spidernet.o
obj-$(CONFIG_TC35815)
+=
tc35815.o
obj-$(CONFIG_SKGE)
+=
skge.o
obj-$(CONFIG_SKY2)
+=
sky2.o
obj-$(CONFIG_SK98LIN)
+=
sk98lin/
obj-$(CONFIG_SKFP)
+=
skfp/
obj-$(CONFIG_VIA_RHINE)
+=
via-rhine.o
...
...
@@ -202,6 +206,7 @@ obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO)
+=
hamradio/
obj-$(CONFIG_IRDA)
+=
irda/
obj-$(CONFIG_ETRAX_ETHERNET)
+=
cris/
obj-$(CONFIG_ENP2611_MSF_NET)
+=
ixp2000/
obj-$(CONFIG_NETCONSOLE)
+=
netconsole.o
...
...
This diff is collapsed.
Click to expand it.
drivers/net/bonding/Makefile
View file @
d779188d
...
...
@@ -4,5 +4,5 @@
obj-$(CONFIG_BONDING)
+=
bonding.o
bonding-objs
:=
bond_main.o bond_3ad.o bond_alb.o
bonding-objs
:=
bond_main.o bond_3ad.o bond_alb.o
bond_sysfs.o
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_3ad.c
View file @
d779188d
...
...
@@ -18,38 +18,6 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*
* Changes:
*
* 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Amir Noam <amir.noam at intel dot com>
* - Added support for lacp_rate module param.
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Based on discussion on mailing list, changed locking scheme
* to use lock/unlock or lock_bh/unlock_bh appropriately instead
* of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
* hidden bugs and solves system hangs that occurred due to the fact
* that holding lock_irqsave doesn't prevent softirqs from running.
* This also increases total throughput since interrupts are not
* blocked on each transmitted packets or monitor timeout.
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Renamed bond_3ad_link_status_changed() to
* bond_3ad_handle_link_change() for compatibility with TLB.
*
* 2003/05/20 - Amir Noam <amir.noam at intel dot com>
* - Fix long fail over time when releasing last slave of an active
* aggregator - send LACPDU on unbind of slave to tell partner this
* port is no longer aggregatable.
*
* 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
* - Send LACPDU as highest priority packet to further fix the above
* problem on very high Tx traffic load where packets may get dropped
* by the slave.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*/
//#define BONDING_DEBUG 1
...
...
@@ -1198,10 +1166,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// detect loopback situation
if
(
!
MAC_ADDRESS_COMPARE
(
&
(
lacpdu
->
actor_system
),
&
(
port
->
actor_system
)))
{
// INFO_RECEIVED_LOOPBACK_FRAMES
printk
(
KERN_ERR
DRV_NAME
": An illegal loopback occurred on
adapter (%s)
\n
"
,
port
->
slave
->
dev
->
name
);
printk
(
KERN_ERR
"Check the configuration to verify that all Adapters "
"are connected to 802.3ad compliant switch ports
\n
"
);
printk
(
KERN_ERR
DRV_NAME
":
%s:
An illegal loopback occurred on
"
"adapter (%s). Check the configuration to verify that all "
"Adapters are connected to 802.3ad compliant switch ports
\n
"
,
port
->
slave
->
dev
->
master
->
name
,
port
->
slave
->
dev
->
name
);
__release_rx_machine_lock
(
port
);
return
;
}
...
...
@@ -1378,8 +1346,9 @@ static void ad_port_selection_logic(struct port *port)
}
}
if
(
!
curr_port
)
{
// meaning: the port was related to an aggregator but was not on the aggregator port list
printk
(
KERN_WARNING
DRV_NAME
": Warning: Port %d (on %s) was "
printk
(
KERN_WARNING
DRV_NAME
":
%s:
Warning: Port %d (on %s) was "
"related to aggregator %d but was not on its port list
\n
"
,
port
->
slave
->
dev
->
master
->
name
,
port
->
actor_port_number
,
port
->
slave
->
dev
->
name
,
port
->
aggregator
->
aggregator_identifier
);
}
...
...
@@ -1450,7 +1419,8 @@ static void ad_port_selection_logic(struct port *port)
dprintk
(
"Port %d joined LAG %d(new LAG)
\n
"
,
port
->
actor_port_number
,
port
->
aggregator
->
aggregator_identifier
);
}
else
{
printk
(
KERN_ERR
DRV_NAME
": Port %d (on %s) did not find a suitable aggregator
\n
"
,
printk
(
KERN_ERR
DRV_NAME
": %s: Port %d (on %s) did not find a suitable aggregator
\n
"
,
port
->
slave
->
dev
->
master
->
name
,
port
->
actor_port_number
,
port
->
slave
->
dev
->
name
);
}
}
...
...
@@ -1582,8 +1552,9 @@ static void ad_agg_selection_logic(struct aggregator *aggregator)
// check if any partner replys
if
(
best_aggregator
->
is_individual
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: No 802.3ad response from the link partner "
"for any adapters in the bond
\n
"
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: No 802.3ad response from "
"the link partner for any adapters in the bond
\n
"
,
best_aggregator
->
slave
->
dev
->
master
->
name
);
}
// check if there are more than one aggregator
...
...
@@ -1915,7 +1886,8 @@ int bond_3ad_bind_slave(struct slave *slave)
struct
aggregator
*
aggregator
;
if
(
bond
==
NULL
)
{
printk
(
KERN_ERR
"The slave %s is not attached to its bond
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_ERR
DRV_NAME
": %s: The slave %s is not attached to its bond
\n
"
,
slave
->
dev
->
master
->
name
,
slave
->
dev
->
name
);
return
-
1
;
}
...
...
@@ -1990,7 +1962,9 @@ void bond_3ad_unbind_slave(struct slave *slave)
// if slave is null, the whole port is not initialized
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Trying to unbind an uninitialized port on %s
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": Warning: %s: Trying to "
"unbind an uninitialized port on %s
\n
"
,
slave
->
dev
->
master
->
name
,
slave
->
dev
->
name
);
return
;
}
...
...
@@ -2021,7 +1995,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
dprintk
(
"Some port(s) related to LAG %d - replaceing with LAG %d
\n
"
,
aggregator
->
aggregator_identifier
,
new_aggregator
->
aggregator_identifier
);
if
((
new_aggregator
->
lag_ports
==
port
)
&&
new_aggregator
->
is_active
)
{
printk
(
KERN_INFO
DRV_NAME
": Removing an active aggregator
\n
"
);
printk
(
KERN_INFO
DRV_NAME
": %s: Removing an active aggregator
\n
"
,
aggregator
->
slave
->
dev
->
master
->
name
);
// select new active aggregator
select_new_active_agg
=
1
;
}
...
...
@@ -2051,15 +2026,17 @@ void bond_3ad_unbind_slave(struct slave *slave)
ad_agg_selection_logic
(
__get_first_agg
(
port
));
}
}
else
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: unbinding aggregator, "
"and could not find a new aggregator for its ports
\n
"
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: unbinding aggregator, "
"and could not find a new aggregator for its ports
\n
"
,
slave
->
dev
->
master
->
name
);
}
}
else
{
// in case that the only port related to this aggregator is the one we want to remove
select_new_active_agg
=
aggregator
->
is_active
;
// clear the aggregator
ad_clear_agg
(
aggregator
);
if
(
select_new_active_agg
)
{
printk
(
KERN_INFO
"Removing an active aggregator
\n
"
);
printk
(
KERN_INFO
DRV_NAME
": %s: Removing an active aggregator
\n
"
,
slave
->
dev
->
master
->
name
);
// select new active aggregator
ad_agg_selection_logic
(
__get_first_agg
(
port
));
}
...
...
@@ -2085,7 +2062,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
// clear the aggregator
ad_clear_agg
(
temp_aggregator
);
if
(
select_new_active_agg
)
{
printk
(
KERN_INFO
"Removing an active aggregator
\n
"
);
printk
(
KERN_INFO
DRV_NAME
": %s: Removing an active aggregator
\n
"
,
slave
->
dev
->
master
->
name
);
// select new active aggregator
ad_agg_selection_logic
(
__get_first_agg
(
port
));
}
...
...
@@ -2131,7 +2109,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
// select the active aggregator for the bond
if
((
port
=
__get_first_port
(
bond
)))
{
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: bond's first port is uninitialized
\n
"
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: bond's first port is "
"uninitialized
\n
"
,
bond
->
dev
->
name
);
goto
re_arm
;
}
...
...
@@ -2143,7 +2122,8 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
// for each port run the state machines
for
(
port
=
__get_first_port
(
bond
);
port
;
port
=
__get_next_port
(
port
))
{
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: Found an uninitialized port
\n
"
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: Found an uninitialized "
"port
\n
"
,
bond
->
dev
->
name
);
goto
re_arm
;
}
...
...
@@ -2184,7 +2164,8 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
port
=
&
(
SLAVE_AD_INFO
(
slave
).
port
);
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: port of slave %s is uninitialized
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: port of slave %s is "
"uninitialized
\n
"
,
slave
->
dev
->
name
,
slave
->
dev
->
master
->
name
);
return
;
}
...
...
@@ -2230,8 +2211,9 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: speed changed for uninitialized port on %s
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": Warning: %s: speed "
"changed for uninitialized port on %s
\n
"
,
slave
->
dev
->
master
->
name
,
slave
->
dev
->
name
);
return
;
}
...
...
@@ -2257,8 +2239,9 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: duplex changed for uninitialized port on %s
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": %s: Warning: duplex changed "
"for uninitialized port on %s
\n
"
,
slave
->
dev
->
master
->
name
,
slave
->
dev
->
name
);
return
;
}
...
...
@@ -2285,8 +2268,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
// if slave is null, the whole port is not initialized
if
(
!
port
->
slave
)
{
printk
(
KERN_WARNING
DRV_NAME
": Warning: link status changed for uninitialized port on %s
\n
"
,
slave
->
dev
->
name
);
printk
(
KERN_WARNING
DRV_NAME
": Warning: %s: link status changed for "
"uninitialized port on %s
\n
"
,
slave
->
dev
->
master
->
name
,
slave
->
dev
->
name
);
return
;
}
...
...
@@ -2363,7 +2347,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
}
if
(
bond_3ad_get_active_agg_info
(
bond
,
&
ad_info
))
{
printk
(
KERN_DEBUG
"ERROR: bond_3ad_get_active_agg_info failed
\n
"
);
printk
(
KERN_DEBUG
DRV_NAME
": %s: Error: "
"bond_3ad_get_active_agg_info failed
\n
"
,
dev
->
name
);
goto
out
;
}
...
...
@@ -2372,7 +2357,9 @@ 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
"
);
printk
(
KERN_DEBUG
DRV_NAME
": %s: Error: active "
"aggregator is empty
\n
"
,
dev
->
name
);
goto
out
;
}
...
...
@@ -2390,7 +2377,8 @@ 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
);
printk
(
KERN_ERR
DRV_NAME
": %s: Error: Couldn't find a slave to tx on "
"for aggregator ID %d
\n
"
,
dev
->
name
,
agg_id
);
goto
out
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_3ad.h
View file @
d779188d
...
...
@@ -18,19 +18,6 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*
* Changes:
*
* 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Amir Noam <amir.noam at intel dot com>
* - Added support for lacp_rate module param.
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Renamed bond_3ad_link_status_changed() to
* bond_3ad_handle_link_change() for compatibility with TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*/
#ifndef __BOND_3AD_H__
...
...
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_alb.c
View file @
d779188d
...
...
@@ -18,25 +18,6 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*
* Changes:
*
* 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
* - Fixed signed/unsigned calculation errors that caused load sharing
* to collapse to one slave under very heavy UDP Tx stress.
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*
* 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
...
...
@@ -198,20 +179,21 @@ static int tlb_initialize(struct bonding *bond)
{
struct
alb_bond_info
*
bond_info
=
&
(
BOND_ALB_INFO
(
bond
));
int
size
=
TLB_HASH_TABLE_SIZE
*
sizeof
(
struct
tlb_client_info
);
struct
tlb_client_info
*
new_hashtbl
;
int
i
;
spin_lock_init
(
&
(
bond_info
->
tx_hashtbl_lock
));
_lock_tx_hashtbl
(
bond
);
bond_info
->
tx_hashtbl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
bond_info
->
tx_hashtbl
)
{
new_hashtbl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
new_hashtbl
)
{
printk
(
KERN_ERR
DRV_NAME
": Error:
%s:
Failed to allocate TLB hash table
\n
"
,
":
%s:
Error: Failed to allocate TLB hash table
\n
"
,
bond
->
dev
->
name
);
_unlock_tx_hashtbl
(
bond
);
return
-
1
;
}
_lock_tx_hashtbl
(
bond
);
bond_info
->
tx_hashtbl
=
new_hashtbl
;
memset
(
bond_info
->
tx_hashtbl
,
0
,
size
);
...
...
@@ -513,7 +495,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info
->
mac_dst
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to create an ARP packet
\n
"
);
": %s: Error: failed to create an ARP packet
\n
"
,
client_info
->
slave
->
dev
->
master
->
name
);
continue
;
}
...
...
@@ -523,7 +506,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
skb
=
vlan_put_tag
(
skb
,
client_info
->
vlan_id
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to insert VLAN tag
\n
"
);
": %s: Error: failed to insert VLAN tag
\n
"
,
client_info
->
slave
->
dev
->
master
->
name
);
continue
;
}
}
...
...
@@ -606,8 +590,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
if
(
!
client_info
->
slave
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: found a client with no channel in "
"the client's hash table
\n
"
);
": %s: Error: found a client with no channel in "
"the client's hash table
\n
"
,
bond
->
dev
->
name
);
continue
;
}
/*update all clients using this src_ip, that are not assigned
...
...
@@ -797,21 +782,22 @@ static int rlb_initialize(struct bonding *bond)
{
struct
alb_bond_info
*
bond_info
=
&
(
BOND_ALB_INFO
(
bond
));
struct
packet_type
*
pk_type
=
&
(
BOND_ALB_INFO
(
bond
).
rlb_pkt_type
);
struct
rlb_client_info
*
new_hashtbl
;
int
size
=
RLB_HASH_TABLE_SIZE
*
sizeof
(
struct
rlb_client_info
);
int
i
;
spin_lock_init
(
&
(
bond_info
->
rx_hashtbl_lock
));
_lock_rx_hashtbl
(
bond
);
bond_info
->
rx_hashtbl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
bond_info
->
rx_hashtbl
)
{
new_hashtbl
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
new_hashtbl
)
{
printk
(
KERN_ERR
DRV_NAME
": Error:
%s:
Failed to allocate RLB hash table
\n
"
,
":
%s:
Error: Failed to allocate RLB hash table
\n
"
,
bond
->
dev
->
name
);
_unlock_rx_hashtbl
(
bond
);
return
-
1
;
}
_lock_rx_hashtbl
(
bond
);
bond_info
->
rx_hashtbl
=
new_hashtbl
;
bond_info
->
rx_hashtbl_head
=
RLB_NULL_INDEX
;
...
...
@@ -927,7 +913,8 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb
=
vlan_put_tag
(
skb
,
vlan
->
vlan_id
);
if
(
!
skb
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: failed to insert VLAN tag
\n
"
);
": %s: Error: failed to insert VLAN tag
\n
"
,
bond
->
dev
->
name
);
continue
;
}
}
...
...
@@ -956,11 +943,11 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
s_addr
.
sa_family
=
dev
->
type
;
if
(
dev_set_mac_address
(
dev
,
&
s_addr
))
{
printk
(
KERN_ERR
DRV_NAME
": Error: dev_set_mac_address of dev %s failed! ALB "
":
%s:
Error: dev_set_mac_address of dev %s failed! ALB "
"mode requires that the base driver support setting "
"the hw address also when the network device's "
"interface is open
\n
"
,
dev
->
name
);
dev
->
master
->
name
,
dev
->
name
);
return
-
EOPNOTSUPP
;
}
return
0
;
...
...
@@ -1153,16 +1140,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
bond
->
alb_info
.
rlb_enabled
);
printk
(
KERN_WARNING
DRV_NAME
": Warning: the hw address of slave %s is in use by "
":
%s:
Warning: the hw address of slave %s is in use by "
"the bond; giving it the hw address of %s
\n
"
,
slave
->
dev
->
name
,
free_mac_slave
->
dev
->
name
);
bond
->
dev
->
name
,
slave
->
dev
->
name
,
free_mac_slave
->
dev
->
name
);
}
else
if
(
has_bond_addr
)
{
printk
(
KERN_ERR
DRV_NAME
": Error: the hw address of slave %s is in use by the "
":
%s:
Error: the hw address of slave %s is in use by the "
"bond; couldn't find a slave with a free hw address to "
"give it (this should not have happened)
\n
"
,
slave
->
dev
->
name
);
bond
->
dev
->
name
,
slave
->
dev
->
name
);
return
-
EFAULT
;
}
...
...
@@ -1250,6 +1237,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
tlb_deinitialize
(
bond
);
return
res
;
}
}
else
{
bond
->
alb_info
.
rlb_enabled
=
0
;
}
return
0
;
...
...
@@ -1409,7 +1398,7 @@ void bond_alb_monitor(struct bonding *bond)
read_lock
(
&
bond
->
curr_slave_lock
);
bond_for_each_slave
(
bond
,
slave
,
i
)
{
alb_send_learning_packets
(
slave
,
slave
->
dev
->
dev_addr
);
alb_send_learning_packets
(
slave
,
slave
->
dev
->
dev_addr
);
}
read_unlock
(
&
bond
->
curr_slave_lock
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_alb.h
View file @
d779188d
...
...
@@ -18,15 +18,6 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*
* Changes:
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*/
#ifndef __BOND_ALB_H__
...
...
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_main.c
View file @
d779188d
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bond_sysfs.c
0 → 100644
View file @
d779188d
This diff is collapsed.
Click to expand it.
drivers/net/bonding/bonding.h
View file @
d779188d
...
...
@@ -10,25 +10,6 @@
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
*
* 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
* Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Shmulik Hen <shmulik.hen at intel dot com>
* - Added support for IEEE 802.3ad Dynamic link aggregation mode.
*
* 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Amir Noam <amir.noam at intel dot com>
* - Code beautification and style changes (mainly in comments).
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Added support for Transmit load balancing mode.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*
* 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
* - added "xmit_policy" kernel parameter for alternate hashing policy
* support for mode 2
*/
#ifndef _LINUX_BONDING_H
...
...
@@ -37,11 +18,12 @@
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/if_bonding.h>
#include <linux/kobject.h>
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "
2.6.5
"
#define DRV_RELDATE "November
4
, 2005"
#define DRV_VERSION "
3.0.0
"
#define DRV_RELDATE "November
8
, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
...
...
@@ -152,6 +134,11 @@ struct bond_params {
u32
arp_targets
[
BOND_MAX_ARP_TARGETS
];
};
struct
bond_parm_tbl
{
char
*
modename
;
int
mode
;
};
struct
vlan_entry
{
struct
list_head
vlan_list
;
u32
vlan_ip
;
...
...
@@ -159,7 +146,7 @@ struct vlan_entry {
};
struct
slave
{
struct
net_device
*
dev
;
/* first - useful
l
for panic debug */
struct
net_device
*
dev
;
/* first - useful for panic debug */
struct
slave
*
next
;
struct
slave
*
prev
;
s16
delay
;
...
...
@@ -185,7 +172,7 @@ struct slave {
* beforehand.
*/
struct
bonding
{
struct
net_device
*
dev
;
/* first - useful
l
for panic debug */
struct
net_device
*
dev
;
/* first - useful for panic debug */
struct
slave
*
first_slave
;
struct
slave
*
curr_active_slave
;
struct
slave
*
current_arp_slave
;
...
...
@@ -255,6 +242,25 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
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
);
int
bond_create
(
char
*
name
,
struct
bond_params
*
params
,
struct
bonding
**
newbond
);
void
bond_deinit
(
struct
net_device
*
bond_dev
);
int
bond_create_sysfs
(
void
);
void
bond_destroy_sysfs
(
void
);
void
bond_destroy_sysfs_entry
(
struct
bonding
*
bond
);
int
bond_create_sysfs_entry
(
struct
bonding
*
bond
);
int
bond_create_slave_symlinks
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
void
bond_destroy_slave_symlinks
(
struct
net_device
*
master
,
struct
net_device
*
slave
);
int
bond_enslave
(
struct
net_device
*
bond_dev
,
struct
net_device
*
slave_dev
);
int
bond_release
(
struct
net_device
*
bond_dev
,
struct
net_device
*
slave_dev
);
int
bond_sethwaddr
(
struct
net_device
*
bond_dev
,
struct
net_device
*
slave_dev
);
void
bond_mii_monitor
(
struct
net_device
*
bond_dev
);
void
bond_loadbalance_arp_mon
(
struct
net_device
*
bond_dev
);
void
bond_activebackup_arp_mon
(
struct
net_device
*
bond_dev
);
void
bond_set_mode_ops
(
struct
bonding
*
bond
,
int
mode
);
int
bond_parse_parm
(
char
*
mode_arg
,
struct
bond_parm_tbl
*
tbl
);
const
char
*
bond_mode_name
(
int
mode
);
void
bond_select_active_slave
(
struct
bonding
*
bond
);
void
bond_change_active_slave
(
struct
bonding
*
bond
,
struct
slave
*
new_active
);
#endif
/* _LINUX_BONDING_H */
This diff is collapsed.
Click to expand it.
drivers/net/chelsio/sge.c
View file @
d779188d
...
...
@@ -1332,8 +1332,8 @@ intr_handler_t t1_select_intr_handler(adapter_t *adapter)
*
* This runs with softirqs disabled.
*/
unsigned
int
t1_sge_tx
(
struct
sk_buff
*
skb
,
struct
adapter
*
adapter
,
unsigned
int
qid
,
struct
net_device
*
dev
)
static
int
t1_sge_tx
(
struct
sk_buff
*
skb
,
struct
adapter
*
adapter
,
unsigned
int
qid
,
struct
net_device
*
dev
)
{
struct
sge
*
sge
=
adapter
->
sge
;
struct
cmdQ
*
q
=
&
sge
->
cmdQ
[
qid
];
...
...
@@ -1352,9 +1352,10 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
set_bit
(
dev
->
if_port
,
&
sge
->
stopped_tx_queues
);
sge
->
stats
.
cmdQ_full
[
3
]
++
;
spin_unlock
(
&
q
->
lock
);
CH_ERR
(
"%s: Tx ring full while queue awake!
\n
"
,
adapter
->
name
);
return
1
;
if
(
!
netif_queue_stopped
(
dev
))
CH_ERR
(
"%s: Tx ring full while queue awake!
\n
"
,
adapter
->
name
);
return
NETDEV_TX_BUSY
;
}
if
(
unlikely
(
credits
-
count
<
q
->
stop_thres
))
{
sge
->
stats
.
cmdQ_full
[
3
]
++
;
...
...
@@ -1389,7 +1390,7 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
writel
(
F_CMDQ0_ENABLE
,
adapter
->
regs
+
A_SG_DOORBELL
);
}
}
return
0
;
return
NETDEV_TX_OK
;
}
#define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
...
...
@@ -1449,7 +1450,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
if
(
unlikely
(
skb
->
len
<
ETH_HLEN
||
skb
->
len
>
dev
->
mtu
+
eth_hdr_len
(
skb
->
data
)))
{
dev_kfree_skb_any
(
skb
);
return
NET
_XMIT_SUCCESS
;
return
NET
DEV_TX_OK
;
}
/*
...
...
@@ -1467,7 +1468,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb
=
skb_realloc_headroom
(
skb
,
sizeof
(
*
cpl
));
dev_kfree_skb_any
(
orig_skb
);
if
(
!
skb
)
return
-
ENOMEM
;
return
NETDEV_TX_OK
;
}
if
(
!
(
adapter
->
flags
&
UDP_CSUM_CAPABLE
)
&&
...
...
@@ -1475,7 +1476,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb
->
nh
.
iph
->
protocol
==
IPPROTO_UDP
)
if
(
unlikely
(
skb_checksum_help
(
skb
,
0
)))
{
dev_kfree_skb_any
(
skb
);
return
-
ENOMEM
;
return
NETDEV_TX_OK
;
}
/* Hmmm, assuming to catch the gratious arp... and we'll use
...
...
This diff is collapsed.
Click to expand it.
drivers/net/chelsio/sge.h
View file @
d779188d
...
...
@@ -89,8 +89,6 @@ int t1_sge_configure(struct sge *, struct sge_params *);
int
t1_sge_set_coalesce_params
(
struct
sge
*
,
struct
sge_params
*
);
void
t1_sge_destroy
(
struct
sge
*
);
intr_handler_t
t1_select_intr_handler
(
adapter_t
*
adapter
);
unsigned
int
t1_sge_tx
(
struct
sk_buff
*
skb
,
struct
adapter
*
adapter
,
unsigned
int
qid
,
struct
net_device
*
netdev
);
int
t1_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
void
t1_set_vlan_accel
(
struct
adapter
*
adapter
,
int
on_off
);
void
t1_sge_start
(
struct
sge
*
);
...
...
This diff is collapsed.
Click to expand it.
drivers/net/e1000/e1000.h
View file @
d779188d
...
...
@@ -188,11 +188,13 @@ struct e1000_tx_ring {
/* array of buffer information structs */
struct
e1000_buffer
*
buffer_info
;
struct
e1000_buffer
previous_buffer_info
;
spinlock_t
tx_lock
;
uint16_t
tdh
;
uint16_t
tdt
;
uint64_t
pkt
;
boolean_t
last_tx_tso
;
};
struct
e1000_rx_ring
{
...
...
This diff is collapsed.
Click to expand it.
drivers/net/e1000/e1000_ethtool.c
View file @
d779188d
...
...
@@ -562,10 +562,29 @@ e1000_get_drvinfo(struct net_device *netdev,
struct
ethtool_drvinfo
*
drvinfo
)
{
struct
e1000_adapter
*
adapter
=
netdev_priv
(
netdev
);
char
firmware_version
[
32
];
uint16_t
eeprom_data
;
strncpy
(
drvinfo
->
driver
,
e1000_driver_name
,
32
);
strncpy
(
drvinfo
->
version
,
e1000_driver_version
,
32
);
strncpy
(
drvinfo
->
fw_version
,
"N/A"
,
32
);
/* EEPROM image version # is reported as firware version # for
* 8257{1|2|3} controllers */
e1000_read_eeprom
(
&
adapter
->
hw
,
5
,
1
,
&
eeprom_data
);
switch
(
adapter
->
hw
.
mac_type
)
{
case
e1000_82571
:
case
e1000_82572
:
case
e1000_82573
:
sprintf
(
firmware_version
,
"%d.%d-%d"
,
(
eeprom_data
&
0xF000
)
>>
12
,
(
eeprom_data
&
0x0FF0
)
>>
4
,
eeprom_data
&
0x000F
);
break
;
default:
sprintf
(
firmware_version
,
"n/a"
);
}
strncpy
(
drvinfo
->
fw_version
,
firmware_version
,
32
);
strncpy
(
drvinfo
->
bus_info
,
pci_name
(
adapter
->
pdev
),
32
);
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
drvinfo
->
testinfo_len
=
E1000_TEST_LEN
;
...
...
@@ -960,13 +979,21 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
}
}
if
(
txdr
->
desc
)
if
(
txdr
->
desc
)
{
pci_free_consistent
(
pdev
,
txdr
->
size
,
txdr
->
desc
,
txdr
->
dma
);
if
(
rxdr
->
desc
)
txdr
->
desc
=
NULL
;
}
if
(
rxdr
->
desc
)
{
pci_free_consistent
(
pdev
,
rxdr
->
size
,
rxdr
->
desc
,
rxdr
->
dma
);
rxdr
->
desc
=
NULL
;
}
kfree
(
txdr
->
buffer_info
);
txdr
->
buffer_info
=
NULL
;
kfree
(
rxdr
->
buffer_info
);
rxdr
->
buffer_info
=
NULL
;
return
;
}
...
...
@@ -1301,21 +1328,32 @@ static int
e1000_setup_loopback_test
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
rctl
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_fiber
||
adapter
->
hw
.
media_type
==
e1000_media_type_internal_serdes
)
{
if
(
adapter
->
hw
.
mac_type
==
e1000_82545
||
adapter
->
hw
.
mac_type
==
e1000_82546
||
adapter
->
hw
.
mac_type
==
e1000_82545_rev_3
||
adapter
->
hw
.
mac_type
==
e1000_82546_rev_3
)
if
(
hw
->
media_type
==
e1000_media_type_fiber
||
hw
->
media_type
==
e1000_media_type_internal_serdes
)
{
switch
(
hw
->
mac_type
)
{
case
e1000_82545
:
case
e1000_82546
:
case
e1000_82545_rev_3
:
case
e1000_82546_rev_3
:
return
e1000_set_phy_loopback
(
adapter
);
else
{
rctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
RCTL
);
break
;
case
e1000_82571
:
case
e1000_82572
:
#define E1000_SERDES_LB_ON 0x410
e1000_set_phy_loopback
(
adapter
);
E1000_WRITE_REG
(
hw
,
SCTL
,
E1000_SERDES_LB_ON
);
msec_delay
(
10
);
return
0
;
break
;
default:
rctl
=
E1000_READ_REG
(
hw
,
RCTL
);
rctl
|=
E1000_RCTL_LBM_TCVR
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
RCTL
,
rctl
);
E1000_WRITE_REG
(
hw
,
RCTL
,
rctl
);
return
0
;
}
}
else
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
)
}
else
if
(
hw
->
media_type
==
e1000_media_type_copper
)
return
e1000_set_phy_loopback
(
adapter
);
return
7
;
...
...
@@ -1326,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
{
uint32_t
rctl
;
uint16_t
phy_reg
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
rctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
RCTL
);
rctl
&=
~
(
E1000_RCTL_LBM_TCVR
|
E1000_RCTL_LBM_MAC
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RCTL
,
rctl
);
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
||
((
adapter
->
hw
.
media_type
==
e1000_media_type_fiber
||
adapter
->
hw
.
media_type
==
e1000_media_type_internal_serdes
)
&&
(
adapter
->
hw
.
mac_type
==
e1000_82545
||
adapter
->
hw
.
mac_type
==
e1000_82546
||
adapter
->
hw
.
mac_type
==
e1000_82545_rev_3
||
adapter
->
hw
.
mac_type
==
e1000_82546_rev_3
)))
{
adapter
->
hw
.
autoneg
=
TRUE
;
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_reg
);
if
(
phy_reg
&
MII_CR_LOOPBACK
)
{
switch
(
hw
->
mac_type
)
{
case
e1000_82571
:
case
e1000_82572
:
if
(
hw
->
media_type
==
e1000_media_type_fiber
||
hw
->
media_type
==
e1000_media_type_internal_serdes
){
#define E1000_SERDES_LB_OFF 0x400
E1000_WRITE_REG
(
hw
,
SCTL
,
E1000_SERDES_LB_OFF
);
msec_delay
(
10
);
break
;
}
/* fall thru for Cu adapters */
case
e1000_82545
:
case
e1000_82546
:
case
e1000_82545_rev_3
:
case
e1000_82546_rev_3
:
default:
hw
->
autoneg
=
TRUE
;
e1000_read_phy_reg
(
hw
,
PHY_CTRL
,
&
phy_reg
);
if
(
phy_reg
&
MII_CR_LOOPBACK
)
{
phy_reg
&=
~
MII_CR_LOOPBACK
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
phy_reg
);
e1000_phy_reset
(
&
adapter
->
hw
);
e1000_write_phy_reg
(
hw
,
PHY_CTRL
,
phy_reg
);
e1000_phy_reset
(
hw
);
}
break
;
}
}
...
...
@@ -1440,9 +1489,11 @@ static int
e1000_loopback_test
(
struct
e1000_adapter
*
adapter
,
uint64_t
*
data
)
{
if
((
*
data
=
e1000_setup_desc_rings
(
adapter
)))
goto
err_loopback
;
if
((
*
data
=
e1000_setup_loopback_test
(
adapter
)))
goto
err_loopback
;
if
((
*
data
=
e1000_setup_loopback_test
(
adapter
)))
goto
err_loopback_setup
;
*
data
=
e1000_run_loopback_test
(
adapter
);
e1000_loopback_cleanup
(
adapter
);
err_loopback_setup:
e1000_free_desc_rings
(
adapter
);
err_loopback:
return
*
data
;
...
...
@@ -1671,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
msleep_interruptible
(
data
*
1000
);
del_timer_sync
(
&
adapter
->
blink_timer
);
}
else
if
(
adapter
->
hw
.
mac_type
<
e1000_82573
)
{
E1000_WRITE_REG
(
&
adapter
->
hw
,
LEDCTL
,
(
E1000_LEDCTL_LED2_BLINK_RATE
|
E1000_LEDCTL_LED0_BLINK
|
E1000_LEDCTL_LED2_BLINK
|
(
E1000_LEDCTL_MODE_LED_ON
<<
E1000_LEDCTL_LED2_MODE_SHIFT
)
|
(
E1000_LEDCTL_MODE_LINK_ACTIVITY
<<
E1000_LEDCTL_LED0_MODE_SHIFT
)
|
(
E1000_LEDCTL_MODE_LED_OFF
<<
E1000_LEDCTL_LED1_MODE_SHIFT
)));
msleep_interruptible
(
data
*
1000
);
}
else
{
E1000_WRITE_REG
(
&
adapter
->
hw
,
LEDCTL
,
(
E1000_LEDCTL_LED2_BLINK_RATE
|
E1000_LEDCTL_LED1_BLINK
|
E1000_LEDCTL_LED2_BLINK
|
...
...
This diff is collapsed.
Click to expand it.
drivers/net/e1000/e1000_hw.c
View file @
d779188d
...
...
@@ -563,11 +563,13 @@ e1000_reset_hw(struct e1000_hw *hw)
msec_delay
(
20
);
break
;
case
e1000_82573
:
udelay
(
10
);
ctrl_ext
=
E1000_READ_REG
(
hw
,
CTRL_EXT
);
ctrl_ext
|=
E1000_CTRL_EXT_EE_RST
;
E1000_WRITE_REG
(
hw
,
CTRL_EXT
,
ctrl_ext
);
E1000_WRITE_FLUSH
(
hw
);
if
(
e1000_is_onboard_nvm_eeprom
(
hw
)
==
FALSE
)
{
udelay
(
10
);
ctrl_ext
=
E1000_READ_REG
(
hw
,
CTRL_EXT
);
ctrl_ext
|=
E1000_CTRL_EXT_EE_RST
;
E1000_WRITE_REG
(
hw
,
CTRL_EXT
,
ctrl_ext
);
E1000_WRITE_FLUSH
(
hw
);
}
/* fall through */
case
e1000_82571
:
case
e1000_82572
:
...
...
@@ -844,19 +846,27 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
if
(
e1000_read_eeprom
(
hw
,
EEPROM_INIT_CONTROL2_REG
,
1
,
&
eeprom_data
))
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
if
(
hw
->
fc
==
e1000_fc_default
)
{
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
0
)
hw
->
fc
=
e1000_fc_none
;
else
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
EEPROM_WORD0F_ASM_DIR
)
hw
->
fc
=
e1000_fc_tx_pause
;
else
if
(
hw
->
fc
==
e1000_fc_default
)
{
switch
(
hw
->
mac_type
)
{
case
e1000_82573
:
hw
->
fc
=
e1000_fc_full
;
break
;
default:
ret_val
=
e1000_read_eeprom
(
hw
,
EEPROM_INIT_CONTROL2_REG
,
1
,
&
eeprom_data
);
if
(
ret_val
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
0
)
hw
->
fc
=
e1000_fc_none
;
else
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
EEPROM_WORD0F_ASM_DIR
)
hw
->
fc
=
e1000_fc_tx_pause
;
else
hw
->
fc
=
e1000_fc_full
;
break
;
}
}
/* We want to save off the original Flow Control configuration just
...
...
@@ -2962,13 +2972,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if
(
hw
->
mac_type
>
e1000_82543
)
{
/* Read the device control register and assert the E1000_CTRL_PHY_RST
* bit. Then, take it out of reset.
* For pre-e1000_82571 hardware, we delay for 10ms between the assert
* and deassert. For e1000_82571 hardware and later, we instead delay
* for 10ms after the deassertion.
*/
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
E1000_WRITE_REG
(
hw
,
CTRL
,
ctrl
|
E1000_CTRL_PHY_RST
);
E1000_WRITE_FLUSH
(
hw
);
msec_delay
(
10
);
if
(
hw
->
mac_type
<
e1000_82571
)
msec_delay
(
10
);
E1000_WRITE_REG
(
hw
,
CTRL
,
ctrl
);
E1000_WRITE_FLUSH
(
hw
);
if
(
hw
->
mac_type
>=
e1000_82571
)
msec_delay
(
10
);
}
else
{
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset.
...
...
@@ -5278,9 +5297,13 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw
->
bus_speed
=
e1000_bus_speed_unknown
;
hw
->
bus_width
=
e1000_bus_width_unknown
;
break
;
case
e1000_82571
:
case
e1000_82572
:
case
e1000_82573
:
hw
->
bus_type
=
e1000_bus_type_pci_express
;
hw
->
bus_speed
=
e1000_bus_speed_2500
;
hw
->
bus_width
=
e1000_bus_width_pciex_1
;
break
;
case
e1000_82571
:
hw
->
bus_type
=
e1000_bus_type_pci_express
;
hw
->
bus_speed
=
e1000_bus_speed_2500
;
hw
->
bus_width
=
e1000_bus_width_pciex_4
;
...
...
@@ -6650,6 +6673,12 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
break
;
}
/* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
* Need to wait for PHY configuration completion before accessing NVM
* and PHY. */
if
(
hw
->
mac_type
==
e1000_82573
)
msec_delay
(
25
);
return
E1000_SUCCESS
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/e1000/e1000_hw.h
View file @
d779188d
...
...
@@ -123,6 +123,7 @@ typedef enum {
e1000_bus_width_32
,
e1000_bus_width_64
,
e1000_bus_width_pciex_1
,
e1000_bus_width_pciex_2
,
e1000_bus_width_pciex_4
,
e1000_bus_width_reserved
}
e1000_bus_width
;
...
...
@@ -149,6 +150,7 @@ typedef enum {
e1000_igp_cable_length_90
=
90
,
e1000_igp_cable_length_100
=
100
,
e1000_igp_cable_length_110
=
110
,
e1000_igp_cable_length_115
=
115
,
e1000_igp_cable_length_120
=
120
,
e1000_igp_cable_length_130
=
130
,
e1000_igp_cable_length_140
=
140
,
...
...
@@ -1457,6 +1459,7 @@ struct e1000_hw {
#define E1000_EECD_AUPDEN 0x00100000
/* Enable Autonomous FLASH update */
#define E1000_EECD_SHADV 0x00200000
/* Shadow RAM Data Valid */
#define E1000_EECD_SEC1VAL 0x00400000
/* Sector One Valid */
#define E1000_EECD_SECVAL_SHIFT 22
#define E1000_STM_OPCODE 0xDB00
#define E1000_HICR_FW_RESET 0xC0
...
...
@@ -1951,7 +1954,6 @@ struct e1000_host_command_info {
#define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
...
...
This diff is collapsed.
Click to expand it.
drivers/net/e1000/e1000_main.c
View file @
d779188d
...
...
@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev,
break
;
case
e1000_82546
:
case
e1000_82546_rev_3
:
case
e1000_82571
:
if
((
E1000_READ_REG
(
&
adapter
->
hw
,
STATUS
)
&
E1000_STATUS_FUNC_1
)
&&
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
))
{
e1000_read_eeprom
(
&
adapter
->
hw
,
...
...
@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
return
-
ENOMEM
;
}
memset
(
txdr
->
buffer_info
,
0
,
size
);
memset
(
&
txdr
->
previous_buffer_info
,
0
,
sizeof
(
struct
e1000_buffer
));
/* round up to nearest 4K */
...
...
@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
/* Free all the Tx ring sk_buffs */
if
(
likely
(
tx_ring
->
previous_buffer_info
.
skb
!=
NULL
))
{
e1000_unmap_and_free_tx_resource
(
adapter
,
&
tx_ring
->
previous_buffer_info
);
}
for
(
i
=
0
;
i
<
tx_ring
->
count
;
i
++
)
{
buffer_info
=
&
tx_ring
->
buffer_info
[
i
];
e1000_unmap_and_free_tx_resource
(
adapter
,
buffer_info
);
...
...
@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
tx_ring
->
next_to_use
=
0
;
tx_ring
->
next_to_clean
=
0
;
tx_ring
->
last_tx_tso
=
0
;
writel
(
0
,
adapter
->
hw
.
hw_addr
+
tx_ring
->
tdh
);
writel
(
0
,
adapter
->
hw
.
hw_addr
+
tx_ring
->
tdt
);
...
...
@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
buffer_info
=
&
tx_ring
->
buffer_info
[
i
];
size
=
min
(
len
,
max_per_txd
);
#ifdef NETIF_F_TSO
/* Workaround for Controller erratum --
* descriptor for non-tso packet in a linear SKB that follows a
* tso gets written back prematurely before the data is fully
* DMAd to the controller */
if
(
!
skb
->
data_len
&&
tx_ring
->
last_tx_tso
&&
!
skb_shinfo
(
skb
)
->
tso_size
)
{
tx_ring
->
last_tx_tso
=
0
;
size
-=
4
;
}
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if
(
unlikely
(
mss
&&
!
nr_frags
&&
size
==
len
&&
size
>
8
))
...
...
@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if
(
skb
->
ip_summed
==
CHECKSUM_HW
)
count
++
;
#endif
#ifdef NETIF_F_TSO
/* Controller Erratum workaround */
if
(
!
skb
->
data_len
&&
tx_ring
->
last_tx_tso
&&
!
skb_shinfo
(
skb
)
->
tso_size
)
count
++
;
#endif
count
+=
TXD_USE_COUNT
(
len
,
max_txd_pwr
);
if
(
adapter
->
pcix_82544
)
...
...
@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return
NETDEV_TX_OK
;
}
if
(
likely
(
tso
))
if
(
likely
(
tso
))
{
tx_ring
->
last_tx_tso
=
1
;
tx_flags
|=
E1000_TX_FLAGS_TSO
;
else
if
(
likely
(
e1000_tx_csum
(
adapter
,
tx_ring
,
skb
)))
}
else
if
(
likely
(
e1000_tx_csum
(
adapter
,
tx_ring
,
skb
)))
tx_flags
|=
E1000_TX_FLAGS_CSUM
;
/* Old method was to assume IPv4 packet by default if TSO was enabled.
...
...
@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
eop_desc
=
E1000_TX_DESC
(
*
tx_ring
,
eop
);
while
(
eop_desc
->
upper
.
data
&
cpu_to_le32
(
E1000_TXD_STAT_DD
))
{
/* Premature writeback of Tx descriptors clear (free buffers
* and unmap pci_mapping) previous_buffer_info */
if
(
likely
(
tx_ring
->
previous_buffer_info
.
skb
!=
NULL
))
{
e1000_unmap_and_free_tx_resource
(
adapter
,
&
tx_ring
->
previous_buffer_info
);
}
for
(
cleaned
=
FALSE
;
!
cleaned
;
)
{
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
buffer_info
=
&
tx_ring
->
buffer_info
[
i
];
cleaned
=
(
i
==
eop
);
#ifdef NETIF_F_TSO
if
(
!
(
netdev
->
features
&
NETIF_F_TSO
))
{
#endif
e1000_unmap_and_free_tx_resource
(
adapter
,
buffer_info
);
#ifdef NETIF_F_TSO
}
else
{
if
(
cleaned
)
{
memcpy
(
&
tx_ring
->
previous_buffer_info
,
buffer_info
,
sizeof
(
struct
e1000_buffer
));
memset
(
buffer_info
,
0
,
sizeof
(
struct
e1000_buffer
));
}
else
{
e1000_unmap_and_free_tx_resource
(
adapter
,
buffer_info
);
}
}
#endif
e1000_unmap_and_free_tx_resource
(
adapter
,
buffer_info
);
tx_desc
->
buffer_addr
=
0
;
tx_desc
->
lower
.
data
=
0
;
...
...
@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
netif_stop_queue
(
netdev
);
}
}
#ifdef NETIF_F_TSO
if
(
unlikely
(
!
(
eop_desc
->
upper
.
data
&
cpu_to_le32
(
E1000_TXD_STAT_DD
))
&&
time_after
(
jiffies
,
tx_ring
->
previous_buffer_info
.
time_stamp
+
HZ
)))
e1000_unmap_and_free_tx_resource
(
adapter
,
&
tx_ring
->
previous_buffer_info
);
#endif
return
cleaned
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/net/gianfar.c
View file @
d779188d
...
...
@@ -2,7 +2,8 @@
* drivers/net/gianfar.c
*
* Gianfar Ethernet Driver
* Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
* This driver is designed for the non-CPM ethernet controllers
* on the 85xx and 83xx family of integrated processors
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
...
...
@@ -22,8 +23,6 @@
* B-V +1.62
*
* Theory of operation
* This driver is designed for the non-CPM ethernet controllers
* on the 85xx and 83xx family of integrated processors
*
* The driver is initialized through platform_device. Structures which
* define the configuration needed by the board are defined in a
...
...
@@ -110,7 +109,7 @@
#endif
const
char
gfar_driver_name
[]
=
"Gianfar Ethernet"
;
const
char
gfar_driver_version
[]
=
"1.
2
"
;
const
char
gfar_driver_version
[]
=
"1.
3
"
;
static
int
gfar_enet_open
(
struct
net_device
*
dev
);
static
int
gfar_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
...
...
@@ -139,6 +138,10 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
static
void
gfar_vlan_rx_register
(
struct
net_device
*
netdev
,
struct
vlan_group
*
grp
);
static
void
gfar_vlan_rx_kill_vid
(
struct
net_device
*
netdev
,
uint16_t
vid
);
void
gfar_halt
(
struct
net_device
*
dev
);
void
gfar_start
(
struct
net_device
*
dev
);
static
void
gfar_clear_exact_match
(
struct
net_device
*
dev
);
static
void
gfar_set_mac_for_addr
(
struct
net_device
*
dev
,
int
num
,
u8
*
addr
);
extern
struct
ethtool_ops
gfar_ethtool_ops
;
...
...
@@ -146,12 +149,10 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION
(
"Gianfar Ethernet Driver"
);
MODULE_LICENSE
(
"GPL"
);
int
gfar_uses_fcb
(
struct
gfar_private
*
priv
)
/* Returns 1 if incoming frames use an FCB */
static
inline
int
gfar_uses_fcb
(
struct
gfar_private
*
priv
)
{
if
(
priv
->
vlan_enable
||
priv
->
rx_csum_enable
)
return
1
;
else
return
0
;
return
(
priv
->
vlan_enable
||
priv
->
rx_csum_enable
);
}
/* Set up the ethernet device structure, private data,
...
...
@@ -320,15 +321,10 @@ static int gfar_probe(struct platform_device *pdev)
else
priv
->
padding
=
0
;
dev
->
hard_header_len
+=
priv
->
padding
;
if
(
dev
->
features
&
NETIF_F_IP_CSUM
)
dev
->
hard_header_len
+=
GMAC_FCB_LEN
;
priv
->
rx_buffer_size
=
DEFAULT_RX_BUFFER_SIZE
;
#ifdef CONFIG_GFAR_BUFSTASH
priv
->
rx_stash_size
=
STASH_LENGTH
;
#endif
priv
->
tx_ring_size
=
DEFAULT_TX_RING_SIZE
;
priv
->
rx_ring_size
=
DEFAULT_RX_RING_SIZE
;
...
...
@@ -350,6 +346,9 @@ static int gfar_probe(struct platform_device *pdev)
goto
register_fail
;
}
/* Create all the sysfs files */
gfar_init_sysfs
(
dev
);
/* Print out the device info */
printk
(
KERN_INFO
DEVICE_NAME
,
dev
->
name
);
for
(
idx
=
0
;
idx
<
6
;
idx
++
)
...
...
@@ -357,8 +356,7 @@ static int gfar_probe(struct platform_device *pdev)
printk
(
"
\n
"
);
/* Even more device info helps when determining which kernel */
/* provided which set of benchmarks. Since this is global for all */
/* devices, we only print it once */
/* provided which set of benchmarks. */
#ifdef CONFIG_GFAR_NAPI
printk
(
KERN_INFO
"%s: Running with NAPI enabled
\n
"
,
dev
->
name
);
#else
...
...
@@ -463,19 +461,9 @@ static void init_registers(struct net_device *dev)
/* Initialize the max receive buffer length */
gfar_write
(
&
priv
->
regs
->
mrblr
,
priv
->
rx_buffer_size
);
#ifdef CONFIG_GFAR_BUFSTASH
/* If we are stashing buffers, we need to set the
* extraction length to the size of the buffer */
gfar_write
(
&
priv
->
regs
->
attreli
,
priv
->
rx_stash_size
<<
16
);
#endif
/* Initialize the Minimum Frame Length Register */
gfar_write
(
&
priv
->
regs
->
minflr
,
MINFLR_INIT_SETTINGS
);
/* Setup Attributes so that snooping is on for rx */
gfar_write
(
&
priv
->
regs
->
attr
,
ATTR_INIT_SETTINGS
);
gfar_write
(
&
priv
->
regs
->
attreli
,
ATTRELI_INIT_SETTINGS
);
/* Assign the TBI an address which won't conflict with the PHYs */
gfar_write
(
&
priv
->
regs
->
tbipa
,
TBIPA_VALUE
);
}
...
...
@@ -577,8 +565,7 @@ static void free_skb_resources(struct gfar_private *priv)
for
(
i
=
0
;
i
<
priv
->
rx_ring_size
;
i
++
)
{
if
(
priv
->
rx_skbuff
[
i
])
{
dma_unmap_single
(
NULL
,
rxbdp
->
bufPtr
,
priv
->
rx_buffer_size
+
RXBUF_ALIGNMENT
,
priv
->
rx_buffer_size
,
DMA_FROM_DEVICE
);
dev_kfree_skb_any
(
priv
->
rx_skbuff
[
i
]);
...
...
@@ -636,6 +623,7 @@ int startup_gfar(struct net_device *dev)
struct
gfar
*
regs
=
priv
->
regs
;
int
err
=
0
;
u32
rctrl
=
0
;
u32
attrs
=
0
;
gfar_write
(
&
regs
->
imask
,
IMASK_INIT_CLEAR
);
...
...
@@ -795,18 +783,50 @@ int startup_gfar(struct net_device *dev)
if
(
priv
->
rx_csum_enable
)
rctrl
|=
RCTRL_CHECKSUMMING
;
if
(
priv
->
extended_hash
)
if
(
priv
->
extended_hash
)
{
rctrl
|=
RCTRL_EXTHASH
;
gfar_clear_exact_match
(
dev
);
rctrl
|=
RCTRL_EMEN
;
}
if
(
priv
->
vlan_enable
)
rctrl
|=
RCTRL_VLAN
;
if
(
priv
->
padding
)
{
rctrl
&=
~
RCTRL_PAL_MASK
;
rctrl
|=
RCTRL_PADDING
(
priv
->
padding
);
}
/* Init rctrl based on our settings */
gfar_write
(
&
priv
->
regs
->
rctrl
,
rctrl
);
if
(
dev
->
features
&
NETIF_F_IP_CSUM
)
gfar_write
(
&
priv
->
regs
->
tctrl
,
TCTRL_INIT_CSUM
);
/* Set the extraction length and index */
attrs
=
ATTRELI_EL
(
priv
->
rx_stash_size
)
|
ATTRELI_EI
(
priv
->
rx_stash_index
);
gfar_write
(
&
priv
->
regs
->
attreli
,
attrs
);
/* Start with defaults, and add stashing or locking
* depending on the approprate variables */
attrs
=
ATTR_INIT_SETTINGS
;
if
(
priv
->
bd_stash_en
)
attrs
|=
ATTR_BDSTASH
;
if
(
priv
->
rx_stash_size
!=
0
)
attrs
|=
ATTR_BUFSTASH
;
gfar_write
(
&
priv
->
regs
->
attr
,
attrs
);
gfar_write
(
&
priv
->
regs
->
fifo_tx_thr
,
priv
->
fifo_threshold
);
gfar_write
(
&
priv
->
regs
->
fifo_tx_starve
,
priv
->
fifo_starve
);
gfar_write
(
&
priv
->
regs
->
fifo_tx_starve_shutoff
,
priv
->
fifo_starve_off
);
/* Start the controller */
gfar_start
(
dev
);
return
0
;
...
...
@@ -851,34 +871,32 @@ static int gfar_enet_open(struct net_device *dev)
return
err
;
}
static
struct
txfcb
*
gfar_add_fcb
(
struct
sk_buff
*
skb
,
struct
txbd8
*
bdp
)
static
inline
struct
txfcb
*
gfar_add_fcb
(
struct
sk_buff
*
skb
,
struct
txbd8
*
bdp
)
{
struct
txfcb
*
fcb
=
(
struct
txfcb
*
)
skb_push
(
skb
,
GMAC_FCB_LEN
);
memset
(
fcb
,
0
,
GMAC_FCB_LEN
);
/* Flag the bd so the controller looks for the FCB */
bdp
->
status
|=
TXBD_TOE
;
return
fcb
;
}
static
inline
void
gfar_tx_checksum
(
struct
sk_buff
*
skb
,
struct
txfcb
*
fcb
)
{
int
len
;
u8
flags
=
0
;
/* If we're here, it's a IP packet with a TCP or UDP
* payload. We set it to checksum, using a pseudo-header
* we provide
*/
fcb
->
ip
=
1
;
fcb
->
tup
=
1
;
fcb
->
ctu
=
1
;
fcb
->
nph
=
1
;
flags
=
TXFCB_DEFAULT
;
/* Notify the controller what the protocol is */
if
(
skb
->
nh
.
iph
->
protocol
==
IPPROTO_UDP
)
fcb
->
udp
=
1
;
/* Tell the controller what the protocol is */
/* And provide the already calculated phcs */
if
(
skb
->
nh
.
iph
->
protocol
==
IPPROTO_UDP
)
{
flags
|=
TXFCB_UDP
;
fcb
->
phcs
=
skb
->
h
.
uh
->
check
;
}
else
fcb
->
phcs
=
skb
->
h
.
th
->
check
;
/* l3os is the distance between the start of the
* frame (skb->data) and the start of the IP hdr.
...
...
@@ -887,17 +905,12 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
fcb
->
l3os
=
(
u16
)(
skb
->
nh
.
raw
-
skb
->
data
-
GMAC_FCB_LEN
);
fcb
->
l4os
=
(
u16
)(
skb
->
h
.
raw
-
skb
->
nh
.
raw
);
len
=
skb
->
nh
.
iph
->
tot_len
-
fcb
->
l4os
;
/* Provide the pseudoheader csum */
fcb
->
phcs
=
~
csum_tcpudp_magic
(
skb
->
nh
.
iph
->
saddr
,
skb
->
nh
.
iph
->
daddr
,
len
,
skb
->
nh
.
iph
->
protocol
,
0
);
fcb
->
flags
=
flags
;
}
void
gfar_tx_vlan
(
struct
sk_buff
*
skb
,
struct
txfcb
*
fcb
)
void
inline
gfar_tx_vlan
(
struct
sk_buff
*
skb
,
struct
txfcb
*
fcb
)
{
fcb
->
vln
=
1
;
fcb
->
flags
|=
TXFCB_VLN
;
fcb
->
vlctl
=
vlan_tx_tag_get
(
skb
);
}
...
...
@@ -908,6 +921,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct
gfar_private
*
priv
=
netdev_priv
(
dev
);
struct
txfcb
*
fcb
=
NULL
;
struct
txbd8
*
txbdp
;
u16
status
;
/* Update transmit stats */
priv
->
stats
.
tx_bytes
+=
skb
->
len
;
...
...
@@ -919,19 +933,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp
=
priv
->
cur_tx
;
/* Clear all but the WRAP status flags */
txbdp
->
status
&
=
TXBD_WRAP
;
status
=
txbdp
->
status
&
TXBD_WRAP
;
/* Set up checksumming */
if
((
dev
->
features
&
NETIF_F_IP_CSUM
)
&&
(
CHECKSUM_HW
==
skb
->
ip_summed
))
{
if
(
likely
((
dev
->
features
&
NETIF_F_IP_CSUM
)
&&
(
CHECKSUM_HW
==
skb
->
ip_summed
))
)
{
fcb
=
gfar_add_fcb
(
skb
,
txbdp
);
status
|=
TXBD_TOE
;
gfar_tx_checksum
(
skb
,
fcb
);
}
if
(
priv
->
vlan_enable
&&
unlikely
(
priv
->
vlgrp
&&
vlan_tx_tag_present
(
skb
)))
{
if
(
NULL
==
fcb
)
if
(
unlikely
(
NULL
==
fcb
)
)
{
fcb
=
gfar_add_fcb
(
skb
,
txbdp
);
status
|=
TXBD_TOE
;
}
gfar_tx_vlan
(
skb
,
fcb
);
}
...
...
@@ -949,14 +966,16 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
(
priv
->
skb_curtx
+
1
)
&
TX_RING_MOD_MASK
(
priv
->
tx_ring_size
);
/* Flag the BD as interrupt-causing */
txbdp
->
status
|=
TXBD_INTERRUPT
;
status
|=
TXBD_INTERRUPT
;
/* Flag the BD as ready to go, last in frame, and */
/* in need of CRC */
txbdp
->
status
|=
(
TXBD_READY
|
TXBD_LAST
|
TXBD_CRC
);
status
|=
(
TXBD_READY
|
TXBD_LAST
|
TXBD_CRC
);
dev
->
trans_start
=
jiffies
;
txbdp
->
status
=
status
;
/* If this was the last BD in the ring, the next one */
/* is at the beginning of the ring */
if
(
txbdp
->
status
&
TXBD_WRAP
)
...
...
@@ -1010,21 +1029,7 @@ static struct net_device_stats * gfar_get_stats(struct net_device *dev)
/* Changes the mac address if the controller is not running. */
int
gfar_set_mac_address
(
struct
net_device
*
dev
)
{
struct
gfar_private
*
priv
=
netdev_priv
(
dev
);
int
i
;
char
tmpbuf
[
MAC_ADDR_LEN
];
u32
tempval
;
/* Now copy it into the mac registers backwards, cuz */
/* little endian is silly */
for
(
i
=
0
;
i
<
MAC_ADDR_LEN
;
i
++
)
tmpbuf
[
MAC_ADDR_LEN
-
1
-
i
]
=
dev
->
dev_addr
[
i
];
gfar_write
(
&
priv
->
regs
->
macstnaddr1
,
*
((
u32
*
)
(
tmpbuf
)));
tempval
=
*
((
u32
*
)
(
tmpbuf
+
4
));
gfar_write
(
&
priv
->
regs
->
macstnaddr2
,
tempval
);
gfar_set_mac_for_addr
(
dev
,
0
,
dev
->
dev_addr
);
return
0
;
}
...
...
@@ -1110,7 +1115,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
INCREMENTAL_BUFFER_SIZE
;
/* Only stop and start the controller if it isn't already
* stopped */
* stopped
, and we changed something
*/
if
((
oldsize
!=
tempsize
)
&&
(
dev
->
flags
&
IFF_UP
))
stop_gfar
(
dev
);
...
...
@@ -1220,6 +1225,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs)
struct
sk_buff
*
gfar_new_skb
(
struct
net_device
*
dev
,
struct
rxbd8
*
bdp
)
{
unsigned
int
alignamount
;
struct
gfar_private
*
priv
=
netdev_priv
(
dev
);
struct
sk_buff
*
skb
=
NULL
;
unsigned
int
timeout
=
SKB_ALLOC_TIMEOUT
;
...
...
@@ -1231,18 +1237,18 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
if
(
NULL
==
skb
)
return
NULL
;
alignamount
=
RXBUF_ALIGNMENT
-
(((
unsigned
)
skb
->
data
)
&
(
RXBUF_ALIGNMENT
-
1
));
/* We need the data buffer to be aligned properly. We will reserve
* as many bytes as needed to align the data properly
*/
skb_reserve
(
skb
,
RXBUF_ALIGNMENT
-
(((
unsigned
)
skb
->
data
)
&
(
RXBUF_ALIGNMENT
-
1
)));
skb_reserve
(
skb
,
alignamount
);
skb
->
dev
=
dev
;
bdp
->
bufPtr
=
dma_map_single
(
NULL
,
skb
->
data
,
priv
->
rx_buffer_size
+
RXBUF_ALIGNMENT
,
DMA_FROM_DEVICE
);
priv
->
rx_buffer_size
,
DMA_FROM_DEVICE
);
bdp
->
length
=
0
;
...
...
@@ -1350,7 +1356,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
/* If valid headers were found, and valid sums
* were verified, then we tell the kernel that no
* checksumming is necessary. Otherwise, it is */
if
(
fcb
->
cip
&&
!
fcb
->
eip
&&
fcb
->
ctu
&&
!
fcb
->
etu
)
if
(
(
fcb
->
flags
&
RXFCB_CSUM_MASK
)
==
(
RXFCB_CIP
|
RXFCB_CTU
)
)
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
else
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -1401,7 +1407,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
/* Send the packet up the stack */
if
(
unlikely
(
priv
->
vlgrp
&&
fcb
->
vln
))
if
(
unlikely
(
priv
->
vlgrp
&&
(
fcb
->
flags
&
RXFCB_VLN
)
))
ret
=
gfar_rx_vlan
(
skb
,
priv
->
vlgrp
,
fcb
->
vlctl
);
else
ret
=
RECEIVE
(
skb
);
...
...
@@ -1620,6 +1626,7 @@ static void adjust_link(struct net_device *dev)
spin_lock_irqsave
(
&
priv
->
lock
,
flags
);
if
(
phydev
->
link
)
{
u32
tempval
=
gfar_read
(
&
regs
->
maccfg2
);
u32
ecntrl
=
gfar_read
(
&
regs
->
ecntrl
);
/* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */
...
...
@@ -1644,6 +1651,13 @@ static void adjust_link(struct net_device *dev)
case
10
:
tempval
=
((
tempval
&
~
(
MACCFG2_IF
))
|
MACCFG2_MII
);
/* Reduced mode distinguishes
* between 10 and 100 */
if
(
phydev
->
speed
==
SPEED_100
)
ecntrl
|=
ECNTRL_R100
;
else
ecntrl
&=
~
(
ECNTRL_R100
);
break
;
default:
if
(
netif_msg_link
(
priv
))
...
...
@@ -1657,6 +1671,7 @@ static void adjust_link(struct net_device *dev)
}
gfar_write
(
&
regs
->
maccfg2
,
tempval
);
gfar_write
(
&
regs
->
ecntrl
,
ecntrl
);
if
(
!
priv
->
oldlink
)
{
new_state
=
1
;
...
...
@@ -1721,6 +1736,9 @@ static void gfar_set_multi(struct net_device *dev)
gfar_write
(
&
regs
->
gaddr6
,
0xffffffff
);
gfar_write
(
&
regs
->
gaddr7
,
0xffffffff
);
}
else
{
int
em_num
;
int
idx
;
/* zero out the hash */
gfar_write
(
&
regs
->
igaddr0
,
0x0
);
gfar_write
(
&
regs
->
igaddr1
,
0x0
);
...
...
@@ -1739,18 +1757,47 @@ static void gfar_set_multi(struct net_device *dev)
gfar_write
(
&
regs
->
gaddr6
,
0x0
);
gfar_write
(
&
regs
->
gaddr7
,
0x0
);
/* If we have extended hash tables, we need to
* clear the exact match registers to prepare for
* setting them */
if
(
priv
->
extended_hash
)
{
em_num
=
GFAR_EM_NUM
+
1
;
gfar_clear_exact_match
(
dev
);
idx
=
1
;
}
else
{
idx
=
0
;
em_num
=
0
;
}
if
(
dev
->
mc_count
==
0
)
return
;
/* Parse the list, and set the appropriate bits */
for
(
mc_ptr
=
dev
->
mc_list
;
mc_ptr
;
mc_ptr
=
mc_ptr
->
next
)
{
gfar_set_hash_for_addr
(
dev
,
mc_ptr
->
dmi_addr
);
if
(
idx
<
em_num
)
{
gfar_set_mac_for_addr
(
dev
,
idx
,
mc_ptr
->
dmi_addr
);
idx
++
;
}
else
gfar_set_hash_for_addr
(
dev
,
mc_ptr
->
dmi_addr
);
}
}
return
;
}
/* Clears each of the exact match registers to zero, so they
* don't interfere with normal reception */
static
void
gfar_clear_exact_match
(
struct
net_device
*
dev
)
{
int
idx
;
u8
zero_arr
[
MAC_ADDR_LEN
]
=
{
0
,
0
,
0
,
0
,
0
,
0
};
for
(
idx
=
1
;
idx
<
GFAR_EM_NUM
+
1
;
idx
++
)
gfar_set_mac_for_addr
(
dev
,
idx
,
(
u8
*
)
zero_arr
);
}
/* Set the appropriate hash bit for the given addr */
/* The algorithm works like so:
* 1) Take the Destination Address (ie the multicast address), and
...
...
@@ -1781,6 +1828,32 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
return
;
}
/* There are multiple MAC Address register pairs on some controllers
* This function sets the numth pair to a given address
*/
static
void
gfar_set_mac_for_addr
(
struct
net_device
*
dev
,
int
num
,
u8
*
addr
)
{
struct
gfar_private
*
priv
=
netdev_priv
(
dev
);
int
idx
;
char
tmpbuf
[
MAC_ADDR_LEN
];
u32
tempval
;
u32
*
macptr
=
&
priv
->
regs
->
macstnaddr1
;
macptr
+=
num
*
2
;
/* Now copy it into the mac registers backwards, cuz */
/* little endian is silly */
for
(
idx
=
0
;
idx
<
MAC_ADDR_LEN
;
idx
++
)
tmpbuf
[
MAC_ADDR_LEN
-
1
-
idx
]
=
addr
[
idx
];
gfar_write
(
macptr
,
*
((
u32
*
)
(
tmpbuf
)));
tempval
=
*
((
u32
*
)
(
tmpbuf
+
4
));
gfar_write
(
macptr
+
1
,
tempval
);
}
/* GFAR error interrupt handler */
static
irqreturn_t
gfar_error
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
Next
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