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
81c830a4
Commit
81c830a4
authored
May 25, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/jgarzik/net-drivers-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
01166d96
cd8286cf
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1461 additions
and
308 deletions
+1461
-308
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/arcnet.c
+3
-2
drivers/net/e100/e100.h
drivers/net/e100/e100.h
+18
-12
drivers/net/e100/e100_main.c
drivers/net/e100/e100_main.c
+253
-89
drivers/net/e100/e100_phy.c
drivers/net/e100/e100_phy.c
+5
-2
drivers/net/e100/e100_test.c
drivers/net/e100/e100_test.c
+110
-45
drivers/net/e1000/Makefile
drivers/net/e1000/Makefile
+1
-1
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000.h
+4
-1
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_ethtool.c
+934
-25
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.c
+13
-10
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_hw.h
+5
-3
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_main.c
+62
-83
drivers/net/fc/iph5526.c
drivers/net/fc/iph5526.c
+10
-8
drivers/net/fec.c
drivers/net/fec.c
+13
-5
drivers/net/fmv18x.c
drivers/net/fmv18x.c
+3
-3
drivers/net/hamradio/scc.c
drivers/net/hamradio/scc.c
+4
-3
drivers/net/myri_sbus.c
drivers/net/myri_sbus.c
+3
-1
drivers/net/ppp_synctty.c
drivers/net/ppp_synctty.c
+1
-3
drivers/net/seeq8005.c
drivers/net/seeq8005.c
+7
-2
drivers/net/sunqe.c
drivers/net/sunqe.c
+1
-0
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/lanstreamer.c
+3
-2
drivers/net/tulip/de4x5.c
drivers/net/tulip/de4x5.c
+1
-1
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/lmc/lmc_main.c
+6
-2
drivers/net/wireless/airport.c
drivers/net/wireless/airport.c
+0
-4
include/linux/arcdevice.h
include/linux/arcdevice.h
+1
-1
No files found.
drivers/net/arcnet/arcnet.c
View file @
81c830a4
...
...
@@ -671,7 +671,7 @@ static void arcnet_timeout(struct net_device *dev)
* interrupts. Establish which device needs attention, and call the correct
* chipset interrupt handler.
*/
void
arcnet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
irqreturn_t
arcnet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
struct
arcnet_local
*
lp
;
...
...
@@ -696,7 +696,7 @@ void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ACOMMAND
(
CFLAGScmd
|
RESETclear
);
AINTMASK
(
0
);
spin_unlock
(
&
arcnet_lock
);
return
;
return
IRQ_HANDLED
;
}
BUGMSG
(
D_DURING
,
"in arcnet_inthandler (status=%Xh, intmask=%Xh)
\n
"
,
...
...
@@ -864,6 +864,7 @@ void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
AINTMASK
(
lp
->
intmask
);
spin_unlock
(
&
arcnet_lock
);
return
IRQ_RETVAL
(
didsomething
);
}
...
...
drivers/net/e100/e100.h
View file @
81c830a4
...
...
@@ -60,7 +60,14 @@
#include <linux/if_vlan.h>
#include <linux/mii.h>
#define E100_REGS_LEN 1
#define E100_CABLE_UNKNOWN 0
#define E100_CABLE_OK 1
#define E100_CABLE_OPEN_NEAR 2
/* Open Circuit Near End */
#define E100_CABLE_OPEN_FAR 3
/* Open Circuit Far End */
#define E100_CABLE_SHORT_NEAR 4
/* Short Circuit Near End */
#define E100_CABLE_SHORT_FAR 5
/* Short Circuit Far End */
#define E100_REGS_LEN 2
/*
* Configure parameters for buffers per controller.
* If the machine this is being used on is a faster machine (i.e. > 150MHz)
...
...
@@ -105,8 +112,6 @@
#define E100_MAX_CU_IDLE_WAIT 50
/* Max udelays in wait_cus_idle */
/* HWI feature related constant */
#define HWI_MAX_LOOP 100
#define MAX_SAME_RESULTS 3
#define HWI_REGISTER_GRANULARITY 80
/* register granularity = 80 Cm */
#define HWI_NEAR_END_BOUNDARY 1000
/* Near end is defined as < 10 meters */
...
...
@@ -942,7 +947,6 @@ struct e100_private {
#ifdef CONFIG_PM
u32
pci_state
[
16
];
#endif
char
ifname
[
IFNAMSIZ
];
#ifdef E100_CU_DEBUG
u8
last_cmd
;
u8
last_sub_cmd
;
...
...
@@ -956,7 +960,10 @@ struct e100_private {
#define E100_SPEED_100_FULL 4
/********* function prototypes *************/
extern
int
e100_open
(
struct
net_device
*
);
extern
int
e100_close
(
struct
net_device
*
);
extern
void
e100_isolate_driver
(
struct
e100_private
*
bdp
);
extern
unsigned
char
e100_hw_init
(
struct
e100_private
*
);
extern
void
e100_sw_reset
(
struct
e100_private
*
bdp
,
u32
reset_cmd
);
extern
u8
e100_start_cu
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
);
extern
void
e100_free_non_tx_cmd
(
struct
e100_private
*
bdp
,
...
...
@@ -981,14 +988,13 @@ extern unsigned char e100_cu_unknown_state(struct e100_private *bdp);
#define TEST_TIMEOUT 0x08
enum
test_offsets
{
E100_EEPROM_TEST_FAIL
=
0
,
E100_CHIP_TIMEOUT
,
E100_ROM_TEST_FAIL
,
E100_REG_TEST_FAIL
,
E100_MAC_TEST_FAIL
,
E100_LPBK_MAC_FAIL
,
E100_LPBK_PHY_FAIL
,
E100_MAX_TEST_RES
test_link
,
test_eeprom
,
test_self_test
,
test_loopback_mac
,
test_loopback_phy
,
cable_diag
,
max_test_res
,
/* must be last */
};
#endif
drivers/net/e100/e100_main.c
View file @
81c830a4
...
...
@@ -45,6 +45,24 @@
**********************************************************************/
/* Change Log
*
* 2.3.13 05/08/03
* o Feature remove: /proc/net/PRO_LAN_Adapters support gone completely
* o Feature remove: IDIAG support (use ethtool -t instead)
* o Cleanup: fixed spelling mistakes found by community
* o Feature add: ethtool cable diag test
* o Feature add: ethtool parameter support (ring size, xsum, flow ctrl)
* o Cleanup: move e100_asf_enable under CONFIG_PM to avoid warning
* [Stephen Rothwell (sfr@canb.auug.org.au)]
* o Bug fix: don't call any netif_carrier_* until netdev registered.
* [Andrew Morton (akpm@digeo.com)]
* o Cleanup: replace (skb->len - skb->data_len) with skb_headlen(skb)
* [jmorris@intercode.com.au]
* o Bug fix: cleanup of Tx skbs after running ethtool diags
* o Bug fix: incorrect reporting of ethtool diag overall results
* o Bug fix: must hold xmit_lock before stopping queue in ethtool
* operations that require reset h/w and driver structures.
* o Bug fix: statistic command failure would stop statistic collection.
*
* 2.2.21 02/11/03
* o Removed marketing brand strings. Instead, Using generic string
...
...
@@ -61,21 +79,6 @@
* o New feature: added ICH5 support
*
* 2.1.27 11/20/02
* o Bug fix: Device command timeout due to SMBus processing during init
* o Bug fix: Not setting/clearing I (Interrupt) bit in tcb correctly
* o Bug fix: Not using EEPROM WoL setting as default in ethtool
* o Bug fix: Not able to set autoneg on using ethtool when interface down
* o Bug fix: Not able to change speed/duplex using ethtool/mii
* when interface up
* o Bug fix: Ethtool shows autoneg on when forced to 100/Full
* o Bug fix: Compiler error when CONFIG_PROC_FS not defined
* o Bug fix: 2.5.44 e100 doesn't load with preemptive kernel enabled
* (sleep while holding spinlock)
* o Bug fix: 2.1.24-k1 doesn't display complete statistics
* o Bug fix: System panic due to NULL watchdog timer dereference during
* ifconfig down, rmmod and insmod
*
* 2.1.24 10/7/02
*/
#include <linux/config.h>
...
...
@@ -121,14 +124,13 @@ extern void e100_config_wol(struct e100_private *bdp);
extern
u32
e100_run_diag
(
struct
net_device
*
dev
,
u64
*
test_info
,
u32
flags
);
static
int
e100_ethtool_test
(
struct
net_device
*
,
struct
ifreq
*
);
static
int
e100_ethtool_gstrings
(
struct
net_device
*
,
struct
ifreq
*
);
static
char
*
test_strings
[]
=
{
"E100_EEPROM_TEST_FAIL"
,
"E100_CHIP_TIMEOUT"
,
"E100_ROM_TEST_FAIL"
,
"E100_REG_TEST_FAIL"
,
"E100_MAC_TEST_FAIL"
,
"E100_LPBK_MAC_FAIL"
,
"E100_LPBK_PHY_FAIL"
static
char
test_strings
[][
ETH_GSTRING_LEN
]
=
{
"Link test (on/offline)"
,
"Eeprom test (on/offline)"
,
"Self test (offline)"
,
"Mac loopback (offline)"
,
"Phy loopback (offline)"
,
"Cable diagnostic (offline)"
};
static
int
e100_ethtool_led_blink
(
struct
net_device
*
,
struct
ifreq
*
);
...
...
@@ -139,10 +141,10 @@ static unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,
nxmit_cb_entry_t
*
);
static
void
e100_free_nontx_list
(
struct
e100_private
*
);
static
void
e100_non_tx_background
(
unsigned
long
);
static
inline
void
e100_tx_skb_free
(
struct
e100_private
*
bdp
,
tcb_t
*
tcb
);
/* Global Data structures and variables */
char
e100_copyright
[]
__devinitdata
=
"Copyright (c) 2003 Intel Corporation"
;
char
e100_driver_version
[]
=
"2.
2.21
-k1"
;
char
e100_driver_version
[]
=
"2.
3.13
-k1"
;
const
char
*
e100_full_driver_name
=
"Intel(R) PRO/100 Network Driver"
;
char
e100_short_driver_name
[]
=
"e100"
;
static
int
e100nics
=
0
;
...
...
@@ -155,6 +157,7 @@ static void e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
static
int
e100_notify_reboot
(
struct
notifier_block
*
,
unsigned
long
event
,
void
*
ptr
);
static
int
e100_suspend
(
struct
pci_dev
*
pcid
,
u32
state
);
static
int
e100_resume
(
struct
pci_dev
*
pcid
);
static
unsigned
char
e100_asf_enabled
(
struct
e100_private
*
bdp
);
struct
notifier_block
e100_notifier_reboot
=
{
.
notifier_call
=
e100_notify_reboot
,
.
next
=
NULL
,
...
...
@@ -182,8 +185,6 @@ struct notifier_block e100_notifier_reboot = {
static
u8
e100_D101M_checksum
(
struct
e100_private
*
,
struct
sk_buff
*
);
static
u8
e100_D102_check_checksum
(
rfd_t
*
);
static
int
e100_ioctl
(
struct
net_device
*
,
struct
ifreq
*
,
int
);
static
int
e100_open
(
struct
net_device
*
);
static
int
e100_close
(
struct
net_device
*
);
static
int
e100_change_mtu
(
struct
net_device
*
,
int
);
static
int
e100_xmit_frame
(
struct
sk_buff
*
,
struct
net_device
*
);
static
unsigned
char
e100_init
(
struct
e100_private
*
);
...
...
@@ -193,7 +194,6 @@ struct net_device_stats *e100_get_stats(struct net_device *);
static
irqreturn_t
e100intr
(
int
,
void
*
,
struct
pt_regs
*
);
static
void
e100_print_brd_conf
(
struct
e100_private
*
);
static
void
e100_set_multi
(
struct
net_device
*
);
void
e100_set_speed_duplex
(
struct
e100_private
*
);
static
u8
e100_pci_setup
(
struct
pci_dev
*
,
struct
e100_private
*
);
static
u8
e100_sw_init
(
struct
e100_private
*
);
...
...
@@ -215,7 +215,6 @@ u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
static
unsigned
char
e100_clr_cntrs
(
struct
e100_private
*
);
static
unsigned
char
e100_load_microcode
(
struct
e100_private
*
);
static
unsigned
char
e100_hw_init
(
struct
e100_private
*
);
static
unsigned
char
e100_setup_iaaddr
(
struct
e100_private
*
,
u8
*
);
static
unsigned
char
e100_update_stats
(
struct
e100_private
*
bdp
);
...
...
@@ -228,7 +227,6 @@ static void e100_set_bool_option(struct e100_private *bdp, int, u32, int,
char
*
);
unsigned
char
e100_wait_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
,
u8
);
void
e100_exec_cmplx
(
struct
e100_private
*
,
u32
,
u8
);
static
unsigned
char
e100_asf_enabled
(
struct
e100_private
*
bdp
);
/**
* e100_get_rx_struct - retrieve cell to hold skb buff from the pool
...
...
@@ -616,6 +614,10 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
goto
err_dealloc
;
}
if
((
rc
=
register_netdev
(
dev
))
!=
0
)
{
goto
err_pci
;
}
if
(((
bdp
->
pdev
->
device
>
0x1030
)
&&
(
bdp
->
pdev
->
device
<
0x103F
))
||
((
bdp
->
pdev
->
device
>=
0x1050
)
...
...
@@ -645,7 +647,7 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
printk
(
KERN_ERR
"e100: Failed to initialize, instance #%d
\n
"
,
e100nics
);
rc
=
-
ENODEV
;
goto
err_
pci
;
goto
err_
unregister_netdev
;
}
/* Check if checksum is valid */
...
...
@@ -655,7 +657,7 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
printk
(
KERN_ERR
"e100: Corrupted EEPROM on instance #%d
\n
"
,
e100nics
);
rc
=
-
ENODEV
;
goto
err_
pci
;
goto
err_
unregister_netdev
;
}
dev
->
vlan_rx_register
=
e100_vlan_rx_register
;
...
...
@@ -679,12 +681,6 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
e100_get_speed_duplex_caps
(
bdp
);
if
((
rc
=
register_netdev
(
dev
))
!=
0
)
{
goto
err_pci
;
}
memcpy
(
bdp
->
ifname
,
dev
->
name
,
IFNAMSIZ
);
bdp
->
ifname
[
IFNAMSIZ
-
1
]
=
0
;
printk
(
KERN_NOTICE
"e100: %s: %s
\n
"
,
bdp
->
device
->
name
,
"Intel(R) PRO/100 Network Connection"
);
...
...
@@ -709,6 +705,8 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
goto
out
;
err_unregister_netdev:
unregister_netdev
(
dev
);
err_pci:
iounmap
(
bdp
->
scb
);
pci_release_regions
(
pcid
);
...
...
@@ -974,7 +972,7 @@ e100_set_bool_option(struct e100_private *bdp, int val, u32 mask,
}
}
static
int
int
e100_open
(
struct
net_device
*
dev
)
{
struct
e100_private
*
bdp
;
...
...
@@ -1012,7 +1010,11 @@ e100_open(struct net_device *dev)
mod_timer
(
&
(
bdp
->
watchdog_timer
),
jiffies
+
(
2
*
HZ
));
netif_start_queue
(
dev
);
if
(
dev
->
flags
&
IFF_UP
)
/* Otherwise process may sleep forever */
netif_wake_queue
(
dev
);
else
netif_start_queue
(
dev
);
e100_start_ru
(
bdp
);
if
((
rc
=
request_irq
(
dev
->
irq
,
&
e100intr
,
SA_SHIRQ
,
...
...
@@ -1033,7 +1035,7 @@ e100_open(struct net_device *dev)
return
rc
;
}
static
int
int
e100_close
(
struct
net_device
*
dev
)
{
struct
e100_private
*
bdp
=
dev
->
priv
;
...
...
@@ -1074,7 +1076,8 @@ e100_xmit_frame(struct sk_buff *skb, struct net_device *dev)
goto
exit2
;
}
if
(
!
TCBS_AVAIL
(
bdp
->
tcb_pool
)
||
/* tcb list may be empty temporarily during releasing resources */
if
(
!
TCBS_AVAIL
(
bdp
->
tcb_pool
)
||
(
bdp
->
tcb_phys
==
0
)
||
(
bdp
->
non_tx_command_state
!=
E100_NON_TX_IDLE
))
{
notify_stop
=
true
;
rc
=
1
;
...
...
@@ -1285,10 +1288,8 @@ e100_init(struct e100_private *bdp)
/* read NIC's part number */
e100_rd_pwa_no
(
bdp
);
if
(
!
e100_hw_init
(
bdp
))
{
printk
(
KERN_ERR
"e100: hw init failed
\n
"
);
if
(
!
e100_hw_init
(
bdp
))
return
false
;
}
/* Interrupts are enabled after device reset */
e100_disable_clear_intr
(
bdp
);
...
...
@@ -1330,6 +1331,8 @@ e100_sw_init(struct e100_private *bdp)
spin_lock_init
(
&
(
bdp
->
bd_non_tx_lock
));
spin_lock_init
(
&
(
bdp
->
config_lock
));
spin_lock_init
(
&
(
bdp
->
mdi_access_lock
));
/* Initialize configuration data */
e100_config_init
(
bdp
);
return
1
;
}
...
...
@@ -1384,11 +1387,11 @@ e100_tco_workaround(struct e100_private *bdp)
* true - If the adapter was initialized
* false - If the adapter failed initialization
*/
unsigned
char
__devinit
unsigned
char
e100_hw_init
(
struct
e100_private
*
bdp
)
{
if
(
!
e100_phy_init
(
bdp
))
return
false
;
goto
err
;
e100_sw_reset
(
bdp
,
PORT_SELECTIVE_RESET
);
...
...
@@ -1398,27 +1401,25 @@ e100_hw_init(struct e100_private *bdp)
/* Load the CU BASE (set to 0, because we use linear mode) */
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
,
0
))
return
false
;
goto
err
;
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
,
0
))
return
false
;
goto
err
;
/* Load interrupt microcode */
if
(
e100_load_microcode
(
bdp
))
{
bdp
->
flags
|=
DF_UCODE_LOADED
;
}
e100_config_init
(
bdp
);
if
(
!
e100_config
(
bdp
))
{
return
false
;
}
if
(
!
e100_config
(
bdp
))
goto
err
;
if
(
!
e100_setup_iaaddr
(
bdp
,
bdp
->
device
->
dev_addr
))
return
false
;
goto
err
;
/* Clear the internal counters */
if
(
!
e100_clr_cntrs
(
bdp
))
return
false
;
goto
err
;
/* Change for 82558 enhancement */
/* If 82558/9 and if the user has enabled flow control, set up the
...
...
@@ -1431,6 +1432,9 @@ e100_hw_init(struct e100_private *bdp)
}
return
true
;
err:
printk
(
KERN_ERR
"e100: hw init failed
\n
"
);
return
false
;
}
/**
...
...
@@ -1591,9 +1595,22 @@ e100_alloc_tcb_pool(struct e100_private *bdp)
void
e100_free_tcb_pool
(
struct
e100_private
*
bdp
)
{
tcb_t
*
tcb
;
int
i
;
/* Return tx skbs */
for
(
i
=
0
;
i
<
bdp
->
params
.
TxDescriptors
;
i
++
)
{
tcb
=
bdp
->
tcb_pool
.
data
;
tcb
+=
bdp
->
tcb_pool
.
head
;
e100_tx_skb_free
(
bdp
,
tcb
);
if
(
NEXT_TCB_TOUSE
(
bdp
->
tcb_pool
.
head
)
==
bdp
->
tcb_pool
.
tail
)
break
;
bdp
->
tcb_pool
.
head
=
NEXT_TCB_TOUSE
(
bdp
->
tcb_pool
.
head
);
}
pci_free_consistent
(
bdp
->
pdev
,
sizeof
(
tcb_t
)
*
bdp
->
params
.
TxDescriptors
,
bdp
->
tcb_pool
.
data
,
bdp
->
tcb_phys
);
bdp
->
tcb_pool
.
head
=
0
;
bdp
->
tcb_pool
.
tail
=
1
;
bdp
->
tcb_phys
=
0
;
}
...
...
@@ -1747,12 +1764,10 @@ e100_watchdog(struct net_device *dev)
e100_set_multi
(
dev
);
}
}
/* Update the statistics needed by the upper interface */
/* This should be the last statistic related command
* as it's async. now */
e100_dump_stats_cntrs
(
bdp
);
}
/* Issue command to dump statistics from device. */
/* Check for command completion on next watchdog timer. */
e100_dump_stats_cntrs
(
bdp
);
wmb
();
...
...
@@ -2544,6 +2559,7 @@ e100_update_stats(struct e100_private *bdp)
pcmd_complete
=
e100_cmd_complete_location
(
bdp
);
if
(
*
pcmd_complete
!=
le32_to_cpu
(
DUMP_RST_STAT_COMPLETED
)
&&
*
pcmd_complete
!=
le32_to_cpu
(
DUMP_STAT_COMPLETED
))
{
*
pcmd_complete
=
0
;
return
false
;
}
...
...
@@ -3041,23 +3057,6 @@ e100_isolate_driver(struct e100_private *bdp)
e100_sw_reset
(
bdp
,
PORT_SELECTIVE_RESET
);
}
void
e100_set_speed_duplex
(
struct
e100_private
*
bdp
)
{
int
carrier_ok
;
/* Device may lose link with some siwtches when */
/* changing speed/duplex to non-autoneg. e100 */
/* needs to remember carrier state in order to */
/* start watchdog timer for recovering link */
if
((
carrier_ok
=
netif_carrier_ok
(
bdp
->
device
)))
e100_isolate_driver
(
bdp
);
e100_phy_set_speed_duplex
(
bdp
,
true
);
e100_config_fc
(
bdp
);
/* re-config flow-control if necessary */
e100_config
(
bdp
);
if
(
carrier_ok
)
e100_deisolate_driver
(
bdp
,
false
);
}
static
void
e100_tcb_add_C_bit
(
struct
e100_private
*
bdp
)
{
...
...
@@ -3213,6 +3212,144 @@ e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
case
ETHTOOL_PHYS_ID
:
rc
=
e100_ethtool_led_blink
(
dev
,
ifr
);
break
;
#ifdef ETHTOOL_GRINGPARAM
case
ETHTOOL_GRINGPARAM
:
{
struct
ethtool_ringparam
ering
;
struct
e100_private
*
bdp
=
dev
->
priv
;
memset
((
void
*
)
&
ering
,
0
,
sizeof
(
ering
));
ering
.
rx_max_pending
=
E100_MAX_RFD
;
ering
.
tx_max_pending
=
E100_MAX_TCB
;
ering
.
rx_pending
=
bdp
->
params
.
RxDescriptors
;
ering
.
tx_pending
=
bdp
->
params
.
TxDescriptors
;
rc
=
copy_to_user
(
ifr
->
ifr_data
,
&
ering
,
sizeof
(
ering
))
?
-
EFAULT
:
0
;
return
rc
;
}
#endif
#ifdef ETHTOOL_SRINGPARAM
case
ETHTOOL_SRINGPARAM
:
{
struct
ethtool_ringparam
ering
;
struct
e100_private
*
bdp
=
dev
->
priv
;
if
(
copy_from_user
(
&
ering
,
ifr
->
ifr_data
,
sizeof
(
ering
)))
return
-
EFAULT
;
if
(
ering
.
rx_pending
>
E100_MAX_RFD
||
ering
.
rx_pending
<
E100_MIN_RFD
)
return
-
EINVAL
;
if
(
ering
.
tx_pending
>
E100_MAX_TCB
||
ering
.
tx_pending
<
E100_MIN_TCB
)
return
-
EINVAL
;
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
/* Use new values to open interface */
bdp
->
params
.
RxDescriptors
=
ering
.
rx_pending
;
bdp
->
params
.
TxDescriptors
=
ering
.
tx_pending
;
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
else
{
bdp
->
params
.
RxDescriptors
=
ering
.
rx_pending
;
bdp
->
params
.
TxDescriptors
=
ering
.
tx_pending
;
}
return
0
;
}
#endif
#ifdef ETHTOOL_GPAUSEPARAM
case
ETHTOOL_GPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
;
struct
e100_private
*
bdp
=
dev
->
priv
;
memset
((
void
*
)
&
epause
,
0
,
sizeof
(
epause
));
if
((
bdp
->
flags
&
IS_BACHELOR
)
&&
(
bdp
->
params
.
b_params
&
PRM_FC
))
{
epause
.
autoneg
=
1
;
if
(
bdp
->
flags
&&
DF_LINK_FC_CAP
)
{
epause
.
rx_pause
=
1
;
epause
.
tx_pause
=
1
;
}
if
(
bdp
->
flags
&&
DF_LINK_FC_TX_ONLY
)
epause
.
tx_pause
=
1
;
}
rc
=
copy_to_user
(
ifr
->
ifr_data
,
&
epause
,
sizeof
(
epause
))
?
-
EFAULT
:
0
;
return
rc
;
}
#endif
#ifdef ETHTOOL_SPAUSEPARAM
case
ETHTOOL_SPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
;
struct
e100_private
*
bdp
=
dev
->
priv
;
if
(
!
(
bdp
->
flags
&
IS_BACHELOR
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
epause
,
ifr
->
ifr_data
,
sizeof
(
epause
)))
return
-
EFAULT
;
if
(
epause
.
autoneg
==
1
)
bdp
->
params
.
b_params
|=
PRM_FC
;
else
bdp
->
params
.
b_params
&=
~
PRM_FC
;
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
return
0
;
}
#endif
#ifdef ETHTOOL_GRXCSUM
case
ETHTOOL_GRXCSUM
:
case
ETHTOOL_GTXCSUM
:
case
ETHTOOL_GSG
:
{
struct
ethtool_value
eval
;
struct
e100_private
*
bdp
=
dev
->
priv
;
memset
((
void
*
)
&
eval
,
0
,
sizeof
(
eval
));
if
((
ecmd
.
cmd
==
ETHTOOL_GRXCSUM
)
&&
(
bdp
->
params
.
b_params
&
PRM_XSUMRX
))
eval
.
data
=
1
;
else
eval
.
data
=
0
;
rc
=
copy_to_user
(
ifr
->
ifr_data
,
&
eval
,
sizeof
(
eval
))
?
-
EFAULT
:
0
;
return
rc
;
}
#endif
#ifdef ETHTOOL_SRXCSUM
case
ETHTOOL_SRXCSUM
:
case
ETHTOOL_STXCSUM
:
case
ETHTOOL_SSG
:
{
struct
ethtool_value
eval
;
struct
e100_private
*
bdp
=
dev
->
priv
;
if
(
copy_from_user
(
&
eval
,
ifr
->
ifr_data
,
sizeof
(
eval
)))
return
-
EFAULT
;
if
(
ecmd
.
cmd
==
ETHTOOL_SRXCSUM
)
{
if
(
eval
.
data
==
1
)
{
if
(
bdp
->
rev_id
>=
D101MA_REV_ID
)
bdp
->
params
.
b_params
|=
PRM_XSUMRX
;
else
return
-
EINVAL
;
}
else
{
if
(
bdp
->
rev_id
>=
D101MA_REV_ID
)
bdp
->
params
.
b_params
&=
~
PRM_XSUMRX
;
else
return
0
;
}
}
else
{
if
(
eval
.
data
==
1
)
return
-
EINVAL
;
else
return
0
;
}
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
return
0
;
}
#endif
default:
break
;
}
//switch
...
...
@@ -3298,7 +3435,13 @@ e100_ethtool_set_settings(struct net_device *dev, struct ifreq *ifr)
if
((
ecmd
.
autoneg
==
AUTONEG_ENABLE
)
&&
(
bdp
->
speed_duplex_caps
&
SUPPORTED_Autoneg
))
{
bdp
->
params
.
e100_speed_duplex
=
E100_AUTONEG
;
e100_set_speed_duplex
(
bdp
);
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
}
else
{
if
(
ecmd
.
speed
==
SPEED_10
)
{
if
(
ecmd
.
duplex
==
DUPLEX_HALF
)
{
...
...
@@ -3329,7 +3472,13 @@ e100_ethtool_set_settings(struct net_device *dev, struct ifreq *ifr)
if
(
bdp
->
speed_duplex_caps
&
ethtool_new_speed_duplex
)
{
bdp
->
params
.
e100_speed_duplex
=
e100_new_speed_duplex
;
e100_set_speed_duplex
(
bdp
);
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
}
else
{
return
-
EOPNOTSUPP
;
}
...
...
@@ -3364,14 +3513,14 @@ e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
struct
ethtool_test
*
info
;
int
rc
=
-
EFAULT
;
info
=
kmalloc
(
sizeof
(
*
info
)
+
E100_MAX_TEST_RES
*
sizeof
(
u64
),
info
=
kmalloc
(
sizeof
(
*
info
)
+
max_test_res
*
sizeof
(
u64
),
GFP_ATOMIC
);
if
(
!
info
)
return
-
ENOMEM
;
memset
((
void
*
)
info
,
0
,
sizeof
(
*
info
)
+
E100_MAX_TEST_RES
*
sizeof
(
u64
));
max_test_res
*
sizeof
(
u64
));
if
(
copy_from_user
(
info
,
ifr
->
ifr_data
,
sizeof
(
*
info
)))
goto
exit
;
...
...
@@ -3379,7 +3528,7 @@ e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
info
->
flags
=
e100_run_diag
(
dev
,
info
->
data
,
info
->
flags
);
if
(
!
copy_to_user
(
ifr
->
ifr_data
,
info
,
sizeof
(
*
info
)
+
E100_MAX_TEST_RES
*
sizeof
(
u64
)))
sizeof
(
*
info
)
+
max_test_res
*
sizeof
(
u64
)))
rc
=
0
;
exit:
kfree
(
info
);
...
...
@@ -3393,6 +3542,7 @@ e100_ethtool_gregs(struct net_device *dev, struct ifreq *ifr)
u32
regs_buff
[
E100_REGS_LEN
];
struct
ethtool_regs
regs
=
{
ETHTOOL_GREGS
};
void
*
addr
=
ifr
->
ifr_data
;
u16
mdi_reg
;
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
...
...
@@ -3405,6 +3555,8 @@ e100_ethtool_gregs(struct net_device *dev, struct ifreq *ifr)
regs_buff
[
0
]
=
readb
(
&
(
bdp
->
scb
->
scb_cmd_hi
))
<<
24
|
readb
(
&
(
bdp
->
scb
->
scb_cmd_low
))
<<
16
|
readw
(
&
(
bdp
->
scb
->
scb_status
));
e100_mdi_read
(
bdp
,
MII_NCONFIG
,
bdp
->
phy_addr
,
&
mdi_reg
);
regs_buff
[
1
]
=
mdi_reg
;
if
(
copy_to_user
(
addr
,
&
regs
,
sizeof
(
regs
)))
return
-
EFAULT
;
...
...
@@ -3428,7 +3580,13 @@ e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
if
((
bdp
->
speed_duplex_caps
&
SUPPORTED_Autoneg
)
&&
(
bdp
->
params
.
e100_speed_duplex
==
E100_AUTONEG
))
{
e100_set_speed_duplex
(
bdp
);
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
}
else
{
return
-
EFAULT
;
}
...
...
@@ -3454,7 +3612,7 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
info
.
n_stats
=
E100_STATS_LEN
;
info
.
regdump_len
=
E100_REGS_LEN
*
sizeof
(
u32
);
info
.
eedump_len
=
(
bdp
->
eeprom_size
<<
1
);
info
.
testinfo_len
=
E100_MAX_TEST_RES
;
info
.
testinfo_len
=
max_test_res
;
if
(
copy_to_user
(
ifr
->
ifr_data
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
...
...
@@ -3804,15 +3962,15 @@ static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
switch
(
info
.
string_set
)
{
case
ETH_SS_TEST
:
{
int
ret
=
0
;
if
(
info
.
len
>
E100_MAX_TEST_RES
)
info
.
len
=
E100_MAX_TEST_RES
;
if
(
info
.
len
>
max_test_res
)
info
.
len
=
max_test_res
;
strings
=
kmalloc
(
info
.
len
*
ETH_GSTRING_LEN
,
GFP_ATOMIC
);
if
(
!
strings
)
return
-
ENOMEM
;
memset
(
strings
,
0
,
info
.
len
*
ETH_GSTRING_LEN
);
for
(
i
=
0
;
i
<
info
.
len
;
i
++
)
{
sprintf
(
strings
+
i
*
ETH_GSTRING_LEN
,
"%
-31
s"
,
sprintf
(
strings
+
i
*
ETH_GSTRING_LEN
,
"%s"
,
test_strings
[
i
]);
}
if
(
copy_to_user
(
ifr
->
ifr_data
,
&
info
,
sizeof
(
info
)))
...
...
@@ -3881,7 +4039,13 @@ e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
bdp
->
params
.
e100_speed_duplex
=
E100_SPEED_10_FULL
;
else
bdp
->
params
.
e100_speed_duplex
=
E100_SPEED_10_HALF
;
e100_set_speed_duplex
(
bdp
);
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
e100_hw_init
(
bdp
);
e100_open
(
dev
);
}
}
else
/* Only allows changing speed/duplex */
...
...
@@ -4164,7 +4328,6 @@ e100_resume(struct pci_dev *pcid)
return
0
;
}
#endif
/* CONFIG_PM */
/**
* e100_asf_enabled - checks if ASF is configured on the current adaper
...
...
@@ -4190,6 +4353,7 @@ e100_asf_enabled(struct e100_private *bdp)
}
return
false
;
}
#endif
/* CONFIG_PM */
#ifdef E100_CU_DEBUG
unsigned
char
...
...
drivers/net/e100/e100_phy.c
View file @
81c830a4
...
...
@@ -628,8 +628,6 @@ e100_force_speed_duplex(struct e100_private *bdp)
u16
control
;
unsigned
long
expires
;
e100_phy_reset
(
bdp
);
bdp
->
flags
|=
DF_SPEED_FORCED
;
e100_mdi_read
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
&
control
);
...
...
@@ -912,6 +910,10 @@ e100_phy_reset(struct e100_private *bdp)
u16
ctrl_reg
;
ctrl_reg
=
BMCR_RESET
;
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
ctrl_reg
);
/* ieee 802.3 : The reset process shall be completed */
/* within 0.5 seconds from the settting of PHY reset bit. */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
2
);
}
unsigned
char
__devinit
...
...
@@ -928,6 +930,7 @@ e100_phy_init(struct e100_private *bdp)
bdp
->
PhyDelay
=
0
;
bdp
->
zlock_state
=
ZLOCK_INITIAL
;
e100_phy_reset
(
bdp
);
e100_phy_set_speed_duplex
(
bdp
,
false
);
e100_fix_polarity
(
bdp
);
...
...
drivers/net/e100/e100_test.c
View file @
81c830a4
...
...
@@ -25,7 +25,7 @@
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include "e100.h"
#include "e100
_phy
.h"
#include "e100_config.h"
extern
u16
e100_eeprom_read
(
struct
e100_private
*
,
u16
);
...
...
@@ -46,6 +46,7 @@ static u8 e100_diag_loopback_alloc(struct e100_private *);
static
void
e100_diag_loopback_cu_ru_exec
(
struct
e100_private
*
);
static
u8
e100_diag_check_pkt
(
u8
*
);
static
void
e100_diag_loopback_free
(
struct
e100_private
*
);
static
int
e100_cable_diag
(
struct
e100_private
*
bdp
);
#define LB_PACKET_SIZE 1500
...
...
@@ -60,46 +61,52 @@ u32
e100_run_diag
(
struct
net_device
*
dev
,
u64
*
test_info
,
u32
flags
)
{
struct
e100_private
*
bdp
=
dev
->
priv
;
u8
test_result
=
true
;
e100_isolate_driver
(
bdp
);
u8
test_result
=
0
;
if
(
!
e100_get_link_state
(
bdp
))
{
test_result
=
ETH_TEST_FL_FAILED
;
test_info
[
test_link
]
=
true
;
}
if
(
!
e100_diag_eeprom
(
dev
))
{
test_result
=
ETH_TEST_FL_FAILED
;
test_info
[
test_eeprom
]
=
true
;
}
if
(
flags
&
ETH_TEST_FL_OFFLINE
)
{
u8
fail_mask
;
fail_mask
=
e100_diag_selftest
(
dev
);
if
(
fail_mask
)
{
test_result
=
false
;
if
(
fail_mask
&
REGISTER_TEST_FAIL
)
test_info
[
E100_REG_TEST_FAIL
]
=
true
;
if
(
fail_mask
&
ROM_TEST_FAIL
)
test_info
[
E100_ROM_TEST_FAIL
]
=
true
;
if
(
fail_mask
&
SELF_TEST_FAIL
)
test_info
[
E100_MAC_TEST_FAIL
]
=
true
;
if
(
fail_mask
&
TEST_TIMEOUT
)
test_info
[
E100_CHIP_TIMEOUT
]
=
true
;
if
(
netif_running
(
dev
))
{
spin_lock_bh
(
&
dev
->
xmit_lock
);
e100_close
(
dev
);
spin_unlock_bh
(
&
dev
->
xmit_lock
);
}
if
(
e100_diag_selftest
(
dev
))
{
test_result
=
ETH_TEST_FL_FAILED
;
test_info
[
test_self_test
]
=
true
;
}
fail_mask
=
e100_diag_loopback
(
dev
);
if
(
fail_mask
)
{
test_result
=
false
;
test_result
=
ETH_TEST_FL_FAILED
;
if
(
fail_mask
&
PHY_LOOPBACK
)
test_info
[
E100_LPBK_PHY_FAIL
]
=
true
;
test_info
[
test_loopback_phy
]
=
true
;
if
(
fail_mask
&
MAC_LOOPBACK
)
test_info
[
E100_LPBK_MAC_FAIL
]
=
true
;
test_info
[
test_loopback_mac
]
=
true
;
}
}
if
(
!
e100_diag_eeprom
(
dev
))
{
test_result
=
false
;
test_info
[
E100_EEPROM_TEST_FAIL
]
=
true
;
test_info
[
cable_diag
]
=
e100_cable_diag
(
bdp
);
/* Need hw init regardless of netif_running */
e100_hw_init
(
bdp
);
if
(
netif_running
(
dev
))
{
e100_open
(
dev
);
}
}
else
{
test_info
[
test_self_test
]
=
false
;
test_info
[
test_loopback_phy
]
=
false
;
test_info
[
test_loopback_mac
]
=
false
;
test_info
[
cable_diag
]
=
false
;
}
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
*
2
);
e100_deisolate_driver
(
bdp
,
false
);
return
flags
|
(
test_result
?
0
:
ETH_TEST_FL_FAILED
);
return
flags
|
test_result
;
}
/**
...
...
@@ -126,8 +133,6 @@ e100_diag_selftest(struct net_device *dev)
}
}
e100_configure_device
(
bdp
);
return
retval
;
}
...
...
@@ -165,14 +170,14 @@ e100_diag_loopback (struct net_device *dev)
u8
rc
=
0
;
printk
(
KERN_DEBUG
"%s: PHY loopback test starts
\n
"
,
dev
->
name
);
e100_
sw_reset
(
dev
->
priv
,
PORT_SELECTIVE_RESET
);
e100_
hw_init
(
dev
->
priv
);
if
(
!
e100_diag_one_loopback
(
dev
,
PHY_LOOPBACK
))
{
rc
|=
PHY_LOOPBACK
;
}
printk
(
KERN_DEBUG
"%s: PHY loopback test ends
\n
"
,
dev
->
name
);
printk
(
KERN_DEBUG
"%s: MAC loopback test starts
\n
"
,
dev
->
name
);
e100_
sw_reset
(
dev
->
priv
,
PORT_SELECTIVE_RESET
);
e100_
hw_init
(
dev
->
priv
);
if
(
!
e100_diag_one_loopback
(
dev
,
MAC_LOOPBACK
))
{
rc
|=
MAC_LOOPBACK
;
}
...
...
@@ -257,15 +262,10 @@ e100_diag_config_loopback(struct e100_private* bdp,
if
(
set_loopback
)
/* Set PHY loopback mode */
e100_phy_set_loopback
(
bdp
);
else
{
/* Back to normal speed and duplex */
if
(
bdp
->
params
.
e100_speed_duplex
==
E100_AUTONEG
)
/* Reset PHY and do autoneg */
e100_phy_autoneg
(
bdp
);
else
/* Reset PHY and force speed and duplex */
e100_force_speed_duplex
(
bdp
);
}
/* Wait for PHY state change */
else
/* Reset PHY loopback mode */
e100_phy_reset
(
bdp
);
/* Wait for PHY state change */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
);
}
else
{
/* For MAC loopback wait 500 msec to take effect */
...
...
@@ -348,10 +348,6 @@ static void
e100_diag_loopback_cu_ru_exec
(
struct
e100_private
*
bdp
)
{
/*load CU & RU base */
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
,
0
))
printk
(
KERN_ERR
"e100: SCB_CUC_LOAD_BASE failed
\n
"
);
if
(
!
e100_wait_exec_cmplx
(
bdp
,
0
,
SCB_RUC_LOAD_BASE
,
0
))
printk
(
KERN_ERR
"e100: SCB_RUC_LOAD_BASE failed!
\n
"
);
if
(
!
e100_wait_exec_cmplx
(
bdp
,
bdp
->
loopback
.
dma_handle
,
SCB_RUC_START
,
0
))
printk
(
KERN_ERR
"e100: SCB_RUC_START failed!
\n
"
);
...
...
@@ -433,3 +429,72 @@ e100_diag_loopback_free (struct e100_private *bdp)
bdp
->
loopback
.
dma_handle
);
}
static
int
e100_cable_diag
(
struct
e100_private
*
bdp
)
{
int
saved_open_circut
=
0xffff
;
int
saved_short_circut
=
0xffff
;
int
saved_distance
=
0xffff
;
int
saved_same
=
0
;
int
cable_status
=
E100_CABLE_UNKNOWN
;
int
i
;
/* If we have link, */
if
(
e100_get_link_state
(
bdp
))
return
E100_CABLE_OK
;
if
(
bdp
->
rev_id
<
D102_REV_ID
)
return
E100_CABLE_UNKNOWN
;
/* Disable MDI/MDI-X auto switching */
e100_mdi_write
(
bdp
,
MII_NCONFIG
,
bdp
->
phy_addr
,
MDI_MDIX_RESET_ALL_MASK
);
/* Set to 100 Full as required by cable test */
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
BMCR_SPEED100
|
BMCR_FULLDPLX
);
/* Test up to 100 times */
for
(
i
=
0
;
i
<
100
;
i
++
)
{
u16
ctrl_reg
;
int
distance
,
open_circut
,
short_circut
,
near_end
;
/* Enable and execute cable test */
e100_mdi_write
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
(
HWI_TEST_ENABLE
|
HWI_TEST_EXECUTE
));
/* Wait for cable test finished */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
+
1
);
/* Read results */
e100_mdi_read
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
&
ctrl_reg
);
distance
=
ctrl_reg
&
HWI_TEST_DISTANCE
;
open_circut
=
ctrl_reg
&
HWI_TEST_HIGHZ_PROBLEM
;
short_circut
=
ctrl_reg
&
HWI_TEST_LOWZ_PROBLEM
;
if
((
distance
==
saved_distance
)
&&
(
open_circut
==
saved_open_circut
)
&&
(
short_circut
==
saved_short_circut
))
saved_same
++
;
else
{
saved_same
=
0
;
saved_distance
=
distance
;
saved_open_circut
=
open_circut
;
saved_short_circut
=
short_circut
;
}
/* If results are the same 3 times */
if
(
saved_same
==
3
)
{
near_end
=
((
distance
*
HWI_REGISTER_GRANULARITY
)
<
HWI_NEAR_END_BOUNDARY
);
if
(
open_circut
)
cable_status
=
(
near_end
)
?
E100_CABLE_OPEN_NEAR
:
E100_CABLE_OPEN_FAR
;
if
(
short_circut
)
cable_status
=
(
near_end
)
?
E100_CABLE_SHORT_NEAR
:
E100_CABLE_SHORT_FAR
;
break
;
}
}
/* Reset cable test */
e100_mdi_write
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
HWI_RESET_ALL_MASK
);
return
cable_status
;
}
drivers/net/e1000/Makefile
View file @
81c830a4
################################################################################
#
#
# Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
# Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
...
...
drivers/net/e1000/e1000.h
View file @
81c830a4
...
...
@@ -134,6 +134,7 @@ struct e1000_buffer {
uint64_t
dma
;
unsigned
long
length
;
unsigned
long
time_stamp
;
unsigned
int
next_to_watch
;
};
struct
e1000_desc_ring
{
...
...
@@ -169,7 +170,6 @@ struct e1000_adapter {
struct
timer_list
watchdog_timer
;
struct
timer_list
phy_info_timer
;
struct
vlan_group
*
vlgrp
;
char
*
id_string
;
uint32_t
bd_number
;
uint32_t
rx_buffer_len
;
uint32_t
part_num
;
...
...
@@ -218,6 +218,9 @@ struct e1000_adapter {
struct
e1000_phy_info
phy_info
;
struct
e1000_phy_stats
phy_stats
;
uint32_t
test_icr
;
struct
e1000_desc_ring
test_tx_ring
;
struct
e1000_desc_ring
test_rx_ring
;
uint32_t
pci_state
[
16
];
...
...
drivers/net/e1000/e1000_ethtool.c
View file @
81c830a4
...
...
@@ -40,15 +40,60 @@ extern void e1000_down(struct e1000_adapter *adapter);
extern
void
e1000_reset
(
struct
e1000_adapter
*
adapter
);
extern
int
e1000_set_spd_dplx
(
struct
e1000_adapter
*
adapter
,
uint16_t
spddplx
);
static
char
e1000_gstrings_stats
[][
ETH_GSTRING_LEN
]
=
{
"rx_packets"
,
"tx_packets"
,
"rx_bytes"
,
"tx_bytes"
,
"rx_errors"
,
"tx_errors"
,
"rx_dropped"
,
"tx_dropped"
,
"multicast"
,
"collisions"
,
"rx_length_errors"
,
"rx_over_errors"
,
"rx_crc_errors"
,
"rx_frame_errors"
,
"rx_fifo_errors"
,
"rx_missed_errors"
,
"tx_aborted_errors"
,
"tx_carrier_errors"
,
"tx_fifo_errors"
,
"tx_heartbeat_errors"
,
"tx_window_errors"
,
struct
e1000_stats
{
char
stat_string
[
ETH_GSTRING_LEN
];
int
sizeof_stat
;
int
stat_offset
;
};
#define E1000_STATS_LEN sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN
#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
offsetof(struct e1000_adapter, m)
static
struct
e1000_stats
e1000_gstrings_stats
[]
=
{
{
"rx_packets"
,
E1000_STAT
(
net_stats
.
rx_packets
)
},
{
"tx_packets"
,
E1000_STAT
(
net_stats
.
tx_packets
)
},
{
"rx_bytes"
,
E1000_STAT
(
net_stats
.
rx_bytes
)
},
{
"tx_bytes"
,
E1000_STAT
(
net_stats
.
tx_bytes
)
},
{
"rx_errors"
,
E1000_STAT
(
net_stats
.
rx_errors
)
},
{
"tx_errors"
,
E1000_STAT
(
net_stats
.
tx_errors
)
},
{
"rx_dropped"
,
E1000_STAT
(
net_stats
.
rx_dropped
)
},
{
"tx_dropped"
,
E1000_STAT
(
net_stats
.
tx_dropped
)
},
{
"multicast"
,
E1000_STAT
(
net_stats
.
multicast
)
},
{
"collisions"
,
E1000_STAT
(
net_stats
.
collisions
)
},
{
"rx_length_errors"
,
E1000_STAT
(
net_stats
.
rx_length_errors
)
},
{
"rx_over_errors"
,
E1000_STAT
(
net_stats
.
rx_over_errors
)
},
{
"rx_crc_errors"
,
E1000_STAT
(
net_stats
.
rx_crc_errors
)
},
{
"rx_frame_errors"
,
E1000_STAT
(
net_stats
.
rx_frame_errors
)
},
{
"rx_fifo_errors"
,
E1000_STAT
(
net_stats
.
rx_fifo_errors
)
},
{
"rx_missed_errors"
,
E1000_STAT
(
net_stats
.
rx_missed_errors
)
},
{
"tx_aborted_errors"
,
E1000_STAT
(
net_stats
.
tx_aborted_errors
)
},
{
"tx_carrier_errors"
,
E1000_STAT
(
net_stats
.
tx_carrier_errors
)
},
{
"tx_fifo_errors"
,
E1000_STAT
(
net_stats
.
tx_fifo_errors
)
},
{
"tx_heartbeat_errors"
,
E1000_STAT
(
net_stats
.
tx_heartbeat_errors
)
},
{
"tx_window_errors"
,
E1000_STAT
(
net_stats
.
tx_window_errors
)
},
{
"tx_abort_late_coll"
,
E1000_STAT
(
stats
.
latecol
)
},
{
"tx_deferred_ok"
,
E1000_STAT
(
stats
.
dc
)
},
{
"tx_single_coll_ok"
,
E1000_STAT
(
stats
.
scc
)
},
{
"tx_multi_coll_ok"
,
E1000_STAT
(
stats
.
mcc
)
},
{
"rx_long_length_errors"
,
E1000_STAT
(
stats
.
roc
)
},
{
"rx_short_length_errors"
,
E1000_STAT
(
stats
.
ruc
)
},
{
"rx_align_errors"
,
E1000_STAT
(
stats
.
algnerrc
)
},
{
"tx_tcp_seg_good"
,
E1000_STAT
(
stats
.
tsctc
)
},
{
"tx_tcp_seg_failed"
,
E1000_STAT
(
stats
.
tsctfc
)
},
{
"rx_flow_control_xon"
,
E1000_STAT
(
stats
.
xonrxc
)
},
{
"rx_flow_control_xoff"
,
E1000_STAT
(
stats
.
xoffrxc
)
},
{
"tx_flow_control_xon"
,
E1000_STAT
(
stats
.
xontxc
)
},
{
"tx_flow_control_xoff"
,
E1000_STAT
(
stats
.
xofftxc
)
},
{
"rx_csum_offload_good"
,
E1000_STAT
(
hw_csum_good
)
},
{
"rx_csum_offload_errors"
,
E1000_STAT
(
hw_csum_err
)
}
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
static
char
e1000_gstrings_test
[][
ETH_GSTRING_LEN
]
=
{
"Register test (offline)"
,
"Eeprom test (offline)"
,
"Interrupt test (offline)"
,
"Loopback test (offline)"
,
"Link test (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
static
void
e1000_ethtool_gset
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_cmd
*
ecmd
)
...
...
@@ -154,6 +199,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
strncpy
(
drvinfo
->
fw_version
,
"N/A"
,
32
);
strncpy
(
drvinfo
->
bus_info
,
adapter
->
pdev
->
slot_name
,
32
);
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
drvinfo
->
testinfo_len
=
E1000_TEST_LEN
;
#define E1000_REGS_LEN 32
drvinfo
->
regdump_len
=
E1000_REGS_LEN
*
sizeof
(
uint32_t
);
drvinfo
->
eedump_len
=
adapter
->
hw
.
eeprom
.
word_size
*
2
;
...
...
@@ -164,6 +210,7 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter,
struct
ethtool_regs
*
regs
,
uint32_t
*
regs_buff
)
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
phy_data
;
regs
->
version
=
(
1
<<
24
)
|
(
hw
->
revision_id
<<
16
)
|
hw
->
device_id
;
...
...
@@ -182,6 +229,62 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter,
regs_buff
[
10
]
=
E1000_READ_REG
(
hw
,
TDT
);
regs_buff
[
11
]
=
E1000_READ_REG
(
hw
,
TIDV
);
regs_buff
[
12
]
=
adapter
->
hw
.
phy_type
;
/* PHY type (IGP=1, M88=0) */
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_AGC_A
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_AGC_A
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
13
]
=
(
uint32_t
)
phy_data
;
/* cable length */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_AGC_B
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_AGC_B
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
14
]
=
(
uint32_t
)
phy_data
;
/* cable length */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_AGC_C
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_AGC_C
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
15
]
=
(
uint32_t
)
phy_data
;
/* cable length */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_AGC_D
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_AGC_D
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
16
]
=
(
uint32_t
)
phy_data
;
/* cable length */
regs_buff
[
17
]
=
0
;
/* extended 10bt distance (not needed) */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_STATUS
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
18
]
=
(
uint32_t
)
phy_data
;
/* cable polarity */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_PCS_INIT_REG
);
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PCS_INIT_REG
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
);
regs_buff
[
19
]
=
(
uint32_t
)
phy_data
;
/* cable polarity */
regs_buff
[
20
]
=
0
;
/* polarity correction enabled (always) */
regs_buff
[
22
]
=
0
;
/* phy receive errors (unavailable) */
regs_buff
[
23
]
=
regs_buff
[
18
];
/* mdix mode */
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0
);
}
else
{
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
);
regs_buff
[
13
]
=
(
uint32_t
)
phy_data
;
/* cable length */
regs_buff
[
14
]
=
0
;
/* Dummy (to align w/ IGP phy reg dump) */
regs_buff
[
15
]
=
0
;
/* Dummy (to align w/ IGP phy reg dump) */
regs_buff
[
16
]
=
0
;
/* Dummy (to align w/ IGP phy reg dump) */
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
);
regs_buff
[
17
]
=
(
uint32_t
)
phy_data
;
/* extended 10bt distance */
regs_buff
[
18
]
=
regs_buff
[
13
];
/* cable polarity */
regs_buff
[
19
]
=
0
;
/* Dummy (to align w/ IGP phy reg dump) */
regs_buff
[
20
]
=
regs_buff
[
17
];
/* polarity correction */
/* phy receive errors */
regs_buff
[
22
]
=
adapter
->
phy_stats
.
receive_errors
;
regs_buff
[
23
]
=
regs_buff
[
13
];
/* mdix mode */
}
regs_buff
[
21
]
=
adapter
->
phy_stats
.
idle_errors
;
/* phy idle errors */
e1000_read_phy_reg
(
hw
,
PHY_1000T_STATUS
,
&
phy_data
);
regs_buff
[
24
]
=
(
uint32_t
)
phy_data
;
/* phy local receiver status */
regs_buff
[
25
]
=
regs_buff
[
24
];
/* phy remote receiver status */
return
;
}
...
...
@@ -219,7 +322,7 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
uint16_t
i
;
for
(
i
=
0
;
i
<
last_word
-
first_word
+
1
;
i
++
)
if
((
ret_val
=
e1000_read_eeprom
(
hw
,
first_word
+
i
,
1
,
&
eeprom_buff
[
i
])))
&
eeprom_buff
[
i
])))
break
;
}
geeprom_error:
...
...
@@ -249,7 +352,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
first_word
=
eeprom
->
offset
>>
1
;
last_word
=
(
eeprom
->
offset
+
eeprom
->
len
-
1
)
>>
1
;
eeprom_buff
=
kmalloc
(
max_len
,
GFP_KERNEL
);
if
(
eeprom_buff
==
NULL
)
if
(
!
eeprom_buff
)
return
-
ENOMEM
;
ptr
=
(
void
*
)
eeprom_buff
;
...
...
@@ -284,6 +387,765 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
return
ret_val
;
}
#define REG_PATTERN_TEST(R, M, W) \
{ \
uint32_t pat, value; \
uint32_t test[] = \
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \
E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
value = E1000_READ_REG(&adapter->hw, R); \
if(value != (test[pat] & W & M)) { \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
} \
} \
}
#define REG_SET_AND_CHECK(R, M, W) \
{ \
uint32_t value; \
E1000_WRITE_REG(&adapter->hw, R, W & M); \
value = E1000_READ_REG(&adapter->hw, R); \
if ((W & M) != (value & M)) { \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
} \
}
static
int
e1000_reg_test
(
struct
e1000_adapter
*
adapter
,
uint64_t
*
data
)
{
uint32_t
value
;
uint32_t
i
;
/* The status register is Read Only, so a write should fail.
* Some bits that get toggled are ignored.
*/
value
=
(
E1000_READ_REG
(
&
adapter
->
hw
,
STATUS
)
&
(
0xFFFFF833
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
STATUS
,
(
0xFFFFFFFF
));
if
(
value
!=
(
E1000_READ_REG
(
&
adapter
->
hw
,
STATUS
)
&
(
0xFFFFF833
)))
{
*
data
=
1
;
return
1
;
}
REG_PATTERN_TEST
(
FCAL
,
0xFFFFFFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
FCAH
,
0x0000FFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
FCT
,
0x0000FFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
VET
,
0x0000FFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
RDTR
,
0x0000FFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
RDBAH
,
0xFFFFFFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
RDLEN
,
0x000FFF80
,
0x000FFFFF
);
REG_PATTERN_TEST
(
RDH
,
0x0000FFFF
,
0x0000FFFF
);
REG_PATTERN_TEST
(
RDT
,
0x0000FFFF
,
0x0000FFFF
);
REG_PATTERN_TEST
(
FCRTH
,
0x0000FFF8
,
0x0000FFF8
);
REG_PATTERN_TEST
(
FCTTV
,
0x0000FFFF
,
0x0000FFFF
);
REG_PATTERN_TEST
(
TIPG
,
0x3FFFFFFF
,
0x3FFFFFFF
);
REG_PATTERN_TEST
(
TDBAH
,
0xFFFFFFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
TDLEN
,
0x000FFF80
,
0x000FFFFF
);
REG_SET_AND_CHECK
(
RCTL
,
0xFFFFFFFF
,
0x00000000
);
REG_SET_AND_CHECK
(
RCTL
,
0x06DFB3FE
,
0x003FFFFB
);
REG_SET_AND_CHECK
(
TCTL
,
0xFFFFFFFF
,
0x00000000
);
if
(
adapter
->
hw
.
mac_type
>=
e1000_82543
)
{
REG_SET_AND_CHECK
(
RCTL
,
0x06DFB3FE
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
RDBAL
,
0xFFFFFFF0
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
TXCW
,
0xC000FFFF
,
0x0000FFFF
);
REG_PATTERN_TEST
(
TDBAL
,
0xFFFFFFF0
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
TIDV
,
0x0000FFFF
,
0x0000FFFF
);
for
(
i
=
0
;
i
<
E1000_RAR_ENTRIES
;
i
++
)
{
REG_PATTERN_TEST
(
RA
+
((
i
<<
1
)
<<
2
),
0xFFFFFFFF
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
RA
+
(((
i
<<
1
)
+
1
)
<<
2
),
0x8003FFFF
,
0xFFFFFFFF
);
}
}
else
{
REG_SET_AND_CHECK
(
RCTL
,
0xFFFFFFFF
,
0x01FFFFFF
);
REG_PATTERN_TEST
(
RDBAL
,
0xFFFFF000
,
0xFFFFFFFF
);
REG_PATTERN_TEST
(
TXCW
,
0x0000FFFF
,
0x0000FFFF
);
REG_PATTERN_TEST
(
TDBAL
,
0xFFFFF000
,
0xFFFFFFFF
);
}
for
(
i
=
0
;
i
<
E1000_MC_TBL_SIZE
;
i
++
)
REG_PATTERN_TEST
(
MTA
+
(
i
<<
2
),
0xFFFFFFFF
,
0xFFFFFFFF
);
return
0
;
}
static
int
e1000_eeprom_test
(
struct
e1000_adapter
*
adapter
,
uint64_t
*
data
)
{
uint16_t
temp
;
uint16_t
checksum
=
0
;
uint16_t
i
;
*
data
=
0
;
/* Read and add up the contents of the EEPROM */
for
(
i
=
0
;
i
<
(
EEPROM_CHECKSUM_REG
+
1
);
i
++
)
{
if
((
e1000_read_eeprom
(
&
adapter
->
hw
,
i
,
1
,
&
temp
))
<
0
)
{
*
data
=
1
;
break
;
}
checksum
+=
temp
;
}
/* If Checksum is not Correct return error else test passed */
if
((
checksum
!=
(
uint16_t
)
EEPROM_SUM
)
&&
!
(
*
data
))
*
data
=
2
;
return
*
data
;
}
static
irqreturn_t
e1000_test_intr
(
int
irq
,
void
*
data
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
netdev
=
(
struct
net_device
*
)
data
;
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
adapter
->
test_icr
|=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
);
return
IRQ_HANDLED
;
}
static
int
e1000_intr_test
(
struct
e1000_adapter
*
adapter
,
uint64_t
*
data
)
{
struct
net_device
*
netdev
=
adapter
->
netdev
;
uint32_t
icr
,
mask
,
i
=
0
;
*
data
=
0
;
/* Hook up test interrupt handler just for this test */
if
(
request_irq
(
netdev
->
irq
,
&
e1000_test_intr
,
SA_SHIRQ
,
netdev
->
name
,
netdev
))
{
*
data
=
1
;
return
-
1
;
}
/* Disable all the interrupts */
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
0xFFFFFFFF
);
msec_delay
(
10
);
/* Interrupts are disabled, so read interrupt cause
* register (icr) twice to verify that there are no interrupts
* pending. icr is clear on read.
*/
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
);
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
);
if
(
icr
!=
0
)
{
/* if icr is non-zero, there is no point
* running other interrupt tests.
*/
*
data
=
2
;
i
=
10
;
}
/* Test each interrupt */
for
(;
i
<
10
;
i
++
)
{
/* Interrupt to test */
mask
=
1
<<
i
;
/* Disable the interrupt to be reported in
* the cause register and then force the same
* interrupt and see if one gets posted. If
* an interrupt was posted to the bus, the
* test failed.
*/
adapter
->
test_icr
=
0
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
mask
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
ICS
,
mask
);
msec_delay
(
10
);
if
(
adapter
->
test_icr
&
mask
)
{
*
data
=
3
;
break
;
}
/* Enable the interrupt to be reported in
* the cause register and then force the same
* interrupt and see if one gets posted. If
* an interrupt was not posted to the bus, the
* test failed.
*/
adapter
->
test_icr
=
0
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMS
,
mask
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
ICS
,
mask
);
msec_delay
(
10
);
if
(
!
(
adapter
->
test_icr
&
mask
))
{
*
data
=
4
;
break
;
}
/* Disable the other interrupts to be reported in
* the cause register and then force the other
* interrupts and see if any get posted. If
* an interrupt was posted to the bus, the
* test failed.
*/
adapter
->
test_icr
=
0
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
~
mask
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
ICS
,
~
mask
);
msec_delay
(
10
);
if
(
adapter
->
test_icr
)
{
*
data
=
5
;
break
;
}
}
/* Disable all the interrupts */
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
0xFFFFFFFF
);
msec_delay
(
10
);
/* Unhook test interrupt handler */
free_irq
(
netdev
->
irq
,
netdev
);
return
*
data
;
}
static
void
e1000_free_desc_rings
(
struct
e1000_adapter
*
adapter
)
{
struct
e1000_desc_ring
*
txdr
=
&
adapter
->
test_tx_ring
;
struct
e1000_desc_ring
*
rxdr
=
&
adapter
->
test_rx_ring
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
int
i
;
if
(
txdr
->
desc
&&
txdr
->
buffer_info
)
{
for
(
i
=
0
;
i
<
txdr
->
count
;
i
++
)
{
if
(
txdr
->
buffer_info
[
i
].
dma
)
pci_unmap_single
(
pdev
,
txdr
->
buffer_info
[
i
].
dma
,
txdr
->
buffer_info
[
i
].
length
,
PCI_DMA_TODEVICE
);
if
(
txdr
->
buffer_info
[
i
].
skb
)
dev_kfree_skb
(
txdr
->
buffer_info
[
i
].
skb
);
}
}
if
(
rxdr
->
desc
&&
rxdr
->
buffer_info
)
{
for
(
i
=
0
;
i
<
rxdr
->
count
;
i
++
)
{
if
(
rxdr
->
buffer_info
[
i
].
dma
)
pci_unmap_single
(
pdev
,
rxdr
->
buffer_info
[
i
].
dma
,
rxdr
->
buffer_info
[
i
].
length
,
PCI_DMA_FROMDEVICE
);
if
(
rxdr
->
buffer_info
[
i
].
skb
)
dev_kfree_skb
(
rxdr
->
buffer_info
[
i
].
skb
);
}
}
if
(
txdr
->
desc
)
pci_free_consistent
(
pdev
,
txdr
->
size
,
txdr
->
desc
,
txdr
->
dma
);
if
(
rxdr
->
desc
)
pci_free_consistent
(
pdev
,
rxdr
->
size
,
rxdr
->
desc
,
rxdr
->
dma
);
if
(
txdr
->
buffer_info
)
kfree
(
txdr
->
buffer_info
);
if
(
rxdr
->
buffer_info
)
kfree
(
rxdr
->
buffer_info
);
return
;
}
static
int
e1000_setup_desc_rings
(
struct
e1000_adapter
*
adapter
)
{
struct
e1000_desc_ring
*
txdr
=
&
adapter
->
test_tx_ring
;
struct
e1000_desc_ring
*
rxdr
=
&
adapter
->
test_rx_ring
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
uint32_t
rctl
;
int
size
,
i
,
ret_val
;
/* Setup Tx descriptor ring and Tx buffers */
txdr
->
count
=
80
;
size
=
txdr
->
count
*
sizeof
(
struct
e1000_buffer
);
if
(
!
(
txdr
->
buffer_info
=
kmalloc
(
size
,
GFP_KERNEL
)))
{
ret_val
=
1
;
goto
err_nomem
;
}
memset
(
txdr
->
buffer_info
,
0
,
size
);
txdr
->
size
=
txdr
->
count
*
sizeof
(
struct
e1000_tx_desc
);
E1000_ROUNDUP
(
txdr
->
size
,
4096
);
if
(
!
(
txdr
->
desc
=
pci_alloc_consistent
(
pdev
,
txdr
->
size
,
&
txdr
->
dma
)))
{
ret_val
=
2
;
goto
err_nomem
;
}
memset
(
txdr
->
desc
,
0
,
txdr
->
size
);
txdr
->
next_to_use
=
txdr
->
next_to_clean
=
0
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDBAL
,
((
uint64_t
)
txdr
->
dma
&
0x00000000FFFFFFFF
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDBAH
,
((
uint64_t
)
txdr
->
dma
>>
32
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDLEN
,
txdr
->
count
*
sizeof
(
struct
e1000_tx_desc
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDH
,
0
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDT
,
0
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
E1000_TCTL_PSP
|
E1000_TCTL_EN
|
E1000_COLLISION_THRESHOLD
<<
E1000_CT_SHIFT
|
E1000_FDX_COLLISION_DISTANCE
<<
E1000_COLD_SHIFT
);
for
(
i
=
0
;
i
<
txdr
->
count
;
i
++
)
{
struct
e1000_tx_desc
*
tx_desc
=
E1000_TX_DESC
(
*
txdr
,
i
);
struct
sk_buff
*
skb
;
unsigned
int
size
=
1024
;
if
(
!
(
skb
=
alloc_skb
(
size
,
GFP_KERNEL
)))
{
ret_val
=
3
;
goto
err_nomem
;
}
skb_put
(
skb
,
size
);
txdr
->
buffer_info
[
i
].
skb
=
skb
;
txdr
->
buffer_info
[
i
].
length
=
skb
->
len
;
txdr
->
buffer_info
[
i
].
dma
=
pci_map_single
(
pdev
,
skb
->
data
,
skb
->
len
,
PCI_DMA_TODEVICE
);
tx_desc
->
buffer_addr
=
cpu_to_le64
(
txdr
->
buffer_info
[
i
].
dma
);
tx_desc
->
lower
.
data
=
cpu_to_le32
(
skb
->
len
);
tx_desc
->
lower
.
data
|=
E1000_TXD_CMD_EOP
;
tx_desc
->
lower
.
data
|=
E1000_TXD_CMD_IFCS
;
tx_desc
->
lower
.
data
|=
E1000_TXD_CMD_RPS
;
tx_desc
->
upper
.
data
=
0
;
}
/* Setup Rx descriptor ring and Rx buffers */
rxdr
->
count
=
80
;
size
=
rxdr
->
count
*
sizeof
(
struct
e1000_buffer
);
if
(
!
(
rxdr
->
buffer_info
=
kmalloc
(
size
,
GFP_KERNEL
)))
{
ret_val
=
4
;
goto
err_nomem
;
}
memset
(
rxdr
->
buffer_info
,
0
,
size
);
rxdr
->
size
=
rxdr
->
count
*
sizeof
(
struct
e1000_rx_desc
);
if
(
!
(
rxdr
->
desc
=
pci_alloc_consistent
(
pdev
,
rxdr
->
size
,
&
rxdr
->
dma
)))
{
ret_val
=
5
;
goto
err_nomem
;
}
memset
(
rxdr
->
desc
,
0
,
rxdr
->
size
);
rxdr
->
next_to_use
=
rxdr
->
next_to_clean
=
0
;
rctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
RCTL
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RCTL
,
rctl
&
~
E1000_RCTL_EN
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDBAL
,
((
uint64_t
)
rxdr
->
dma
&
0xFFFFFFFF
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDBAH
,
((
uint64_t
)
rxdr
->
dma
>>
32
));
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDLEN
,
rxdr
->
size
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDH
,
0
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDT
,
0
);
rctl
=
E1000_RCTL_EN
|
E1000_RCTL_BAM
|
E1000_RCTL_SZ_2048
|
E1000_RCTL_LBM_NO
|
E1000_RCTL_RDMTS_HALF
|
(
adapter
->
hw
.
mc_filter_type
<<
E1000_RCTL_MO_SHIFT
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
RCTL
,
rctl
);
for
(
i
=
0
;
i
<
rxdr
->
count
;
i
++
)
{
struct
e1000_rx_desc
*
rx_desc
=
E1000_RX_DESC
(
*
rxdr
,
i
);
struct
sk_buff
*
skb
;
if
(
!
(
skb
=
alloc_skb
(
E1000_RXBUFFER_2048
+
2
,
GFP_KERNEL
)))
{
ret_val
=
6
;
goto
err_nomem
;
}
skb_reserve
(
skb
,
2
);
rxdr
->
buffer_info
[
i
].
skb
=
skb
;
rxdr
->
buffer_info
[
i
].
length
=
E1000_RXBUFFER_2048
;
rxdr
->
buffer_info
[
i
].
dma
=
pci_map_single
(
pdev
,
skb
->
data
,
E1000_RXBUFFER_2048
,
PCI_DMA_FROMDEVICE
);
rx_desc
->
buffer_addr
=
cpu_to_le64
(
rxdr
->
buffer_info
[
i
].
dma
);
memset
(
skb
->
data
,
0x00
,
skb
->
len
);
}
return
0
;
err_nomem:
e1000_free_desc_rings
(
adapter
);
return
ret_val
;
}
static
void
e1000_phy_disable_receiver
(
struct
e1000_adapter
*
adapter
)
{
/* Write out to PHY registers 29 and 30 to disable the Receiver. */
e1000_write_phy_reg
(
&
adapter
->
hw
,
29
,
0x001F
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
30
,
0x8FFC
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
29
,
0x001A
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
30
,
0x8FF0
);
return
;
}
static
void
e1000_phy_reset_clk_and_crs
(
struct
e1000_adapter
*
adapter
)
{
uint16_t
phy_reg
;
/* Because we reset the PHY above, we need to re-force TX_CLK in the
* Extended PHY Specific Control Register to 25MHz clock. This
* value defaults back to a 2.5MHz clock when the PHY is reset.
*/
e1000_read_phy_reg
(
&
adapter
->
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_reg
);
phy_reg
|=
M88E1000_EPSCR_TX_CLK_25
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
phy_reg
);
/* In addition, because of the s/w reset above, we need to enable
* CRS on TX. This must be set for both full and half duplex
* operation.
*/
e1000_read_phy_reg
(
&
adapter
->
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_reg
);
phy_reg
|=
M88E1000_PSCR_ASSERT_CRS_ON_TX
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_reg
);
}
static
int
e1000_nonintegrated_phy_loopback
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
ctrl_reg
;
uint16_t
phy_reg
;
/* Setup the Device Control Register for PHY loopback test. */
ctrl_reg
=
E1000_READ_REG
(
&
adapter
->
hw
,
CTRL
);
ctrl_reg
|=
(
E1000_CTRL_ILOS
|
/* Invert Loss-Of-Signal */
E1000_CTRL_FRCSPD
|
/* Set the Force Speed Bit */
E1000_CTRL_FRCDPX
|
/* Set the Force Duplex Bit */
E1000_CTRL_SPD_1000
|
/* Force Speed to 1000 */
E1000_CTRL_FD
);
/* Force Duplex to FULL */
E1000_WRITE_REG
(
&
adapter
->
hw
,
CTRL
,
ctrl_reg
);
/* Read the PHY Specific Control Register (0x10) */
e1000_read_phy_reg
(
&
adapter
->
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_reg
);
/* Clear Auto-Crossover bits in PHY Specific Control Register
* (bits 6:5).
*/
phy_reg
&=
~
M88E1000_PSCR_AUTO_X_MODE
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_reg
);
/* Perform software reset on the PHY */
e1000_phy_reset
(
&
adapter
->
hw
);
/* Have to setup TX_CLK and TX_CRS after software reset */
e1000_phy_reset_clk_and_crs
(
adapter
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
0x8100
);
/* Wait for reset to complete. */
udelay
(
500
);
/* Have to setup TX_CLK and TX_CRS after software reset */
e1000_phy_reset_clk_and_crs
(
adapter
);
/* Write out to PHY registers 29 and 30 to disable the Receiver. */
e1000_phy_disable_receiver
(
adapter
);
/* Set the loopback bit in the PHY control register. */
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_reg
);
phy_reg
|=
MII_CR_LOOPBACK
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
phy_reg
);
/* Setup TX_CLK and TX_CRS one more time. */
e1000_phy_reset_clk_and_crs
(
adapter
);
/* Check Phy Configuration */
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_reg
);
if
(
phy_reg
!=
0x4100
)
return
9
;
e1000_read_phy_reg
(
&
adapter
->
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_reg
);
if
(
phy_reg
!=
0x0070
)
return
10
;
e1000_read_phy_reg
(
&
adapter
->
hw
,
29
,
&
phy_reg
);
if
(
phy_reg
!=
0x001A
)
return
11
;
return
0
;
}
static
int
e1000_integrated_phy_loopback
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
ctrl_reg
=
0
;
uint32_t
stat_reg
=
0
;
adapter
->
hw
.
autoneg
=
FALSE
;
if
(
adapter
->
hw
.
phy_type
==
e1000_phy_m88
)
{
/* Auto-MDI/MDIX Off */
e1000_write_phy_reg
(
&
adapter
->
hw
,
M88E1000_PHY_SPEC_CTRL
,
0x0808
);
/* reset to update Auto-MDI/MDIX */
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
0x9140
);
/* autoneg off */
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
0x8140
);
}
/* force 1000, set loopback */
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
0x4140
);
/* Now set up the MAC to the same speed/duplex as the PHY. */
ctrl_reg
=
E1000_READ_REG
(
&
adapter
->
hw
,
CTRL
);
ctrl_reg
&=
~
E1000_CTRL_SPD_SEL
;
/* Clear the speed sel bits */
ctrl_reg
|=
(
E1000_CTRL_FRCSPD
|
/* Set the Force Speed Bit */
E1000_CTRL_FRCDPX
|
/* Set the Force Duplex Bit */
E1000_CTRL_SPD_1000
|
/* Force Speed to 1000 */
E1000_CTRL_FD
);
/* Force Duplex to FULL */
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
&&
adapter
->
hw
.
phy_type
==
e1000_phy_m88
)
{
ctrl_reg
|=
E1000_CTRL_ILOS
;
/* Invert Loss of Signal */
}
else
{
/* Set the ILOS bit on the fiber Nic is half
* duplex link is detected. */
stat_reg
=
E1000_READ_REG
(
&
adapter
->
hw
,
STATUS
);
if
((
stat_reg
&
E1000_STATUS_FD
)
==
0
)
ctrl_reg
|=
(
E1000_CTRL_ILOS
|
E1000_CTRL_SLU
);
}
E1000_WRITE_REG
(
&
adapter
->
hw
,
CTRL
,
ctrl_reg
);
/* Disable the receiver on the PHY so when a cable is plugged in, the
* PHY does not begin to autoneg when a cable is reconnected to the NIC.
*/
if
(
adapter
->
hw
.
phy_type
==
e1000_phy_m88
)
e1000_phy_disable_receiver
(
adapter
);
udelay
(
500
);
return
0
;
}
static
int
e1000_set_phy_loopback
(
struct
e1000_adapter
*
adapter
)
{
uint16_t
phy_reg
=
0
;
uint16_t
count
=
0
;
switch
(
adapter
->
hw
.
mac_type
)
{
case
e1000_82543
:
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
)
{
/* Attempt to setup Loopback mode on Non-integrated PHY.
* Some PHY registers get corrupted at random, so
* attempt this 10 times.
*/
while
(
e1000_nonintegrated_phy_loopback
(
adapter
)
&&
count
++
<
10
);
if
(
count
<
11
)
return
0
;
}
break
;
case
e1000_82544
:
case
e1000_82540
:
case
e1000_82545
:
case
e1000_82546
:
case
e1000_82541
:
case
e1000_82547
:
return
e1000_integrated_phy_loopback
(
adapter
);
break
;
default:
/* Default PHY loopback work is to read the MII
* control register and assert bit 14 (loopback mode).
*/
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_reg
);
phy_reg
|=
MII_CR_LOOPBACK
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
phy_reg
);
return
0
;
break
;
}
return
8
;
}
static
int
e1000_setup_loopback_test
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
rctl
;
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_fiber
)
{
if
(
adapter
->
hw
.
mac_type
==
e1000_82545
||
adapter
->
hw
.
mac_type
==
e1000_82546
)
return
e1000_set_phy_loopback
(
adapter
);
else
{
rctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
RCTL
);
rctl
|=
E1000_RCTL_LBM_TCVR
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
RCTL
,
rctl
);
return
0
;
}
}
else
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
)
return
e1000_set_phy_loopback
(
adapter
);
return
7
;
}
static
void
e1000_loopback_cleanup
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
rctl
;
uint16_t
phy_reg
;
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
.
mac_type
==
e1000_82545
||
adapter
->
hw
.
mac_type
==
e1000_82546
)))
{
adapter
->
hw
.
autoneg
=
TRUE
;
e1000_read_phy_reg
(
&
adapter
->
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
);
}
}
}
static
void
e1000_create_lbtest_frame
(
struct
sk_buff
*
skb
,
unsigned
int
frame_size
)
{
memset
(
skb
->
data
,
0xFF
,
frame_size
);
frame_size
=
(
frame_size
%
2
)
?
(
frame_size
-
1
)
:
frame_size
;
memset
(
&
skb
->
data
[
frame_size
/
2
],
0xAA
,
frame_size
/
2
-
1
);
memset
(
&
skb
->
data
[
frame_size
/
2
+
10
],
0xBE
,
1
);
memset
(
&
skb
->
data
[
frame_size
/
2
+
12
],
0xAF
,
1
);
}
static
int
e1000_check_lbtest_frame
(
struct
sk_buff
*
skb
,
unsigned
int
frame_size
)
{
frame_size
=
(
frame_size
%
2
)
?
(
frame_size
-
1
)
:
frame_size
;
if
(
*
(
skb
->
data
+
3
)
==
0xFF
)
{
if
((
*
(
skb
->
data
+
frame_size
/
2
+
10
)
==
0xBE
)
&&
(
*
(
skb
->
data
+
frame_size
/
2
+
12
)
==
0xAF
))
{
return
0
;
}
}
return
13
;
}
static
int
e1000_run_loopback_test
(
struct
e1000_adapter
*
adapter
)
{
struct
e1000_desc_ring
*
txdr
=
&
adapter
->
test_tx_ring
;
struct
e1000_desc_ring
*
rxdr
=
&
adapter
->
test_rx_ring
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
int
i
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDT
,
rxdr
->
count
-
1
);
for
(
i
=
0
;
i
<
64
;
i
++
)
{
e1000_create_lbtest_frame
(
txdr
->
buffer_info
[
i
].
skb
,
1024
);
pci_dma_sync_single
(
pdev
,
txdr
->
buffer_info
[
i
].
dma
,
txdr
->
buffer_info
[
i
].
length
,
PCI_DMA_TODEVICE
);
}
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDT
,
i
);
msec_delay
(
200
);
pci_dma_sync_single
(
pdev
,
rxdr
->
buffer_info
[
0
].
dma
,
rxdr
->
buffer_info
[
0
].
length
,
PCI_DMA_FROMDEVICE
);
return
e1000_check_lbtest_frame
(
rxdr
->
buffer_info
[
0
].
skb
,
1024
);
}
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
;
*
data
=
e1000_run_loopback_test
(
adapter
);
e1000_loopback_cleanup
(
adapter
);
e1000_free_desc_rings
(
adapter
);
err_loopback:
return
*
data
;
}
static
int
e1000_link_test
(
struct
e1000_adapter
*
adapter
,
uint64_t
*
data
)
{
*
data
=
0
;
e1000_check_for_link
(
&
adapter
->
hw
);
if
(
!
(
E1000_READ_REG
(
&
adapter
->
hw
,
STATUS
)
&
E1000_STATUS_LU
))
{
*
data
=
1
;
}
return
*
data
;
}
static
int
e1000_ethtool_test
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_test
*
eth_test
,
uint64_t
*
data
)
{
boolean_t
if_running
=
netif_running
(
adapter
->
netdev
);
if
(
eth_test
->
flags
==
ETH_TEST_FL_OFFLINE
)
{
/* Offline tests */
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result */
if
(
e1000_link_test
(
adapter
,
&
data
[
4
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
if
(
if_running
)
e1000_down
(
adapter
);
e1000_reset
(
adapter
);
if
(
e1000_reg_test
(
adapter
,
&
data
[
0
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
e1000_reset
(
adapter
);
if
(
e1000_eeprom_test
(
adapter
,
&
data
[
1
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
e1000_reset
(
adapter
);
if
(
e1000_intr_test
(
adapter
,
&
data
[
2
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
e1000_reset
(
adapter
);
if
(
e1000_loopback_test
(
adapter
,
&
data
[
3
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
e1000_reset
(
adapter
);
if
(
if_running
)
e1000_up
(
adapter
);
}
else
{
/* Online tests */
if
(
e1000_link_test
(
adapter
,
&
data
[
4
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
/* Offline tests aren't run; pass by default */
data
[
0
]
=
0
;
data
[
1
]
=
0
;
data
[
2
]
=
0
;
data
[
3
]
=
0
;
}
return
0
;
}
static
void
e1000_ethtool_gwol
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_wolinfo
*
wol
)
{
...
...
@@ -443,24 +1305,46 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
case
ETHTOOL_GSTRINGS
:
{
struct
ethtool_gstrings
gstrings
=
{
ETHTOOL_GSTRINGS
};
char
*
strings
=
NULL
;
int
err
=
0
;
if
(
copy_from_user
(
&
gstrings
,
addr
,
sizeof
(
gstrings
)))
return
-
EFAULT
;
switch
(
gstrings
.
string_set
)
{
case
ETH_SS_STATS
:
case
ETH_SS_TEST
:
gstrings
.
len
=
E1000_TEST_LEN
;
strings
=
kmalloc
(
E1000_TEST_LEN
*
ETH_GSTRING_LEN
,
GFP_KERNEL
);
if
(
!
strings
)
return
-
ENOMEM
;
memcpy
(
strings
,
e1000_gstrings_test
,
E1000_TEST_LEN
*
ETH_GSTRING_LEN
);
break
;
case
ETH_SS_STATS
:
{
int
i
;
gstrings
.
len
=
E1000_STATS_LEN
;
strings
=
*
e1000_gstrings_stats
;
strings
=
kmalloc
(
E1000_STATS_LEN
*
ETH_GSTRING_LEN
,
GFP_KERNEL
);
if
(
!
strings
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
{
memcpy
(
&
strings
[
i
*
ETH_GSTRING_LEN
],
e1000_gstrings_stats
[
i
].
stat_string
,
ETH_GSTRING_LEN
);
}
break
;
}
default:
return
-
EOPNOTSUPP
;
}
if
(
copy_to_user
(
addr
,
&
gstrings
,
sizeof
(
gstrings
)))
return
-
EFAULT
;
err
=
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_gstrings
,
data
);
if
(
copy_to_user
(
addr
,
strings
,
if
(
!
err
&&
copy_to_user
(
addr
,
strings
,
gstrings
.
len
*
ETH_GSTRING_LEN
))
return
-
EFAULT
;
return
0
;
err
=
-
EFAULT
;
kfree
(
strings
);
return
err
;
}
case
ETHTOOL_GREGS
:
{
struct
ethtool_regs
regs
=
{
ETHTOOL_GREGS
};
...
...
@@ -522,16 +1406,14 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
void
*
ptr
;
int
err
=
0
;
if
(
copy_from_user
(
&
eeprom
,
addr
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
eeprom_buff
=
kmalloc
(
hw
->
eeprom
.
word_size
*
2
,
GFP_KERNEL
);
if
(
eeprom_buff
==
NULL
)
if
(
!
eeprom_buff
)
return
-
ENOMEM
;
if
(
copy_from_user
(
&
eeprom
,
addr
,
sizeof
(
eeprom
)))
{
err
=
-
EFAULT
;
goto
err_geeprom_ioctl
;
}
if
((
err
=
e1000_ethtool_geeprom
(
adapter
,
&
eeprom
,
eeprom_buff
)))
goto
err_geeprom_ioctl
;
...
...
@@ -565,18 +1447,45 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
}
case
ETHTOOL_GSTATS
:
{
struct
{
struct
ethtool_stats
cmd
;
struct
ethtool_stats
eth_stats
;
uint64_t
data
[
E1000_STATS_LEN
];
}
stats
=
{
{
ETHTOOL_GSTATS
,
E1000_STATS_LEN
}
};
int
i
;
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
stats
.
data
[
i
]
=
((
unsigned
long
*
)
&
adapter
->
net_stats
)[
i
];
stats
.
data
[
i
]
=
(
e1000_gstrings_stats
[
i
].
sizeof_stat
==
sizeof
(
uint64_t
))
?
*
(
uint64_t
*
)((
char
*
)
adapter
+
e1000_gstrings_stats
[
i
].
stat_offset
)
:
*
(
uint32_t
*
)((
char
*
)
adapter
+
e1000_gstrings_stats
[
i
].
stat_offset
);
if
(
copy_to_user
(
addr
,
&
stats
,
sizeof
(
stats
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_TEST
:
{
struct
{
struct
ethtool_test
eth_test
;
uint64_t
data
[
E1000_TEST_LEN
];
}
test
=
{
{
ETHTOOL_TEST
}
};
int
err
;
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
copy_from_user
(
&
test
.
eth_test
,
addr
,
sizeof
(
test
.
eth_test
)))
return
-
EFAULT
;
test
.
eth_test
.
len
=
E1000_TEST_LEN
;
if
((
err
=
e1000_ethtool_test
(
adapter
,
&
test
.
eth_test
,
test
.
data
)))
return
err
;
if
(
copy_to_user
(
addr
,
&
test
,
sizeof
(
test
))
!=
0
)
return
-
EFAULT
;
return
0
;
}
default:
return
-
EOPNOTSUPP
;
}
...
...
drivers/net/e1000/e1000_hw.c
View file @
81c830a4
...
...
@@ -185,6 +185,7 @@ e1000_set_mac_type(struct e1000_hw *hw)
break
;
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_FIBER
:
case
E1000_DEV_ID_82546EB_QUAD_COPPER
:
hw
->
mac_type
=
e1000_82546
;
break
;
case
E1000_DEV_ID_82541EI
:
...
...
@@ -288,9 +289,7 @@ e1000_reset_hw(struct e1000_hw *hw)
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
led_ctrl
|=
(
IGP_ACTIVITY_LED_ENABLE
|
IGP_LED3_MODE
);
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
}
...
...
@@ -737,9 +736,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
led_ctrl
|=
(
IGP_ACTIVITY_LED_ENABLE
|
IGP_LED3_MODE
);
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
if
(
hw
->
autoneg_advertised
==
ADVERTISE_1000_FULL
)
{
...
...
@@ -2293,9 +2290,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
led_ctrl
|=
(
IGP_ACTIVITY_LED_ENABLE
|
IGP_LED3_MODE
);
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
}
}
...
...
@@ -3801,6 +3796,7 @@ e1000_setup_led(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_QUAD_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
...
...
@@ -3842,6 +3838,7 @@ e1000_cleanup_led(struct e1000_hw *hw)
case
E1000_DEV_ID_82545EM_FIBER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_FIBER
:
case
E1000_DEV_ID_82546EB_QUAD_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
...
...
@@ -3896,6 +3893,7 @@ e1000_led_on(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_QUAD_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
...
...
@@ -3949,6 +3947,7 @@ e1000_led_off(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_QUAD_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
...
...
@@ -4206,7 +4205,11 @@ e1000_get_bus_info(struct e1000_hw *hw)
status
=
E1000_READ_REG
(
hw
,
STATUS
);
hw
->
bus_type
=
(
status
&
E1000_STATUS_PCIX_MODE
)
?
e1000_bus_type_pcix
:
e1000_bus_type_pci
;
if
(
hw
->
bus_type
==
e1000_bus_type_pci
)
{
if
(
hw
->
device_id
==
E1000_DEV_ID_82546EB_QUAD_COPPER
)
{
hw
->
bus_speed
=
(
hw
->
bus_type
==
e1000_bus_type_pci
)
?
e1000_bus_speed_66
:
e1000_bus_speed_120
;
}
else
if
(
hw
->
bus_type
==
e1000_bus_type_pci
)
{
hw
->
bus_speed
=
(
status
&
E1000_STATUS_PCI66
)
?
e1000_bus_speed_66
:
e1000_bus_speed_33
;
}
else
{
...
...
drivers/net/e1000/e1000_hw.h
View file @
81c830a4
...
...
@@ -99,6 +99,7 @@ typedef enum {
e1000_bus_speed_33
,
e1000_bus_speed_66
,
e1000_bus_speed_100
,
e1000_bus_speed_120
,
e1000_bus_speed_133
,
e1000_bus_speed_reserved
}
e1000_bus_speed
;
...
...
@@ -314,10 +315,11 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EP 0x1018
#define E1000_DEV_ID_82547EI 0x1019
#define NUM_DEV_IDS
19
#define NUM_DEV_IDS
20
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
...
...
@@ -601,7 +603,7 @@ struct e1000_ffvt_entry {
#define E1000_EECD 0x00010
/* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014
/* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018
/* Extended Device Control - RW */
#define E1000_FLA 0x0001C
/* Flash Access
Register
- RW */
#define E1000_FLA 0x0001C
/* Flash Access - RW */
#define E1000_MDIC 0x00020
/* MDI Control - RW */
#define E1000_FCAL 0x00028
/* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C
/* Flow Control Address High -RW */
...
...
@@ -730,6 +732,7 @@ struct e1000_ffvt_entry {
* the registers function in the same manner.
*/
#define E1000_82542_CTRL E1000_CTRL
#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
#define E1000_82542_STATUS E1000_STATUS
#define E1000_82542_EECD E1000_EECD
#define E1000_82542_EERD E1000_EERD
...
...
@@ -1485,7 +1488,6 @@ struct e1000_hw {
#define E1000_COLLISION_DISTANCE 64
#define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
#define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
#define E1000_GB_HDX_COLLISION_DISTANCE 512
#define E1000_COLD_SHIFT 12
/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
...
...
drivers/net/e1000/e1000_main.c
View file @
81c830a4
...
...
@@ -30,7 +30,14 @@
/* Change Log
*
* 5.0.43 3/5/03
* 5.1.11 5/6/03
* o Feature: Added support for 82546EB (Quad-port) hardware.
* o Feature: Added support for Diagnostics through Ethtool.
* o Cleanup: Removed /proc support.
* o Cleanup: Removed proprietary IDIAG interface.
* o Bug fix: TSO bug fixes.
*
* 5.0.42 3/5/03
* o Feature: Added support for 82541 and 82547 hardware.
* o Feature: Added support for Intel Gigabit PHY (IGP) and a variety of
* eeproms.
...
...
@@ -46,51 +53,22 @@
* shared interrupt instances.
*
* 4.4.18 11/27/02
* o Feature: Added user-settable knob for interrupt throttle rate (ITR).
* o Cleanup: removed large static array allocations.
* o Cleanup: C99 struct initializer format.
* o Bug fix: restore VLAN settings when interface is brought up.
* o Bug fix: return cleanly in probe if error in detecting MAC type.
* o Bug fix: Wake up on magic packet by default only if enabled in eeprom.
* o Bug fix: Validate MAC address in set_mac.
* o Bug fix: Throw away zero-length Tx skbs.
* o Bug fix: Make ethtool EEPROM acceses work on older versions of ethtool.
*
* 4.4.12 10/15/02
*/
char
e1000_driver_name
[]
=
"e1000"
;
char
e1000_driver_string
[]
=
"Intel(R) PRO/1000 Network Driver"
;
char
e1000_driver_version
[]
=
"5.
0.43-k3
"
;
char
e1000_driver_version
[]
=
"5.
1.11-k1
"
;
char
e1000_copyright
[]
=
"Copyright (c) 1999-2003 Intel Corporation."
;
/* e1000_pci_tbl - PCI Device ID Table
*
* Private driver_data field (last one) stores an index into e1000_strings
* Wildcard entries (PCI_ANY_ID) should come last
* Last entry must be all 0s
*
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask,
String Index
}
* Class, Class Mask,
private data (not used)
}
*/
static
struct
pci_device_id
e1000_pci_tbl
[]
__devinitdata
=
{
/* Intel(R) PRO/1000 Network Connection */
{
0x8086
,
0x1000
,
0x8086
,
0x1000
,
0
,
0
,
0
},
{
0x8086
,
0x1001
,
0x8086
,
0x1003
,
0
,
0
,
0
},
{
0x8086
,
0x1004
,
0x8086
,
0x1004
,
0
,
0
,
0
},
{
0x8086
,
0x1008
,
0x8086
,
0x1107
,
0
,
0
,
0
},
{
0x8086
,
0x1009
,
0x8086
,
0x1109
,
0
,
0
,
0
},
{
0x8086
,
0x100C
,
0x8086
,
0x1112
,
0
,
0
,
0
},
{
0x8086
,
0x100E
,
0x8086
,
0x001E
,
0
,
0
,
0
},
/* Compaq Gigabit Ethernet Server Adapter */
{
0x8086
,
0x1000
,
0x0E11
,
PCI_ANY_ID
,
0
,
0
,
1
},
{
0x8086
,
0x1001
,
0x0E11
,
PCI_ANY_ID
,
0
,
0
,
1
},
{
0x8086
,
0x1004
,
0x0E11
,
PCI_ANY_ID
,
0
,
0
,
1
},
/* IBM Mobile, Desktop & Server Adapters */
{
0x8086
,
0x1000
,
0x1014
,
PCI_ANY_ID
,
0
,
0
,
2
},
{
0x8086
,
0x1001
,
0x1014
,
PCI_ANY_ID
,
0
,
0
,
2
},
{
0x8086
,
0x1004
,
0x1014
,
PCI_ANY_ID
,
0
,
0
,
2
},
/* Generic */
{
0x8086
,
0x1000
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1001
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1004
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
...
...
@@ -106,6 +84,7 @@ static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
{
0x8086
,
0x1016
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1017
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x101E
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x101D
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1013
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1019
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
/* required last entry */
...
...
@@ -114,12 +93,6 @@ static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE
(
pci
,
e1000_pci_tbl
);
static
char
*
e1000_strings
[]
=
{
"Intel(R) PRO/1000 Network Connection"
,
"HP Gigabit Ethernet Server Adapter"
,
"IBM Mobile, Desktop & Server Adapters"
};
/* Local Function Prototypes */
int
e1000_up
(
struct
e1000_adapter
*
adapter
);
...
...
@@ -130,7 +103,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
static
int
e1000_init_module
(
void
);
static
void
e1000_exit_module
(
void
);
static
int
e1000_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
e1000_remove
(
struct
pci_dev
*
pdev
);
static
void
__devexit
e1000_remove
(
struct
pci_dev
*
pdev
);
static
int
e1000_sw_init
(
struct
e1000_adapter
*
adapter
);
static
int
e1000_open
(
struct
net_device
*
netdev
);
static
int
e1000_close
(
struct
net_device
*
netdev
);
...
...
@@ -195,7 +168,6 @@ struct notifier_block e1000_notifier_reboot = {
.
priority
=
0
};
/* Exported from other modules */
extern
void
e1000_check_options
(
struct
e1000_adapter
*
adapter
);
...
...
@@ -234,8 +206,9 @@ e1000_init_module(void)
printk
(
KERN_INFO
"%s
\n
"
,
e1000_copyright
);
ret
=
pci_module_init
(
&
e1000_driver
);
if
(
ret
>=
0
)
if
(
ret
>=
0
)
{
register_reboot_notifier
(
&
e1000_notifier_reboot
);
}
return
ret
;
}
...
...
@@ -439,7 +412,6 @@ e1000_probe(struct pci_dev *pdev,
netdev
->
base_addr
=
adapter
->
hw
.
io_base
;
adapter
->
bd_number
=
cards_found
;
adapter
->
id_string
=
e1000_strings
[
ent
->
driver_data
];
/* setup the private structure */
...
...
@@ -500,15 +472,14 @@ e1000_probe(struct pci_dev *pdev,
(
void
(
*
)(
void
*
))
e1000_tx_timeout_task
,
netdev
);
register_netdev
(
netdev
);
memcpy
(
adapter
->
ifname
,
netdev
->
name
,
IFNAMSIZ
);
adapter
->
ifname
[
IFNAMSIZ
-
1
]
=
0
;
/* we're going to reset, so assume we have no link for now */
netif_carrier_off
(
netdev
);
netif_stop_queue
(
netdev
);
printk
(
KERN_INFO
"%s: %s
\n
"
,
netdev
->
name
,
adapter
->
id_string
);
printk
(
KERN_INFO
"%s: Intel(R) PRO/1000 Network Connection
\n
"
,
netdev
->
name
);
e1000_check_options
(
adapter
);
/* Initial Wake on LAN setting
...
...
@@ -568,7 +539,6 @@ e1000_remove(struct pci_dev *pdev)
e1000_phy_hw_reset
(
&
adapter
->
hw
);
iounmap
(
adapter
->
hw
.
hw_addr
);
pci_release_regions
(
pdev
);
...
...
@@ -831,8 +801,9 @@ e1000_configure_tx(struct e1000_adapter *adapter)
e1000_config_collision_dist
(
&
adapter
->
hw
);
/* Setup Transmit Descriptor Settings for this adapter */
adapter
->
txd_cmd
=
E1000_TXD_CMD_IFCS
|
E1000_TXD_CMD_IDE
;
/* Setup Transmit Descriptor Settings for eop descriptor */
adapter
->
txd_cmd
=
E1000_TXD_CMD_IDE
|
E1000_TXD_CMD_EOP
|
E1000_TXD_CMD_IFCS
;
if
(
adapter
->
hw
.
report_tx_early
==
1
)
adapter
->
txd_cmd
|=
E1000_TXD_CMD_RS
;
...
...
@@ -1435,7 +1406,7 @@ e1000_watchdog(unsigned long data)
#define E1000_TX_FLAGS_VLAN_SHIFT 16
static
inline
boolean_t
e1000_tso
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
,
int
tx_flags
)
e1000_tso
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
)
{
#ifdef NETIF_F_TSO
struct
e1000_context_desc
*
context_desc
;
...
...
@@ -1471,7 +1442,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
context_desc
->
upper_setup
.
tcp_fields
.
tucse
=
cpu_to_le16
(
tucse
);
context_desc
->
tcp_seg_setup
.
fields
.
mss
=
cpu_to_le16
(
mss
);
context_desc
->
tcp_seg_setup
.
fields
.
hdr_len
=
hdr_len
;
context_desc
->
cmd_and_length
=
cpu_to_le32
(
adapter
->
txd_cmd
|
context_desc
->
cmd_and_length
=
cpu_to_le32
(
E1000_TXD_CMD_DEXT
|
E1000_TXD_CMD_TSE
|
E1000_TXD_CMD_IP
|
E1000_TXD_CMD_TCP
|
(
skb
->
len
-
(
hdr_len
)));
...
...
@@ -1504,8 +1475,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc
->
upper_setup
.
tcp_fields
.
tucso
=
cso
;
context_desc
->
upper_setup
.
tcp_fields
.
tucse
=
0
;
context_desc
->
tcp_seg_setup
.
data
=
0
;
context_desc
->
cmd_and_length
=
cpu_to_le32
(
adapter
->
txd_cmd
|
E1000_TXD_CMD_DEXT
);
context_desc
->
cmd_and_length
=
cpu_to_le32
(
E1000_TXD_CMD_DEXT
);
if
(
++
i
==
adapter
->
tx_ring
.
count
)
i
=
0
;
adapter
->
tx_ring
.
next_to_use
=
i
;
...
...
@@ -1520,7 +1490,8 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
static
inline
int
e1000_tx_map
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
)
e1000_tx_map
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
,
unsigned
int
first
)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
int
len
=
skb
->
len
,
offset
=
0
,
size
,
count
=
0
,
i
;
...
...
@@ -1588,6 +1559,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
}
if
(
--
i
<
0
)
i
=
tx_ring
->
count
-
1
;
tx_ring
->
buffer_info
[
i
].
skb
=
skb
;
tx_ring
->
buffer_info
[
first
].
next_to_watch
=
i
;
return
count
;
}
...
...
@@ -1597,12 +1569,9 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
struct
e1000_tx_desc
*
tx_desc
=
NULL
;
uint32_t
txd_upper
,
txd_lower
;
uint32_t
txd_upper
=
0
,
txd_lower
=
E1000_TXD_CMD_IFCS
;
int
i
;
txd_upper
=
0
;
txd_lower
=
adapter
->
txd_cmd
;
if
(
tx_flags
&
E1000_TX_FLAGS_TSO
)
{
txd_lower
|=
E1000_TXD_CMD_DEXT
|
E1000_TXD_DTYP_D
|
E1000_TXD_CMD_TSE
;
...
...
@@ -1630,7 +1599,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
tx_desc
->
lower
.
data
|=
cpu_to_le32
(
E1000_TXD_CMD_EOP
);
tx_desc
->
lower
.
data
|=
cpu_to_le32
(
adapter
->
txd_cmd
);
/* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
...
...
@@ -1690,6 +1659,7 @@ static int
e1000_xmit_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
unsigned
int
first
;
int
tx_flags
=
0
;
if
(
skb
->
len
<=
0
)
{
...
...
@@ -1715,12 +1685,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_flags
|=
(
vlan_tx_tag_get
(
skb
)
<<
E1000_TX_FLAGS_VLAN_SHIFT
);
}
if
(
e1000_tso
(
adapter
,
skb
,
tx_flags
))
first
=
adapter
->
tx_ring
.
next_to_use
;
if
(
e1000_tso
(
adapter
,
skb
))
tx_flags
|=
E1000_TX_FLAGS_TSO
;
else
if
(
e1000_tx_csum
(
adapter
,
skb
))
tx_flags
|=
E1000_TX_FLAGS_CSUM
;
e1000_tx_queue
(
adapter
,
e1000_tx_map
(
adapter
,
skb
),
tx_flags
);
e1000_tx_queue
(
adapter
,
e1000_tx_map
(
adapter
,
skb
,
first
),
tx_flags
);
netdev
->
trans_start
=
jiffies
;
...
...
@@ -1952,6 +1924,7 @@ e1000_update_stats(struct e1000_adapter *adapter)
}
if
((
hw
->
mac_type
<=
e1000_82546
)
&&
(
hw
->
phy_type
==
e1000_phy_m88
)
&&
!
e1000_read_phy_reg
(
hw
,
M88E1000_RX_ERR_CNTR
,
&
phy_tmp
))
adapter
->
phy_stats
.
receive_errors
+=
phy_tmp
;
}
...
...
@@ -2069,39 +2042,47 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
struct
net_device
*
netdev
=
adapter
->
netdev
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
struct
e1000_tx_desc
*
tx_desc
;
int
i
,
cleaned
=
FALSE
;
struct
e1000_tx_desc
*
tx_desc
,
*
eop_desc
;
struct
e1000_buffer
*
buffer_info
;
int
i
,
eop
,
cleaned
=
FALSE
;
i
=
tx_ring
->
next_to_clean
;
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
eop
=
tx_ring
->
buffer_info
[
i
].
next_to_watch
;
eop_desc
=
E1000_TX_DESC
(
*
tx_ring
,
eop
);
while
(
tx
_desc
->
upper
.
data
&
cpu_to_le32
(
E1000_TXD_STAT_DD
))
{
while
(
eop
_desc
->
upper
.
data
&
cpu_to_le32
(
E1000_TXD_STAT_DD
))
{
cleaned
=
TRUE
;
for
(
cleaned
=
FALSE
;
!
cleaned
;
)
{
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
buffer_info
=
&
tx_ring
->
buffer_info
[
i
];
if
(
tx_ring
->
buffer_info
[
i
].
dma
)
{
if
(
buffer_info
->
dma
)
{
pci_unmap_page
(
pdev
,
tx_ring
->
buffer_info
[
i
].
dma
,
tx_ring
->
buffer_info
[
i
].
length
,
PCI_DMA_TODEVICE
);
pci_unmap_page
(
pdev
,
buffer_info
->
dma
,
buffer_info
->
length
,
PCI_DMA_TODEVICE
);
tx_ring
->
buffer_info
[
i
].
dma
=
0
;
}
buffer_info
->
dma
=
0
;
}
if
(
tx_ring
->
buffer_info
[
i
].
skb
)
{
if
(
buffer_info
->
skb
)
{
dev_kfree_skb_any
(
tx_ring
->
buffer_info
[
i
].
skb
);
dev_kfree_skb_any
(
buffer_info
->
skb
);
tx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
}
buffer_info
->
skb
=
NULL
;
}
tx_desc
->
buffer_addr
=
0
;
tx_desc
->
lower
.
data
=
0
;
tx_desc
->
upper
.
data
=
0
;
tx_desc
->
buffer_addr
=
0
;
tx_desc
->
lower
.
data
=
0
;
tx_desc
->
upper
.
data
=
0
;
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
cleaned
=
(
i
==
eop
);
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
eop
=
tx_ring
->
buffer_info
[
i
].
next_to_watch
;
eop_desc
=
E1000_TX_DESC
(
*
tx_ring
,
eop
);
}
tx_ring
->
next_to_clean
=
i
;
...
...
@@ -2224,7 +2205,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
netif_rx
(
skb
);
}
#endif
/* CONFIG_E1000_NAPI */
netdev
->
last_rx
=
jiffies
;
rx_desc
->
status
=
0
;
...
...
@@ -2677,7 +2657,6 @@ e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
return
NOTIFY_DONE
;
}
static
int
e1000_suspend
(
struct
pci_dev
*
pdev
,
uint32_t
state
)
{
...
...
drivers/net/fc/iph5526.c
View file @
81c830a4
...
...
@@ -134,7 +134,7 @@ clone_list[] __initdata = {
{
0
,}
};
static
void
tachyon_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
tachyon_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
void
tachyon_interrupt_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
initialize_register_pointers
(
struct
fc_info
*
fi
);
...
...
@@ -623,7 +623,7 @@ u_int bus_addr, bus_indx_addr, i;
}
static
void
tachyon_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
tachyon_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
Scsi_Host
*
host
=
dev_id
;
struct
iph5526_hostdata
*
hostdata
=
(
struct
iph5526_hostdata
*
)
host
->
hostdata
;
...
...
@@ -632,6 +632,7 @@ u_long flags;
spin_lock_irqsave
(
&
fi
->
fc_lock
,
flags
);
tachyon_interrupt_handler
(
irq
,
dev_id
,
regs
);
spin_unlock_irqrestore
(
&
fi
->
fc_lock
,
flags
);
return
IRQ_HANDLED
;
}
static
void
tachyon_interrupt_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
...
...
@@ -3720,12 +3721,13 @@ struct fc_info *fi = (struct fc_info*)dev->priv;
int
iph5526_detect
(
Scsi_Host_Template
*
tmpt
)
{
struct
Scsi_Host
*
host
=
NULL
;
struct
iph5526_hostdata
*
hostdata
;
struct
fc_info
*
fi
=
NULL
;
int
no_of_hosts
=
0
,
timeout
,
i
,
j
,
count
=
0
;
u_int
pci_maddr
=
0
;
struct
pci_dev
*
pdev
=
NULL
;
struct
Scsi_Host
*
host
=
NULL
;
struct
iph5526_hostdata
*
hostdata
;
struct
fc_info
*
fi
=
NULL
;
int
no_of_hosts
=
0
,
i
,
j
,
count
=
0
;
u_int
pci_maddr
=
0
;
struct
pci_dev
*
pdev
=
NULL
;
unsigned
long
timeout
;
tmpt
->
proc_name
=
"iph5526"
;
if
(
pci_present
()
==
0
)
{
...
...
drivers/net/fec.c
View file @
81c830a4
...
...
@@ -188,7 +188,7 @@ struct fec_enet_private {
static
int
fec_enet_open
(
struct
net_device
*
dev
);
static
int
fec_enet_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
void
fec_enet_mii
(
struct
net_device
*
dev
);
static
void
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
void
fec_enet_tx
(
struct
net_device
*
dev
);
static
void
fec_enet_rx
(
struct
net_device
*
dev
);
static
int
fec_enet_close
(
struct
net_device
*
dev
);
...
...
@@ -393,12 +393,13 @@ fec_timeout(struct net_device *dev)
/* The interrupt handler.
* This is called from the MPC core interrupt.
*/
static
void
static
irqreturn_t
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
volatile
fec_t
*
fecp
;
uint
int_events
;
int
handled
=
0
;
fecp
=
(
volatile
fec_t
*
)
dev
->
base_addr
;
...
...
@@ -413,20 +414,27 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
/* Handle receive event in its own function.
*/
if
(
int_events
&
FEC_ENET_RXF
)
if
(
int_events
&
FEC_ENET_RXF
)
{
handled
=
1
;
fec_enet_rx
(
dev
);
}
/* Transmit OK, or non-fatal error. Update the buffer
descriptors. FEC handles all errors, we just discover
them as part of the transmit process.
*/
if
(
int_events
&
FEC_ENET_TXF
)
if
(
int_events
&
FEC_ENET_TXF
)
{
handled
=
1
;
fec_enet_tx
(
dev
);
}
if
(
int_events
&
FEC_ENET_MII
)
if
(
int_events
&
FEC_ENET_MII
)
{
handled
=
1
;
fec_enet_mii
(
dev
);
}
}
return
IRQ_RETVAL
(
handled
);
}
...
...
drivers/net/fmv18x.c
View file @
81c830a4
...
...
@@ -114,7 +114,7 @@ extern int fmv18x_probe(struct net_device *dev);
static
int
fmv18x_probe1
(
struct
net_device
*
dev
,
short
ioaddr
);
static
int
net_open
(
struct
net_device
*
dev
);
static
int
net_send_packet
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
void
net_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
net_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
void
net_rx
(
struct
net_device
*
dev
);
static
void
net_timeout
(
struct
net_device
*
dev
);
static
int
net_close
(
struct
net_device
*
dev
);
...
...
@@ -423,7 +423,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
/* The typical workload of the driver:
Handle the network interface interrupts. */
static
void
static
irqreturn_t
net_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
...
...
@@ -476,7 +476,7 @@ net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock
(
&
lp
->
lock
);
}
}
return
;
return
IRQ_RETVAL
(
status
)
;
}
/* We have a good packet(s), get it/them out of the buffers. */
...
...
drivers/net/hamradio/scc.c
View file @
81c830a4
...
...
@@ -199,7 +199,7 @@ static void z8530_init(void);
static
void
init_channel
(
struct
scc_channel
*
scc
);
static
void
scc_key_trx
(
struct
scc_channel
*
scc
,
char
tx
);
static
void
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
void
scc_init_timer
(
struct
scc_channel
*
scc
);
static
int
scc_net_setup
(
struct
scc_channel
*
scc
,
unsigned
char
*
name
,
int
addev
);
...
...
@@ -625,7 +625,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
#define SCC_IRQTIMEOUT 30000
static
void
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
unsigned
char
vector
;
struct
scc_channel
*
scc
;
...
...
@@ -653,7 +653,7 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs *regs)
if
(
k
==
SCC_IRQTIMEOUT
)
printk
(
KERN_WARNING
"z8530drv: endless loop in scc_isr()?
\n
"
);
return
;
return
IRQ_HANDLED
;
}
/* Find the SCC generating the interrupt by polling all attached SCCs
...
...
@@ -701,6 +701,7 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs *regs)
}
else
ctrl
++
;
}
return
IRQ_HANDLED
;
}
...
...
drivers/net/myri_sbus.c
View file @
81c830a4
...
...
@@ -541,6 +541,7 @@ static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct
myri_channel
*
chan
=
&
mp
->
shmem
->
channel
;
unsigned
long
flags
;
u32
status
;
int
handled
=
0
;
spin_lock_irqsave
(
&
mp
->
irq_lock
,
flags
);
...
...
@@ -549,6 +550,7 @@ static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if
(
status
&
ISTAT_HOST
)
{
u32
softstate
;
handled
=
1
;
DIRQ
((
"IRQ_DISAB "
));
myri_disable_irq
(
lregs
,
mp
->
cregs
);
softstate
=
sbus_readl
(
&
chan
->
state
);
...
...
@@ -568,7 +570,7 @@ static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore
(
&
mp
->
irq_lock
,
flags
);
return
IRQ_
HANDLED
;
return
IRQ_
RETVAL
(
handled
)
;
}
static
int
myri_open
(
struct
net_device
*
dev
)
...
...
drivers/net/ppp_synctty.c
View file @
81c830a4
...
...
@@ -202,7 +202,6 @@ ppp_sync_open(struct tty_struct *tty)
struct
syncppp
*
ap
;
int
err
;
MOD_INC_USE_COUNT
;
ap
=
kmalloc
(
sizeof
(
*
ap
),
GFP_KERNEL
);
err
=
-
ENOMEM
;
if
(
ap
==
0
)
...
...
@@ -236,7 +235,6 @@ ppp_sync_open(struct tty_struct *tty)
out_free:
kfree
(
ap
);
out:
MOD_DEC_USE_COUNT
;
return
err
;
}
...
...
@@ -276,7 +274,6 @@ ppp_sync_close(struct tty_struct *tty)
if
(
ap
->
tpkt
!=
0
)
kfree_skb
(
ap
->
tpkt
);
kfree
(
ap
);
MOD_DEC_USE_COUNT
;
}
/*
...
...
@@ -404,6 +401,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
static
struct
tty_ldisc
ppp_sync_ldisc
=
{
.
owner
=
THIS_MODULE
,
.
magic
=
TTY_LDISC_MAGIC
,
.
name
=
"pppsync"
,
.
open
=
ppp_sync_open
,
...
...
drivers/net/seeq8005.c
View file @
81c830a4
...
...
@@ -84,7 +84,7 @@ static int seeq8005_probe1(struct net_device *dev, int ioaddr);
static
int
seeq8005_open
(
struct
net_device
*
dev
);
static
void
seeq8005_timeout
(
struct
net_device
*
dev
);
static
int
seeq8005_send_packet
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
void
seeq8005_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
irqreturn_t
seeq8005_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
void
seeq8005_rx
(
struct
net_device
*
dev
);
static
int
seeq8005_close
(
struct
net_device
*
dev
);
static
struct
net_device_stats
*
seeq8005_get_stats
(
struct
net_device
*
dev
);
...
...
@@ -400,11 +400,12 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
/* The typical workload of the driver:
Handle the network interface interrupts. */
static
void
seeq8005_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
seeq8005_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
dev_id
;
struct
net_local
*
lp
;
int
ioaddr
,
status
,
boguscount
=
0
;
int
handled
=
0
;
ioaddr
=
dev
->
base_addr
;
lp
=
(
struct
net_local
*
)
dev
->
priv
;
...
...
@@ -416,17 +417,20 @@ static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs)
}
if
(
status
&
SEEQSTAT_WINDOW_INT
)
{
handled
=
1
;
outw
(
SEEQCMD_WINDOW_INT_ACK
|
(
status
&
SEEQCMD_INT_MASK
),
SEEQ_CMD
);
if
(
net_debug
)
{
printk
(
"%s: window int!
\n
"
,
dev
->
name
);
}
}
if
(
status
&
SEEQSTAT_TX_INT
)
{
handled
=
1
;
outw
(
SEEQCMD_TX_INT_ACK
|
(
status
&
SEEQCMD_INT_MASK
),
SEEQ_CMD
);
lp
->
stats
.
tx_packets
++
;
netif_wake_queue
(
dev
);
/* Inform upper layers. */
}
if
(
status
&
SEEQSTAT_RX_INT
)
{
handled
=
1
;
/* Got a packet(s). */
seeq8005_rx
(
dev
);
}
...
...
@@ -436,6 +440,7 @@ static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if
(
net_debug
>
2
)
{
printk
(
"%s: eoi
\n
"
,
dev
->
name
);
}
return
IRQ_RETVAL
(
handled
);
}
/* We have a good packet(s), get it/them out of the buffers. */
...
...
drivers/net/sunqe.c
View file @
81c830a4
...
...
@@ -124,6 +124,7 @@ static void qe_init_rings(struct sunqe *qep)
qb
->
qe_rxd
[
i
].
rx_flags
=
(
RXD_OWN
|
((
RXD_PKT_SZ
)
&
RXD_LENGTH
));
}
return
IRQ_HANDLED
;
}
static
int
qe_init
(
struct
sunqe
*
qep
,
int
from_irq
)
...
...
drivers/net/tokenring/lanstreamer.c
View file @
81c830a4
...
...
@@ -201,7 +201,7 @@ static int streamer_open(struct net_device *dev);
static
int
streamer_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
);
static
int
streamer_close
(
struct
net_device
*
dev
);
static
void
streamer_set_rx_mode
(
struct
net_device
*
dev
);
static
void
streamer_interrupt
(
int
irq
,
void
*
dev_id
,
static
irqreturn_t
streamer_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
struct
net_device_stats
*
streamer_get_stats
(
struct
net_device
*
dev
);
static
int
streamer_set_mac_address
(
struct
net_device
*
dev
,
void
*
addr
);
...
...
@@ -1021,7 +1021,7 @@ static void streamer_rx(struct net_device *dev)
}
/* end for all completed rx descriptors */
}
static
void
streamer_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
streamer_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_id
;
struct
streamer_private
*
streamer_priv
=
...
...
@@ -1142,6 +1142,7 @@ static void streamer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
/* while() */
spin_unlock
(
&
streamer_priv
->
streamer_lock
)
;
return
IRQ_HANDLED
;
}
static
int
streamer_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
...
...
drivers/net/tulip/de4x5.c
View file @
81c830a4
...
...
@@ -2027,7 +2027,7 @@ set_multicast_list(struct net_device *dev)
}
}
return
;
return
IRQ_HANDLED
;
}
/*
...
...
drivers/net/wan/lmc/lmc_main.c
View file @
81c830a4
...
...
@@ -117,7 +117,7 @@ static int lmc_rx (struct net_device *dev);
static
int
lmc_open
(
struct
net_device
*
dev
);
static
int
lmc_close
(
struct
net_device
*
dev
);
static
struct
net_device_stats
*
lmc_get_stats
(
struct
net_device
*
dev
);
static
void
lmc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
irqreturn_t
lmc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
int
lmc_set_config
(
struct
net_device
*
dev
,
struct
ifmap
*
map
);
static
void
lmc_initcsrs
(
lmc_softc_t
*
const
sc
,
lmc_csrptr_t
csr_base
,
size_t
csr_size
);
static
void
lmc_softreset
(
lmc_softc_t
*
const
);
...
...
@@ -1388,7 +1388,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
/* Interrupt handling routine. This will take an incoming packet, or clean
* up after a trasmit.
*/
static
void
lmc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
/*fold00*/
static
irqreturn_t
lmc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
/*fold00*/
{
struct
net_device
*
dev
=
(
struct
net_device
*
)
dev_instance
;
lmc_softc_t
*
sc
;
...
...
@@ -1398,6 +1398,7 @@ static void lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*
unsigned
int
badtx
;
u32
firstcsr
;
int
max_work
=
LMC_RXDESCS
;
int
handled
=
0
;
lmc_trace
(
dev
,
"lmc_interrupt in"
);
...
...
@@ -1421,6 +1422,8 @@ static void lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*
/* always go through this loop at least once */
while
(
csr
&
sc
->
lmc_intrmask
)
{
handled
=
1
;
/*
* Clear interrupt bits, we handle all case below
*/
...
...
@@ -1580,6 +1583,7 @@ static void lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*
spin_unlock
(
&
sc
->
lmc_lock
);
lmc_trace
(
dev
,
"lmc_interrupt out"
);
return
IRQ_RETVAL
(
handled
);
}
static
int
lmc_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
)
/*fold00*/
...
...
drivers/net/wireless/airport.c
View file @
81c830a4
...
...
@@ -275,15 +275,11 @@ init_airport(void)
printk
(
KERN_DEBUG
"%s
\n
"
,
version
);
MOD_INC_USE_COUNT
;
/* Lookup card in device tree */
airport_node
=
find_devices
(
"radio"
);
if
(
airport_node
&&
!
strcmp
(
airport_node
->
parent
->
name
,
"mac-io"
))
airport_dev
=
airport_attach
(
airport_node
);
MOD_DEC_USE_COUNT
;
return
airport_dev
?
0
:
-
ENODEV
;
}
...
...
include/linux/arcdevice.h
View file @
81c830a4
...
...
@@ -329,7 +329,7 @@ void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc);
#endif
void
arcnet_unregister_proto
(
struct
ArcProto
*
proto
);
void
arcnet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
irqreturn_t
arcnet_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
void
arcdev_setup
(
struct
net_device
*
dev
);
void
arcnet_rx
(
struct
net_device
*
dev
,
int
bufnum
);
...
...
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