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
7f4174f1
Commit
7f4174f1
authored
Feb 02, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-scsi.bkbits.net/scsi-for-linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
3b76b263
edf68308
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
483 additions
and
1717 deletions
+483
-1717
drivers/net/3c509.c
drivers/net/3c509.c
+132
-110
drivers/net/Space.c
drivers/net/Space.c
+3
-0
drivers/net/e100/Makefile
drivers/net/e100/Makefile
+1
-1
drivers/net/e100/e100.h
drivers/net/e100/e100.h
+0
-14
drivers/net/e100/e100_main.c
drivers/net/e100/e100_main.c
+93
-234
drivers/net/e100/e100_proc.c
drivers/net/e100/e100_proc.c
+0
-474
drivers/net/e1000/Makefile
drivers/net/e1000/Makefile
+1
-2
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000.h
+0
-3
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_ethtool.c
+98
-21
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_main.c
+18
-51
drivers/net/e1000/e1000_proc.c
drivers/net/e1000/e1000_proc.c
+0
-702
drivers/net/tg3.c
drivers/net/tg3.c
+129
-105
drivers/net/tg3.h
drivers/net/tg3.h
+5
-0
include/linux/pci_ids.h
include/linux/pci_ids.h
+3
-0
No files found.
drivers/net/3c509.c
View file @
7f4174f1
...
...
@@ -103,6 +103,10 @@ static int el3_debug = EL3_DEBUG;
static
int
el3_debug
=
2
;
#endif
/* Used to do a global count of all the cards in the system. Must be
* a global variable so that the mca/eisa probe routines can increment
* it */
static
int
el3_cards
=
0
;
/* To minimize the size of the driver source I only define operating
constants if they are used several times. You'll need the manual
...
...
@@ -167,16 +171,15 @@ struct el3_private {
/* skb send-queue */
int
head
,
size
;
struct
sk_buff
*
queue
[
SKB_QUEUE_SIZE
];
char
mca_slot
;
#ifdef CONFIG_PM
struct
pm_dev
*
pmdev
;
#endif
#ifdef __ISAPNP__
struct
pnp_dev
*
pnpdev
;
#endif
#ifdef CONFIG_EISA
struct
eisa_device
*
edev
;
#endif
enum
{
EL3_MCA
,
EL3_PNP
,
EL3_EISA
,
}
type
;
/* type of device */
struct
device
*
dev
;
};
static
int
id_port
__initdata
=
0x110
;
/* Start with 0x110 to avoid new sound cards.*/
static
struct
net_device
*
el3_root_dev
;
...
...
@@ -200,6 +203,8 @@ static int el3_suspend(struct pm_dev *pdev);
static
int
el3_resume
(
struct
pm_dev
*
pdev
);
static
int
el3_pm_callback
(
struct
pm_dev
*
pdev
,
pm_request_t
rqst
,
void
*
data
);
#endif
/* generic device remove for all device types */
static
int
el3_device_remove
(
struct
device
*
device
);
#ifdef CONFIG_EISA
struct
eisa_device_id
el3_eisa_ids
[]
=
{
...
...
@@ -209,31 +214,46 @@ struct eisa_device_id el3_eisa_ids[] = {
};
static
int
el3_eisa_probe
(
struct
device
*
device
);
static
int
el3_eisa_remove
(
struct
device
*
device
);
struct
eisa_driver
el3_eisa_driver
=
{
.
id_table
=
el3_eisa_ids
,
.
driver
=
{
.
name
=
"3c509"
,
.
probe
=
el3_eisa_probe
,
.
remove
=
__devexit_p
(
el3_
eisa
_remove
)
.
remove
=
__devexit_p
(
el3_
device
_remove
)
}
};
#endif
#ifdef CONFIG_MCA
struct
el3_mca_adapters_struct
{
char
*
name
;
int
id
;
static
int
el3_mca_probe
(
struct
device
*
dev
);
static
short
el3_mca_adapter_ids
[]
__initdata
=
{
0x627c
,
0x627d
,
0x62db
,
0x62f6
,
0x62f7
,
0x0000
};
static
struct
el3_mca_adapters_struct
el3_mca_adapters
[]
__initdata
=
{
{
"3Com 3c529 EtherLink III (10base2)"
,
0x627c
},
{
"3Com 3c529 EtherLink III (10baseT)"
,
0x627d
},
{
"3Com 3c529 EtherLink III (test mode)"
,
0x62db
},
{
"3Com 3c529 EtherLink III (TP or coax)"
,
0x62f6
},
{
"3Com 3c529 EtherLink III (TP)"
,
0x62f7
},
{
NULL
,
0
},
static
char
*
el3_mca_adapter_names
[]
__initdata
=
{
"3Com 3c529 EtherLink III (10base2)"
,
"3Com 3c529 EtherLink III (10baseT)"
,
"3Com 3c529 EtherLink III (test mode)"
,
"3Com 3c529 EtherLink III (TP or coax)"
,
"3Com 3c529 EtherLink III (TP)"
,
NULL
};
static
struct
mca_driver
el3_mca_driver
=
{
.
id_table
=
el3_mca_adapter_ids
,
.
driver
=
{
.
name
=
"3c529"
,
.
bus
=
&
mca_bus_type
,
.
probe
=
el3_mca_probe
,
.
remove
=
__devexit_p
(
el3_device_remove
),
},
};
#endif
/* CONFIG_MCA */
...
...
@@ -264,12 +284,12 @@ static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
};
static
u16
el3_isapnp_phys_addr
[
8
][
3
];
#endif
/* __ISAPNP__ */
static
int
nopnp
;
#endif
/* __ISAPNP__ */
/* With the driver model introduction for EISA devices, both init
* and cleanup have been split :
* - EISA devices probe/remove starts in el3_eisa_probe/el3_
eisa
_remove
* - EISA devices probe/remove starts in el3_eisa_probe/el3_
device
_remove
* - MCA/ISA still use el3_probe
*
* Both call el3_common_init/el3_common_remove. */
...
...
@@ -278,10 +298,9 @@ static int __init el3_common_init (struct net_device *dev)
{
struct
el3_private
*
lp
=
dev
->
priv
;
short
i
;
#ifdef CONFIG_EISA
if
(
!
lp
->
edev
)
/* EISA devices are not chained */
#endif
el3_cards
++
;
if
(
!
lp
->
dev
)
/* probed devices are not chained */
{
lp
->
next_dev
=
el3_root_dev
;
el3_root_dev
=
dev
;
...
...
@@ -337,17 +356,13 @@ static void el3_common_remove (struct net_device *dev)
struct
el3_private
*
lp
=
dev
->
priv
;
(
void
)
lp
;
/* Keep gcc quiet... */
#ifdef CONFIG_MCA
if
(
lp
->
mca_slot
!=-
1
)
mca_mark_as_unused
(
lp
->
mca_slot
);
#endif
#ifdef CONFIG_PM
if
(
lp
->
pmdev
)
pm_unregister
(
lp
->
pmdev
);
#endif
#ifdef __ISAPNP__
if
(
lp
->
pnpdev
)
pnp_device_detach
(
lp
->
pnpdev
);
if
(
lp
->
type
==
EL3_PNP
)
pnp_device_detach
(
to_pnp_dev
(
lp
->
dev
)
);
#endif
unregister_netdev
(
dev
);
...
...
@@ -363,76 +378,11 @@ static int __init el3_probe(int card_idx)
int
ioaddr
,
irq
,
if_port
;
u16
phys_addr
[
3
];
static
int
current_tag
;
int
mca_slot
=
-
1
;
#ifdef __ISAPNP__
static
int
pnp_cards
;
struct
pnp_dev
*
idev
=
NULL
;
#endif
/* __ISAPNP__ */
#ifdef CONFIG_MCA
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
* modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
* to support standard MCA probing.
*
* redone for multi-card detection by ZP Gu (zpg@castle.net)
* now works as a module
*/
if
(
MCA_bus
)
{
int
slot
,
j
;
u_char
pos4
,
pos5
;
for
(
j
=
0
;
el3_mca_adapters
[
j
].
name
!=
NULL
;
j
++
)
{
slot
=
0
;
while
(
slot
!=
MCA_NOTFOUND
)
{
slot
=
mca_find_unused_adapter
(
el3_mca_adapters
[
j
].
id
,
slot
);
if
(
slot
==
MCA_NOTFOUND
)
break
;
/* if we get this far, an adapter has been
* detected and is enabled
*/
pos4
=
mca_read_stored_pos
(
slot
,
4
);
pos5
=
mca_read_stored_pos
(
slot
,
5
);
ioaddr
=
((
short
)((
pos4
&
0xfc
)
|
0x02
))
<<
8
;
irq
=
pos5
&
0x0f
;
/* probing for a card at a particular IO/IRQ */
if
(
dev
&&
((
dev
->
irq
>=
1
&&
dev
->
irq
!=
irq
)
||
(
dev
->
base_addr
>=
1
&&
dev
->
base_addr
!=
ioaddr
)))
{
slot
++
;
/* probing next slot */
continue
;
}
printk
(
"3c509: found %s at slot %d
\n
"
,
el3_mca_adapters
[
j
].
name
,
slot
+
1
);
/* claim the slot */
mca_set_adapter_name
(
slot
,
el3_mca_adapters
[
j
].
name
);
mca_set_adapter_procfn
(
slot
,
NULL
,
NULL
);
mca_mark_as_used
(
slot
);
if_port
=
pos4
&
0x03
;
if
(
el3_debug
>
2
)
{
printk
(
"3c529: irq %d ioaddr 0x%x ifport %d
\n
"
,
irq
,
ioaddr
,
if_port
);
}
EL3WINDOW
(
0
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
phys_addr
[
i
]
=
htons
(
read_eeprom
(
ioaddr
,
i
));
}
mca_slot
=
slot
;
goto
found
;
}
}
/* if we get here, we didn't find an MCA adapter */
return
-
ENODEV
;
}
#endif
/* CONFIG_MCA */
#ifdef __ISAPNP__
if
(
nopnp
==
1
)
goto
no_pnp
;
...
...
@@ -580,7 +530,7 @@ static int __init el3_probe(int card_idx)
/* Free the interrupt so that some other card can use it. */
outw
(
0x0f00
,
ioaddr
+
WN0_IRQ
);
found:
dev
=
init_etherdev
(
NULL
,
sizeof
(
struct
el3_private
));
if
(
dev
==
NULL
)
{
release_region
(
ioaddr
,
EL3_IO_EXTENT
);
...
...
@@ -594,13 +544,80 @@ static int __init el3_probe(int card_idx)
dev
->
if_port
=
if_port
;
lp
=
dev
->
priv
;
#ifdef __ISAPNP__
lp
->
pnpdev
=
i
dev
;
lp
->
dev
=
&
idev
->
dev
;
#endif
lp
->
mca_slot
=
mca_slot
;
return
el3_common_init
(
dev
);
}
#ifdef CONFIG_MCA
static
int
__init
el3_mca_probe
(
struct
device
*
device
)
{
/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
* heavily modified by Chris Beauregard
* (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
* probing.
*
* redone for multi-card detection by ZP Gu (zpg@castle.net)
* now works as a module */
struct
el3_private
*
lp
;
short
i
;
int
ioaddr
,
irq
,
if_port
;
u16
phys_addr
[
3
];
struct
net_device
*
dev
=
NULL
;
u_char
pos4
,
pos5
;
struct
mca_device
*
mdev
=
to_mca_device
(
device
);
int
slot
=
mdev
->
slot
;
pos4
=
mca_device_read_stored_pos
(
mdev
,
4
);
pos5
=
mca_device_read_stored_pos
(
mdev
,
5
);
ioaddr
=
((
short
)((
pos4
&
0xfc
)
|
0x02
))
<<
8
;
irq
=
pos5
&
0x0f
;
printk
(
"3c529: found %s at slot %d
\n
"
,
el3_mca_adapter_names
[
mdev
->
index
],
slot
+
1
);
/* claim the slot */
strncpy
(
device
->
name
,
el3_mca_adapter_names
[
mdev
->
index
],
sizeof
(
device
->
name
));
mca_device_set_claim
(
mdev
,
1
);
if_port
=
pos4
&
0x03
;
irq
=
mca_device_transform_irq
(
mdev
,
irq
);
ioaddr
=
mca_device_transform_ioport
(
mdev
,
ioaddr
);
if
(
el3_debug
>
2
)
{
printk
(
"3c529: irq %d ioaddr 0x%x ifport %d
\n
"
,
irq
,
ioaddr
,
if_port
);
}
EL3WINDOW
(
0
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
phys_addr
[
i
]
=
htons
(
read_eeprom
(
ioaddr
,
i
));
}
dev
=
init_etherdev
(
NULL
,
sizeof
(
struct
el3_private
));
if
(
dev
==
NULL
)
{
release_region
(
ioaddr
,
EL3_IO_EXTENT
);
return
-
ENOMEM
;
}
SET_MODULE_OWNER
(
dev
);
memcpy
(
dev
->
dev_addr
,
phys_addr
,
sizeof
(
phys_addr
));
dev
->
base_addr
=
ioaddr
;
dev
->
irq
=
irq
;
dev
->
if_port
=
if_port
;
lp
=
dev
->
priv
;
lp
->
dev
=
device
;
lp
->
type
=
EL3_MCA
;
device
->
driver_data
=
dev
;
return
el3_common_init
(
dev
);
}
#endif
/* CONFIG_MCA */
#ifdef CONFIG_EISA
static
int
__init
el3_eisa_probe
(
struct
device
*
device
)
{
...
...
@@ -642,25 +659,26 @@ static int __init el3_eisa_probe (struct device *device)
dev
->
irq
=
irq
;
dev
->
if_port
=
if_port
;
lp
=
dev
->
priv
;
lp
->
mca_slot
=
-
1
;
lp
->
edev
=
edev
;
lp
->
dev
=
device
;
lp
->
type
=
EL3_EISA
;
eisa_set_drvdata
(
edev
,
dev
);
return
el3_common_init
(
dev
);
}
#endif
static
int
__devexit
el3_eisa_remove
(
struct
device
*
device
)
/* This remove works for all device types.
*
* The net dev must be stored in the driver_data field */
static
int
__devexit
el3_device_remove
(
struct
device
*
device
)
{
struct
eisa_device
*
edev
;
struct
net_device
*
dev
;
edev
=
to_eisa_device
(
device
);
dev
=
eisa_get_drvdata
(
edev
);
dev
=
device
->
driver_data
;
el3_common_remove
(
dev
);
return
0
;
}
#endif
/* Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
...
...
@@ -1080,7 +1098,7 @@ el3_close(struct net_device *dev)
free_irq
(
dev
->
irq
,
dev
);
/* Switching back to window 0 disables the IRQ. */
EL3WINDOW
(
0
);
if
(
!
lp
->
edev
)
{
if
(
lp
->
type
!=
EL3_EISA
)
{
/* But we explicitly zero the IRQ line select anyway. Don't do
* it on EISA cards, it prevents the module from getting an
* IRQ after unload+reload... */
...
...
@@ -1530,7 +1548,7 @@ MODULE_LICENSE("GPL");
static
int
__init
el3_init_module
(
void
)
{
int
el3_cards
=
0
;
el3_cards
=
0
;
if
(
debug
>=
0
)
el3_debug
=
debug
;
...
...
@@ -1548,8 +1566,9 @@ static int __init el3_init_module(void)
if
(
eisa_driver_register
(
&
el3_eisa_driver
)
<
0
)
{
eisa_driver_unregister
(
&
el3_eisa_driver
);
}
else
el3_cards
++
;
/* Found an eisa card */
#endif
#ifdef CONFIG_MCA
mca_register_driver
(
&
el3_mca_driver
);
#endif
return
el3_cards
?
0
:
-
ENODEV
;
}
...
...
@@ -1569,6 +1588,9 @@ static void __exit el3_cleanup_module(void)
#ifdef CONFIG_EISA
eisa_driver_unregister
(
&
el3_eisa_driver
);
#endif
#ifdef CONFIG_MCA
mca_unregister_driver
(
&
el3_mca_driver
);
#endif
}
module_init
(
el3_init_module
);
...
...
drivers/net/Space.c
View file @
7f4174f1
...
...
@@ -224,6 +224,9 @@ static struct devprobe isa_probes[] __initdata = {
#ifdef CONFIG_EL2
/* 3c503 */
{
el2_probe
,
0
},
#endif
#ifdef CONFIG_EL3
{
el3_probe
,
0
},
#endif
#ifdef CONFIG_HPLAN
{
hp_probe
,
0
},
#endif
...
...
drivers/net/e100/Makefile
View file @
7f4174f1
...
...
@@ -4,5 +4,5 @@
obj-$(CONFIG_E100)
+=
e100.o
e100-objs
:=
e100_main.o e100_config.o e100_p
roc.o e100_p
hy.o
\
e100-objs
:=
e100_main.o e100_config.o e100_phy.o
\
e100_eeprom.o e100_test.o
drivers/net/e100/e100.h
View file @
7f4174f1
...
...
@@ -56,7 +56,6 @@
#include <linux/if.h>
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/ip.h>
#define E100_REGS_LEN 1
...
...
@@ -926,20 +925,7 @@ struct e100_private {
struct
cfg_params
params
;
/* adapter's command line parameters */
struct
proc_dir_entry
*
proc_parent
;
char
*
id_string
;
char
*
cable_status
;
char
*
mdix_status
;
/* Variables for HWI */
int
saved_open_circut
;
int
saved_short_circut
;
int
saved_distance
;
int
saved_i
;
int
saved_same
;
unsigned
char
hwi_started
;
struct
timer_list
hwi_timer
;
/* hwi timer id */
u32
speed_duplex_caps
;
/* adapter's speed/duplex capabilities */
...
...
drivers/net/e100/e100_main.c
View file @
7f4174f1
...
...
@@ -83,13 +83,15 @@
#include "e100_phy.h"
#include "e100_vendor.h"
#ifdef CONFIG_PROC_FS
extern
int
e100_create_proc_subdir
(
struct
e100_private
*
,
char
*
);
extern
void
e100_remove_proc_subdir
(
struct
e100_private
*
,
char
*
);
#else
#define e100_create_proc_subdir(X, Y) 0
#define e100_remove_proc_subdir(X, Y) do {} while(0)
#endif
static
char
e100_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"
,
};
#define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
static
int
e100_do_ethtool_ioctl
(
struct
net_device
*
,
struct
ifreq
*
);
static
void
e100_get_speed_duplex_caps
(
struct
e100_private
*
);
...
...
@@ -135,7 +137,7 @@ static void e100_non_tx_background(unsigned long);
/* Global Data structures and variables */
char
e100_copyright
[]
__devinitdata
=
"Copyright (c) 2002 Intel Corporation"
;
char
e100_driver_version
[]
=
"2.1.29-k
1
"
;
char
e100_driver_version
[]
=
"2.1.29-k
4
"
;
const
char
*
e100_full_driver_name
=
"Intel(R) PRO/100 Network Driver"
;
char
e100_short_driver_name
[]
=
"e100"
;
static
int
e100nics
=
0
;
...
...
@@ -150,15 +152,6 @@ struct notifier_block e100_notifier_reboot = {
.
priority
=
0
};
#endif
static
int
e100_notify_netdev
(
struct
notifier_block
*
,
unsigned
long
event
,
void
*
ptr
);
struct
notifier_block
e100_notifier_netdev
=
{
.
notifier_call
=
e100_notify_netdev
,
.
next
=
NULL
,
.
priority
=
0
};
static
void
e100_get_mdix_status
(
struct
e100_private
*
bdp
);
/*********************************************************************/
/*! This is a GCC extension to ANSI C.
...
...
@@ -196,6 +189,7 @@ void e100_set_speed_duplex(struct e100_private *);
char
*
e100_get_brand_msg
(
struct
e100_private
*
);
static
u8
e100_pci_setup
(
struct
pci_dev
*
,
struct
e100_private
*
);
static
u8
e100_sw_init
(
struct
e100_private
*
);
static
void
e100_tco_workaround
(
struct
e100_private
*
);
static
unsigned
char
e100_alloc_space
(
struct
e100_private
*
);
static
void
e100_dealloc_space
(
struct
e100_private
*
);
static
int
e100_alloc_tcb_pool
(
struct
e100_private
*
);
...
...
@@ -213,7 +207,7 @@ 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
*
,
u32
);
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
);
...
...
@@ -349,8 +343,6 @@ void e100_tx_srv(struct e100_private *);
u32
e100_rx_srv
(
struct
e100_private
*
);
void
e100_watchdog
(
struct
net_device
*
);
static
void
e100_do_hwi
(
struct
net_device
*
);
static
void
e100_hwi_restore
(
struct
e100_private
*
);
void
e100_refresh_txthld
(
struct
e100_private
*
);
void
e100_manage_adaptive_ifs
(
struct
e100_private
*
);
void
e100_clear_pools
(
struct
e100_private
*
);
...
...
@@ -610,10 +602,6 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp
->
watchdog_timer
.
data
=
(
unsigned
long
)
dev
;
bdp
->
watchdog_timer
.
function
=
(
void
*
)
&
e100_watchdog
;
init_timer
(
&
bdp
->
hwi_timer
);
bdp
->
hwi_timer
.
data
=
(
unsigned
long
)
dev
;
bdp
->
hwi_timer
.
function
=
(
void
*
)
&
e100_do_hwi
;
if
((
rc
=
e100_pci_setup
(
pcid
,
bdp
))
!=
0
)
{
goto
err_dealloc
;
}
...
...
@@ -686,21 +674,6 @@ e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
bdp
->
device
->
name
,
e100_get_brand_msg
(
bdp
));
e100_print_brd_conf
(
bdp
);
bdp
->
id_string
=
e100_get_brand_msg
(
bdp
);
e100_get_mdix_status
(
bdp
);
if
(
netif_carrier_ok
(
bdp
->
device
))
bdp
->
cable_status
=
"Cable OK"
;
else
{
if
(
bdp
->
rev_id
<
D102_REV_ID
)
bdp
->
cable_status
=
"Not supported"
;
else
bdp
->
cable_status
=
"Not available"
;
}
if
(
e100_create_proc_subdir
(
bdp
,
bdp
->
ifname
)
<
0
)
{
printk
(
KERN_ERR
"e100: Failed to create proc dir for %s
\n
"
,
bdp
->
device
->
name
);
}
bdp
->
wolsupported
=
0
;
bdp
->
wolopts
=
0
;
...
...
@@ -766,8 +739,6 @@ e100_remove1(struct pci_dev *pcid)
unregister_netdev
(
dev
);
e100_remove_proc_subdir
(
bdp
,
bdp
->
ifname
);
e100_sw_reset
(
bdp
,
PORT_SELECTIVE_RESET
);
if
(
bdp
->
non_tx_command_state
!=
E100_NON_TX_IDLE
)
{
...
...
@@ -804,7 +775,6 @@ e100_init_module(void)
#ifdef CONFIG_PM
register_reboot_notifier
(
&
e100_notifier_reboot
);
#endif
register_netdevice_notifier
(
&
e100_notifier_netdev
);
}
return
ret
;
...
...
@@ -816,7 +786,6 @@ e100_cleanup_module(void)
#ifdef CONFIG_PM
unregister_reboot_notifier
(
&
e100_notifier_reboot
);
#endif
unregister_netdevice_notifier
(
&
e100_notifier_netdev
);
pci_unregister_driver
(
&
e100_driver
);
}
...
...
@@ -1265,7 +1234,7 @@ e100_init(struct e100_private *bdp)
/* read NIC's part number */
e100_rd_pwa_no
(
bdp
);
if
(
!
e100_hw_init
(
bdp
,
PORT_SOFTWARE_RESET
))
{
if
(
!
e100_hw_init
(
bdp
))
{
printk
(
KERN_ERR
"e100: hw init failed
\n
"
);
return
false
;
}
...
...
@@ -1314,10 +1283,46 @@ e100_sw_init(struct e100_private *bdp)
return
1
;
}
static
void
__devinit
e100_tco_workaround
(
struct
e100_private
*
bdp
)
{
int
i
;
/* Do software reset */
e100_sw_reset
(
bdp
,
PORT_SOFTWARE_RESET
);
/* Do a dummy LOAD CU BASE command. */
/* This gets us out of pre-driver to post-driver. */
e100_exec_cmplx
(
bdp
,
0
,
SCB_CUC_LOAD_BASE
);
/* Wait 20 msec for reset to take effect */
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
50
+
1
);
/* disable interrupts since they are enabled */
/* after device reset */
e100_disable_clear_intr
(
bdp
);
/* Wait for command to be cleared up to 1 sec */
for
(
i
=
0
;
i
<
100
;
i
++
)
{
if
(
!
readb
(
&
bdp
->
scb
->
scb_cmd_low
))
break
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
+
1
);
}
/* Wait for TCO request bit in PMDR register to be clear */
for
(
i
=
0
;
i
<
50
;
i
++
)
{
if
(
!
(
readb
(
&
bdp
->
scb
->
scb_ext
.
d101m_scb
.
scb_pmdr
)
&
BIT_1
))
break
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
+
1
);
}
}
/**
* e100_hw_init - initialized tthe hardware
* @bdp: atapter's private data struct
* @reset_cmd: s/w reset or selective reset
*
* This routine performs a reset on the adapter, and configures the adapter.
* This includes configuring the 82557 LAN controller, validating and setting
...
...
@@ -1329,13 +1334,16 @@ e100_sw_init(struct e100_private *bdp)
* false - If the adapter failed initialization
*/
unsigned
char
__devinit
e100_hw_init
(
struct
e100_private
*
bdp
,
u32
reset_cmd
)
e100_hw_init
(
struct
e100_private
*
bdp
)
{
if
(
!
e100_phy_init
(
bdp
))
return
false
;
/* Issue a software reset to the e100 */
e100_sw_reset
(
bdp
,
reset_cmd
);
e100_sw_reset
(
bdp
,
PORT_SELECTIVE_RESET
);
/* Only 82559 or above needs TCO workaround */
if
(
bdp
->
rev_id
>=
D101MA_REV_ID
)
e100_tco_workaround
(
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
))
...
...
@@ -1391,6 +1399,7 @@ e100_setup_tcb_pool(tcb_t *head, unsigned int qlen, struct e100_private *bdp)
u32
next_phys
;
/* the next phys addr */
u16
txcommand
=
CB_S_BIT
|
CB_TX_SF_BIT
;
bdp
->
tx_count
=
0
;
if
(
bdp
->
flags
&
USE_IPCB
)
{
txcommand
|=
CB_IPCB_TRANSMIT
|
CB_CID_DEFAULT
;
}
else
if
(
bdp
->
flags
&
IS_BACHELOR
)
{
...
...
@@ -1634,7 +1643,6 @@ e100_watchdog(struct net_device *dev)
if
(
!
netif_running
(
dev
))
{
return
;
}
e100_get_mdix_status
(
bdp
);
/* check if link state has changed */
if
(
e100_phy_check
(
bdp
))
{
...
...
@@ -1647,37 +1655,10 @@ e100_watchdog(struct net_device *dev)
e100_config_fc
(
bdp
);
e100_config
(
bdp
);
bdp
->
cable_status
=
"Cable OK"
;
}
else
{
printk
(
KERN_ERR
"e100: %s NIC Link is Down
\n
"
,
bdp
->
device
->
name
);
if
(
bdp
->
rev_id
<
D102_REV_ID
)
bdp
->
cable_status
=
"Not supported"
;
else
{
/* Initiate hwi, ie, cable diagnostic */
bdp
->
saved_open_circut
=
0xffff
;
bdp
->
saved_short_circut
=
0xffff
;
bdp
->
saved_distance
=
0xffff
;
bdp
->
saved_i
=
0
;
bdp
->
saved_same
=
0
;
bdp
->
hwi_started
=
1
;
/* 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 hwi test */
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
BMCR_SPEED100
|
BMCR_FULLDPLX
);
/* Enable and execute HWI test */
e100_mdi_write
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
(
HWI_TEST_ENABLE
|
HWI_TEST_EXECUTE
));
/* Launch hwi timer in 1 msec */
mod_timer
(
&
(
bdp
->
hwi_timer
),
jiffies
+
(
HZ
/
1000
)
);
}
}
}
...
...
@@ -1836,10 +1817,8 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
bdp
->
drv_stats
.
rx_intr_pkts
+=
e100_rx_srv
(
bdp
);
/* clean up after tx'ed packets */
if
(
intr_status
&
(
SCB_STATUS_ACK_CNA
|
SCB_STATUS_ACK_CX
))
{
bdp
->
tx_count
=
0
;
/* restart tx interrupt batch count */
if
(
intr_status
&
(
SCB_STATUS_ACK_CNA
|
SCB_STATUS_ACK_CX
))
e100_tx_srv
(
bdp
);
}
e100_set_intr_mask
(
bdp
);
}
...
...
@@ -2147,11 +2126,12 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
tcb
->
tcb_thrshld
=
bdp
->
tx_thld
;
tcb
->
tcb_hdr
.
cb_cmd
|=
__constant_cpu_to_le16
(
CB_S_BIT
);
/* set the I bit on the modulo tcbs, so we will get an interrupt * to
* clean things up */
if
(
!
(
++
bdp
->
tx_count
%
TX_FRAME_CNT
))
{
/* Set I (Interrupt) bit on every (TX_FRAME_CNT)th packet */
if
(
!
(
++
bdp
->
tx_count
%
TX_FRAME_CNT
))
tcb
->
tcb_hdr
.
cb_cmd
|=
__constant_cpu_to_le16
(
CB_I_BIT
);
}
else
/* Clear I bit on other packets */
tcb
->
tcb_hdr
.
cb_cmd
&=
~
__constant_cpu_to_le16
(
CB_I_BIT
);
tcb
->
tcb_skb
=
skb
;
...
...
@@ -3054,12 +3034,6 @@ e100_isolate_driver(struct e100_private *bdp)
if
(
bdp
->
device
->
flags
&
IFF_UP
)
{
e100_disable_clear_intr
(
bdp
);
del_timer_sync
(
&
bdp
->
watchdog_timer
);
del_timer_sync
(
&
bdp
->
hwi_timer
);
/* If in middle of cable diag, */
if
(
bdp
->
hwi_started
)
{
bdp
->
hwi_started
=
0
;
e100_hwi_restore
(
bdp
);
}
netif_carrier_off
(
bdp
->
device
);
netif_stop_queue
(
bdp
->
device
);
bdp
->
last_tcb
=
NULL
;
...
...
@@ -3205,6 +3179,22 @@ e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
case
ETHTOOL_SEEPROM
:
rc
=
e100_ethtool_eeprom
(
dev
,
ifr
);
break
;
case
ETHTOOL_GSTATS
:
{
struct
{
struct
ethtool_stats
cmd
;
uint64_t
data
[
E100_STATS_LEN
];
}
stats
=
{
{
ETHTOOL_GSTATS
,
E100_STATS_LEN
}
};
struct
e100_private
*
bdp
=
dev
->
priv
;
void
*
addr
=
ifr
->
ifr_data
;
int
i
;
for
(
i
=
0
;
i
<
E100_STATS_LEN
;
i
++
)
stats
.
data
[
i
]
=
((
unsigned
long
*
)
&
bdp
->
drv_stats
.
net_stats
)[
i
];
if
(
copy_to_user
(
addr
,
&
stats
,
sizeof
(
stats
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GWOL
:
case
ETHTOOL_SWOL
:
rc
=
e100_ethtool_wol
(
dev
,
ifr
);
...
...
@@ -3456,6 +3446,7 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
sizeof
(
info
.
fw_version
)
-
1
);
strncpy
(
info
.
bus_info
,
bdp
->
pdev
->
slot_name
,
sizeof
(
info
.
bus_info
)
-
1
);
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
;
...
...
@@ -3816,6 +3807,19 @@ static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
test_strings
[
i
]);
}
break
;
case
ETH_SS_STATS
:
{
char
*
strings
=
NULL
;
void
*
addr
=
ifr
->
ifr_data
;
info
.
len
=
E100_STATS_LEN
;
strings
=
*
e100_gstrings_stats
;
if
(
copy_to_user
(
ifr
->
ifr_data
,
&
info
,
sizeof
(
info
)))
return
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_gstrings
,
data
);
if
(
copy_to_user
(
addr
,
strings
,
info
.
len
*
ETH_GSTRING_LEN
))
return
-
EFAULT
;
return
0
;
}
default:
return
-
EOPNOTSUPP
;
}
...
...
@@ -4054,29 +4058,6 @@ e100_non_tx_background(unsigned long ptr)
spin_unlock_bh
(
&
(
bdp
->
bd_non_tx_lock
));
}
int
e100_notify_netdev
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
p
)
{
struct
e100_private
*
bdp
;
struct
net_device
*
netdev
=
p
;
if
(
netdev
==
NULL
)
return
NOTIFY_DONE
;
switch
(
event
)
{
case
NETDEV_CHANGENAME
:
if
(
netdev
->
open
==
e100_open
)
{
bdp
=
netdev
->
priv
;
/* rename the proc nodes the easy way */
e100_remove_proc_subdir
(
bdp
,
bdp
->
ifname
);
memcpy
(
bdp
->
ifname
,
netdev
->
name
,
IFNAMSIZ
);
bdp
->
ifname
[
IFNAMSIZ
-
1
]
=
0
;
e100_create_proc_subdir
(
bdp
,
bdp
->
ifname
);
}
break
;
}
return
NOTIFY_DONE
;
}
#ifdef CONFIG_PM
static
int
e100_notify_reboot
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
p
)
...
...
@@ -4140,128 +4121,6 @@ e100_resume(struct pci_dev *pcid)
}
#endif
/* CONFIG_PM */
static
void
e100_get_mdix_status
(
struct
e100_private
*
bdp
)
{
if
(
bdp
->
rev_id
<
D102_REV_ID
)
{
if
(
netif_carrier_ok
(
bdp
->
device
))
bdp
->
mdix_status
=
"MDI"
;
else
bdp
->
mdix_status
=
"None"
;
}
else
{
u16
ctrl_reg
;
/* Read the MDIX control register */
e100_mdi_read
(
bdp
,
MII_NCONFIG
,
bdp
->
phy_addr
,
&
ctrl_reg
);
if
(
ctrl_reg
&
MDI_MDIX_CONFIG_IS_OK
)
{
if
(
ctrl_reg
&
MDI_MDIX_STATUS
)
bdp
->
mdix_status
=
"MDI-X"
;
else
bdp
->
mdix_status
=
"MDI"
;
}
else
bdp
->
mdix_status
=
"None"
;
}
}
static
void
e100_do_hwi
(
struct
net_device
*
dev
)
{
struct
e100_private
*
bdp
=
dev
->
priv
;
u16
ctrl_reg
;
int
distance
,
open_circut
,
short_circut
;
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
==
bdp
->
saved_distance
)
&&
(
open_circut
==
bdp
->
saved_open_circut
)
&&
(
short_circut
==
bdp
->
saved_short_circut
))
bdp
->
saved_same
++
;
else
{
bdp
->
saved_same
=
0
;
bdp
->
saved_distance
=
distance
;
bdp
->
saved_open_circut
=
open_circut
;
bdp
->
saved_short_circut
=
short_circut
;
}
if
(
bdp
->
saved_same
==
MAX_SAME_RESULTS
)
{
if
((
open_circut
&&
!
(
short_circut
))
||
(
!
(
open_circut
)
&&
short_circut
))
{
u8
near_end
=
((
distance
*
HWI_REGISTER_GRANULARITY
)
<
HWI_NEAR_END_BOUNDARY
);
if
(
open_circut
)
{
if
(
near_end
)
bdp
->
cable_status
=
"Open Circut Near End"
;
else
bdp
->
cable_status
=
"Open Circut Far End"
;
}
else
{
if
(
near_end
)
bdp
->
cable_status
=
"Short Circut Near End"
;
else
bdp
->
cable_status
=
"Short Circut Far End"
;
}
goto
done
;
}
}
else
if
(
bdp
->
saved_i
==
HWI_MAX_LOOP
)
{
bdp
->
cable_status
=
"Test failed"
;
goto
done
;
}
/* Do another hwi test */
e100_mdi_write
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
(
HWI_TEST_ENABLE
|
HWI_TEST_EXECUTE
));
bdp
->
saved_i
++
;
/* relaunch hwi timer in 1 msec */
mod_timer
(
&
(
bdp
->
hwi_timer
),
jiffies
+
(
HZ
/
1000
)
);
return
;
done:
e100_hwi_restore
(
bdp
);
bdp
->
hwi_started
=
0
;
return
;
}
static
void
e100_hwi_restore
(
struct
e100_private
*
bdp
)
{
u16
control
=
0
;
/* Restore speed, duplex and autoneg before */
/* hwi test, i.e., cable diagnostic */
/* Reset hwi test */
e100_mdi_write
(
bdp
,
HWI_CONTROL_REG
,
bdp
->
phy_addr
,
HWI_RESET_ALL_MASK
);
if
((
bdp
->
params
.
e100_speed_duplex
==
E100_AUTONEG
)
&&
(
bdp
->
rev_id
>=
D102_REV_ID
))
/* Enable MDI/MDI-X auto switching */
e100_mdi_write
(
bdp
,
MII_NCONFIG
,
bdp
->
phy_addr
,
MDI_MDIX_AUTO_SWITCH_ENABLE
);
switch
(
bdp
->
params
.
e100_speed_duplex
)
{
case
E100_SPEED_10_HALF
:
break
;
case
E100_SPEED_10_FULL
:
control
=
BMCR_FULLDPLX
;
break
;
case
E100_SPEED_100_HALF
:
control
=
BMCR_SPEED100
;
break
;
case
E100_SPEED_100_FULL
:
control
=
BMCR_SPEED100
|
BMCR_FULLDPLX
;
break
;
case
E100_AUTONEG
:
control
=
BMCR_ANENABLE
|
BMCR_ANRESTART
;
break
;
}
/* Restore original speed/duplex */
e100_mdi_write
(
bdp
,
MII_BMCR
,
bdp
->
phy_addr
,
control
);
return
;
}
#ifdef E100_CU_DEBUG
unsigned
char
e100_cu_unknown_state
(
struct
e100_private
*
bdp
)
...
...
drivers/net/e100/e100_proc.c
deleted
100644 → 0
View file @
3b76b263
/*******************************************************************************
Copyright(c) 1999 - 2002 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
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/**********************************************************************
* *
* INTEL CORPORATION *
* *
* This software is supplied under the terms of the license included *
* above. All use of this driver must be in accordance with the terms *
* of that license. *
* *
* Module Name: e100_proc.c *
* *
* Abstract: Functions to handle the proc file system. *
* Create the proc directories and files and run read and *
* write requests from the user *
* *
* Environment: This file is intended to be specific to the Linux *
* operating system. *
* *
**********************************************************************/
#include <linux/config.h>
#ifdef CONFIG_PROC_FS
#include "e100.h"
/* MDI sleep time is at least 50 ms, in jiffies */
#define MDI_SLEEP_TIME ((HZ / 20) + 1)
/***************************************************************************/
/* /proc File System Interaface Support Functions */
/***************************************************************************/
static
struct
proc_dir_entry
*
adapters_proc_dir
=
0
;
/* externs from e100_main.c */
extern
char
e100_short_driver_name
[];
extern
char
e100_driver_version
[];
extern
struct
net_device_stats
*
e100_get_stats
(
struct
net_device
*
dev
);
extern
char
*
e100_get_brand_msg
(
struct
e100_private
*
bdp
);
extern
int
e100_mdi_write
(
struct
e100_private
*
,
u32
,
u32
,
u16
);
static
void
e100_proc_cleanup
(
void
);
static
unsigned
char
e100_init_proc_dir
(
void
);
#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
#define WRITE_BUF_MAX_LEN 20
#define READ_BUF_MAX_LEN 256
#define E100_PE_LEN 25
#define bdp_drv_off(off) (unsigned long)(offsetof(struct e100_private, drv_stats.off))
#define bdp_prm_off(off) (unsigned long)(offsetof(struct e100_private, params.off))
typedef
struct
_e100_proc_entry
{
char
*
name
;
read_proc_t
*
read_proc
;
write_proc_t
*
write_proc
;
unsigned
long
offset
;
/* offset into bdp. ~0 means no value, pass NULL. */
}
e100_proc_entry
;
static
int
generic_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
int
len
)
{
if
(
len
<=
off
+
count
)
*
eof
=
1
;
*
start
=
page
+
off
;
len
-=
off
;
if
(
len
>
count
)
len
=
count
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
static
int
read_ulong
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
unsigned
long
l
)
{
int
len
;
len
=
sprintf
(
page
,
"%lu
\n
"
,
l
);
return
generic_read
(
page
,
start
,
off
,
count
,
eof
,
len
);
}
static
int
read_gen_ulong
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
unsigned
long
val
=
0
;
if
(
data
)
val
=
*
((
unsigned
long
*
)
data
);
return
read_ulong
(
page
,
start
,
off
,
count
,
eof
,
val
);
}
static
int
read_hwaddr
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
unsigned
char
*
hwaddr
)
{
int
len
;
len
=
sprintf
(
page
,
"%02X:%02X:%02X:%02X:%02X:%02X
\n
"
,
hwaddr
[
0
],
hwaddr
[
1
],
hwaddr
[
2
],
hwaddr
[
3
],
hwaddr
[
4
],
hwaddr
[
5
]);
return
generic_read
(
page
,
start
,
off
,
count
,
eof
,
len
);
}
static
int
read_descr
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
e100_private
*
bdp
=
data
;
int
len
;
len
=
sprintf
(
page
,
"%s
\n
"
,
bdp
->
id_string
);
return
generic_read
(
page
,
start
,
off
,
count
,
eof
,
len
);
}
static
int
read_permanent_hwaddr
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
e100_private
*
bdp
=
data
;
unsigned
char
*
hwaddr
=
bdp
->
perm_node_address
;
return
read_hwaddr
(
page
,
start
,
off
,
count
,
eof
,
hwaddr
);
}
static
int
read_part_number
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
e100_private
*
bdp
=
data
;
int
len
;
len
=
sprintf
(
page
,
"%06lx-%03x
\n
"
,
(
unsigned
long
)
(
bdp
->
pwa_no
>>
8
),
(
unsigned
int
)
(
bdp
->
pwa_no
&
0xFF
));
return
generic_read
(
page
,
start
,
off
,
count
,
eof
,
len
);
}
static
void
set_led
(
struct
e100_private
*
bdp
,
u16
led_mdi_op
)
{
e100_mdi_write
(
bdp
,
PHY_82555_LED_SWITCH_CONTROL
,
bdp
->
phy_addr
,
led_mdi_op
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
MDI_SLEEP_TIME
);
/* turn led ownership to the chip */
e100_mdi_write
(
bdp
,
PHY_82555_LED_SWITCH_CONTROL
,
bdp
->
phy_addr
,
PHY_82555_LED_NORMAL_CONTROL
);
}
static
int
write_blink_led_timer
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
struct
e100_private
*
bdp
=
data
;
char
s_blink_op
[
WRITE_BUF_MAX_LEN
+
1
];
char
*
res
;
unsigned
long
i_blink_op
;
if
(
!
buffer
)
return
-
EINVAL
;
if
(
count
>
WRITE_BUF_MAX_LEN
)
{
count
=
WRITE_BUF_MAX_LEN
;
}
if
(
copy_from_user
(
s_blink_op
,
buffer
,
count
))
return
-
EFAULT
;
s_blink_op
[
count
]
=
'\0'
;
i_blink_op
=
simple_strtoul
(
s_blink_op
,
&
res
,
0
);
if
(
res
==
s_blink_op
)
{
return
-
EINVAL
;
}
switch
(
i_blink_op
)
{
case
LED_OFF
:
set_led
(
bdp
,
PHY_82555_LED_OFF
);
break
;
case
LED_ON
:
if
(
bdp
->
rev_id
>=
D101MA_REV_ID
)
set_led
(
bdp
,
PHY_82555_LED_ON_559
);
else
set_led
(
bdp
,
PHY_82555_LED_ON_PRE_559
);
break
;
default:
return
-
EINVAL
;
}
return
count
;
}
static
e100_proc_entry
e100_proc_list
[]
=
{
{
"Description"
,
read_descr
,
0
,
0
},
{
"Permanent_HWaddr"
,
read_permanent_hwaddr
,
0
,
0
},
{
"Part_Number"
,
read_part_number
,
0
,
0
},
{
"
\n
"
,},
{
"Rx_TCP_Checksum_Good"
,
read_gen_ulong
,
0
,
~
0
},
{
"Rx_TCP_Checksum_Bad"
,
read_gen_ulong
,
0
,
~
0
},
{
"Tx_TCP_Checksum_Good"
,
read_gen_ulong
,
0
,
~
0
},
{
"Tx_TCP_Checksum_Bad"
,
read_gen_ulong
,
0
,
~
0
},
{
"
\n
"
,},
{
"Tx_Abort_Late_Coll"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
tx_late_col
)},
{
"Tx_Deferred_Ok"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
tx_ok_defrd
)},
{
"Tx_Single_Coll_Ok"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
tx_one_retry
)},
{
"Tx_Multi_Coll_Ok"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
tx_mt_one_retry
)},
{
"Rx_Long_Length_Errors"
,
read_gen_ulong
,
0
,
~
0
},
{
"
\n
"
,},
{
"Tx_Flow_Control_Pause"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
xmt_fc_pkts
)},
{
"Rx_Flow_Control_Pause"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
rcv_fc_pkts
)},
{
"Rx_Flow_Control_Unsup"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
rcv_fc_unsupported
)},
{
"
\n
"
,},
{
"Tx_TCO_Packets"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
xmt_tco_pkts
)},
{
"Rx_TCO_Packets"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
rcv_tco_pkts
)},
{
"
\n
"
,},
{
"Rx_Interrupt_Packets"
,
read_gen_ulong
,
0
,
bdp_drv_off
(
rx_intr_pkts
)},
{
"Identify_Adapter"
,
0
,
write_blink_led_timer
,
0
},
{
""
,
0
,
0
,
0
}
};
static
int
read_info
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
e100_private
*
bdp
=
data
;
e100_proc_entry
*
pe
;
int
tmp
;
void
*
val
;
int
len
=
0
;
for
(
pe
=
e100_proc_list
;
pe
->
name
[
0
];
pe
++
)
{
if
(
pe
->
name
[
0
]
==
'\n'
)
{
len
+=
sprintf
(
page
+
len
,
"
\n
"
);
continue
;
}
if
(
pe
->
read_proc
)
{
if
((
len
+
READ_BUF_MAX_LEN
+
E100_PE_LEN
+
1
)
>=
PAGE_SIZE
)
break
;
if
(
pe
->
offset
!=
~
0
)
val
=
((
char
*
)
bdp
)
+
pe
->
offset
;
else
val
=
NULL
;
len
+=
sprintf
(
page
+
len
,
"%-"
__MODULE_STRING
(
E100_PE_LEN
)
"s "
,
pe
->
name
);
len
+=
pe
->
read_proc
(
page
+
len
,
start
,
0
,
READ_BUF_MAX_LEN
+
1
,
&
tmp
,
val
);
}
}
return
generic_read
(
page
,
start
,
off
,
count
,
eof
,
len
);
}
static
struct
proc_dir_entry
*
create_proc_rw
(
char
*
name
,
void
*
data
,
struct
proc_dir_entry
*
parent
,
read_proc_t
*
read_proc
,
write_proc_t
*
write_proc
)
{
struct
proc_dir_entry
*
pdep
;
mode_t
mode
=
S_IFREG
;
if
(
write_proc
)
{
mode
|=
S_IWUSR
;
if
(
read_proc
)
{
mode
|=
S_IRUSR
;
}
}
else
if
(
read_proc
)
{
mode
|=
S_IRUGO
;
}
if
(
!
(
pdep
=
create_proc_entry
(
name
,
mode
,
parent
)))
return
NULL
;
pdep
->
read_proc
=
read_proc
;
pdep
->
write_proc
=
write_proc
;
pdep
->
data
=
data
;
return
pdep
;
}
void
e100_remove_proc_subdir
(
struct
e100_private
*
bdp
,
char
*
name
)
{
e100_proc_entry
*
pe
;
char
info
[
256
];
int
len
;
/* If our root /proc dir was not created, there is nothing to remove */
if
(
adapters_proc_dir
==
NULL
)
{
return
;
}
len
=
strlen
(
bdp
->
ifname
);
strncpy
(
info
,
bdp
->
ifname
,
sizeof
(
info
));
strncat
(
info
+
len
,
".info"
,
sizeof
(
info
)
-
len
);
if
(
bdp
->
proc_parent
)
{
for
(
pe
=
e100_proc_list
;
pe
->
name
[
0
];
pe
++
)
{
if
(
pe
->
name
[
0
]
==
'\n'
)
continue
;
remove_proc_entry
(
pe
->
name
,
bdp
->
proc_parent
);
}
remove_proc_entry
(
bdp
->
ifname
,
adapters_proc_dir
);
bdp
->
proc_parent
=
NULL
;
}
remove_proc_entry
(
info
,
adapters_proc_dir
);
/* try to remove the main /proc dir, if it's empty */
e100_proc_cleanup
();
}
int
e100_create_proc_subdir
(
struct
e100_private
*
bdp
)
{
struct
proc_dir_entry
*
dev_dir
;
e100_proc_entry
*
pe
;
char
info
[
256
];
int
len
;
void
*
data
;
/* create the main /proc dir if needed */
if
(
!
adapters_proc_dir
)
{
if
(
!
e100_init_proc_dir
())
return
-
ENOMEM
;
}
strncpy
(
info
,
bdp
->
ifname
,
sizeof
(
info
));
len
=
strlen
(
info
);
strncat
(
info
+
len
,
".info"
,
sizeof
(
info
)
-
len
);
/* info */
if
(
!
(
create_proc_rw
(
info
,
bdp
,
adapters_proc_dir
,
read_info
,
0
)))
{
e100_proc_cleanup
();
return
-
ENOMEM
;
}
dev_dir
=
create_proc_entry
(
bdp
->
ifname
,
S_IFDIR
,
adapters_proc_dir
);
bdp
->
proc_parent
=
dev_dir
;
if
(
!
dev_dir
)
{
e100_remove_proc_subdir
(
bdp
,
bdp
->
ifname
);
return
-
ENOMEM
;
}
for
(
pe
=
e100_proc_list
;
pe
->
name
[
0
];
pe
++
)
{
if
(
pe
->
name
[
0
]
==
'\n'
)
continue
;
if
(
pe
->
offset
!=
~
0
)
data
=
((
char
*
)
bdp
)
+
pe
->
offset
;
else
data
=
NULL
;
if
(
!
(
create_proc_rw
(
pe
->
name
,
data
,
dev_dir
,
pe
->
read_proc
,
pe
->
write_proc
)))
{
e100_remove_proc_subdir
(
bdp
,
bdp
->
ifname
);
return
-
ENOMEM
;
}
}
return
0
;
}
/****************************************************************************
* Name: e100_init_proc_dir
*
* Description: This routine creates the top-level /proc directory for the
* driver in /proc/net
*
* Arguments: none
*
* Returns: true on success, false on fail
*
***************************************************************************/
static
unsigned
char
e100_init_proc_dir
(
void
)
{
int
len
;
/* first check if adapters_proc_dir already exists */
len
=
strlen
(
ADAPTERS_PROC_DIR
);
for
(
adapters_proc_dir
=
proc_net
->
subdir
;
adapters_proc_dir
;
adapters_proc_dir
=
adapters_proc_dir
->
next
)
{
if
((
adapters_proc_dir
->
namelen
==
len
)
&&
(
!
memcmp
(
adapters_proc_dir
->
name
,
ADAPTERS_PROC_DIR
,
len
)))
break
;
}
if
(
!
adapters_proc_dir
)
adapters_proc_dir
=
create_proc_entry
(
ADAPTERS_PROC_DIR
,
S_IFDIR
,
proc_net
);
if
(
!
adapters_proc_dir
)
return
false
;
return
true
;
}
/****************************************************************************
* Name: e100_proc_cleanup
*
* Description: This routine clears the top-level /proc directory, if empty.
*
* Arguments: none
*
* Returns: none
*
***************************************************************************/
static
void
e100_proc_cleanup
(
void
)
{
struct
proc_dir_entry
*
de
;
if
(
adapters_proc_dir
==
NULL
)
{
return
;
}
/* check if subdir list is empty before removing adapters_proc_dir */
for
(
de
=
adapters_proc_dir
->
subdir
;
de
;
de
=
de
->
next
)
{
/* ignore . and .. */
if
(
*
(
de
->
name
)
!=
'.'
)
break
;
}
if
(
de
)
return
;
remove_proc_entry
(
ADAPTERS_PROC_DIR
,
proc_net
);
adapters_proc_dir
=
NULL
;
}
#endif
/* CONFIG_PROC_FS */
drivers/net/e1000/Makefile
View file @
7f4174f1
...
...
@@ -32,5 +32,4 @@
obj-$(CONFIG_E1000)
+=
e1000.o
e1000-objs
:=
e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o
\
e1000_proc.o
e1000-objs
:=
e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o
drivers/net/e1000/e1000.h
View file @
7f4174f1
...
...
@@ -157,9 +157,6 @@ struct e1000_desc_ring {
struct
e1000_adapter
{
struct
timer_list
watchdog_timer
;
struct
timer_list
phy_info_timer
;
#ifdef CONFIG_PROC_FS
struct
list_head
proc_list_head
;
#endif
struct
vlan_group
*
vlgrp
;
char
*
id_string
;
uint32_t
bd_number
;
...
...
drivers/net/e1000/e1000_ethtool.c
View file @
7f4174f1
...
...
@@ -39,6 +39,16 @@ extern int e1000_up(struct e1000_adapter *adapter);
extern
void
e1000_down
(
struct
e1000_adapter
*
adapter
);
extern
void
e1000_reset
(
struct
e1000_adapter
*
adapter
);
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"
,
};
#define E1000_STATS_LEN sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN
static
void
e1000_ethtool_gset
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_cmd
*
ecmd
)
{
...
...
@@ -173,6 +183,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
strncpy
(
drvinfo
->
version
,
e1000_driver_version
,
32
);
strncpy
(
drvinfo
->
fw_version
,
"N/A"
,
32
);
strncpy
(
drvinfo
->
bus_info
,
adapter
->
pdev
->
slot_name
,
32
);
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
#define E1000_REGS_LEN 32
drvinfo
->
regdump_len
=
E1000_REGS_LEN
*
sizeof
(
uint32_t
);
drvinfo
->
eedump_len
=
e1000_eeprom_size
(
&
adapter
->
hw
);
...
...
@@ -209,18 +220,24 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct
ethtool_eeprom
*
eeprom
,
uint16_t
*
eeprom_buff
)
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
int
i
,
max_len
,
first_word
,
last_word
;
int
max_len
,
first_word
,
last_word
;
int
ret_val
=
0
;
int
i
;
if
(
eeprom
->
len
==
0
)
return
-
EINVAL
;
if
(
eeprom
->
len
==
0
)
{
ret_val
=
-
EINVAL
;
goto
geeprom_error
;
}
eeprom
->
magic
=
hw
->
vendor_id
|
(
hw
->
device_id
<<
16
);
max_len
=
e1000_eeprom_size
(
hw
);
if
(
eeprom
->
offset
>
eeprom
->
offset
+
eeprom
->
len
)
return
-
EINVAL
;
if
(
eeprom
->
offset
>
eeprom
->
offset
+
eeprom
->
len
)
{
ret_val
=
-
EINVAL
;
goto
geeprom_error
;
}
if
((
eeprom
->
offset
+
eeprom
->
len
)
>
max_len
)
eeprom
->
len
=
(
max_len
-
eeprom
->
offset
);
...
...
@@ -230,7 +247,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
for
(
i
=
0
;
i
<=
(
last_word
-
first_word
);
i
++
)
e1000_read_eeprom
(
hw
,
first_word
+
i
,
&
eeprom_buff
[
i
]);
return
0
;
geeprom_error:
return
ret_val
;
}
static
int
...
...
@@ -238,9 +256,10 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
struct
ethtool_eeprom
*
eeprom
,
void
*
user_data
)
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
eeprom_buff
[
256
]
;
int
i
,
max_len
,
first_word
,
last_word
;
uint16_t
*
eeprom_buff
;
int
max_len
,
first_word
,
last_word
;
void
*
ptr
;
int
i
;
if
(
eeprom
->
len
==
0
)
return
-
EOPNOTSUPP
;
...
...
@@ -255,6 +274,10 @@ 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
)
return
-
ENOMEM
;
ptr
=
(
void
*
)
eeprom_buff
;
if
(
eeprom
->
offset
&
1
)
{
...
...
@@ -269,8 +292,10 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
e1000_read_eeprom
(
hw
,
last_word
,
&
eeprom_buff
[
last_word
-
first_word
]);
}
if
(
copy_from_user
(
ptr
,
user_data
,
eeprom
->
len
))
if
(
copy_from_user
(
ptr
,
user_data
,
eeprom
->
len
))
{
kfree
(
eeprom_buff
);
return
-
EFAULT
;
}
for
(
i
=
0
;
i
<=
(
last_word
-
first_word
);
i
++
)
e1000_write_eeprom
(
hw
,
first_word
+
i
,
eeprom_buff
[
i
]);
...
...
@@ -279,6 +304,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if
(
first_word
<=
EEPROM_CHECKSUM_REG
)
e1000_update_eeprom_checksum
(
hw
);
kfree
(
eeprom_buff
);
return
0
;
}
...
...
@@ -438,6 +465,28 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GSTRINGS
:
{
struct
ethtool_gstrings
gstrings
=
{
ETHTOOL_GSTRINGS
};
char
*
strings
=
NULL
;
if
(
copy_from_user
(
&
gstrings
,
addr
,
sizeof
(
gstrings
)))
return
-
EFAULT
;
switch
(
gstrings
.
string_set
)
{
case
ETH_SS_STATS
:
gstrings
.
len
=
E1000_STATS_LEN
;
strings
=
*
e1000_gstrings_stats
;
break
;
default:
return
-
EOPNOTSUPP
;
}
if
(
copy_to_user
(
addr
,
&
gstrings
,
sizeof
(
gstrings
)))
return
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_gstrings
,
data
);
if
(
copy_to_user
(
addr
,
strings
,
gstrings
.
len
*
ETH_GSTRING_LEN
))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GREGS
:
{
struct
ethtool_regs
regs
=
{
ETHTOOL_GREGS
};
uint32_t
regs_buff
[
E1000_REGS_LEN
];
...
...
@@ -493,26 +542,40 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
}
case
ETHTOOL_GEEPROM
:
{
struct
ethtool_eeprom
eeprom
=
{
ETHTOOL_GEEPROM
};
uint16_t
eeprom_buff
[
256
]
;
uint16_t
*
eeprom_buff
;
void
*
ptr
;
int
err
;
int
max_len
,
err
=
0
;
if
(
copy_from_user
(
&
eeprom
,
addr
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
max_len
=
e1000_eeprom_size
(
&
adapter
->
hw
);
if
((
err
=
e1000_ethtool_geeprom
(
adapter
,
&
eeprom
,
eeprom_buff
)))
return
err
;
eeprom_buff
=
kmalloc
(
max_len
,
GFP_KERNEL
);
if
(
copy_to_user
(
addr
,
&
eeprom
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
if
(
eeprom_buff
==
NULL
)
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
;
if
(
copy_to_user
(
addr
,
&
eeprom
,
sizeof
(
eeprom
)))
{
err
=
-
EFAULT
;
goto
err_geeprom_ioctl
;
}
addr
+=
offsetof
(
struct
ethtool_eeprom
,
data
);
ptr
=
((
void
*
)
eeprom_buff
)
+
(
eeprom
.
offset
&
1
);
if
(
copy_to_user
(
addr
,
ptr
,
eeprom
.
len
))
return
-
EFAULT
;
return
0
;
err
=
-
EFAULT
;
err_geeprom_ioctl:
kfree
(
eeprom_buff
);
return
err
;
}
case
ETHTOOL_SEEPROM
:
{
struct
ethtool_eeprom
eeprom
;
...
...
@@ -526,6 +589,20 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
addr
+=
offsetof
(
struct
ethtool_eeprom
,
data
);
return
e1000_ethtool_seeprom
(
adapter
,
&
eeprom
,
addr
);
}
case
ETHTOOL_GSTATS
:
{
struct
{
struct
ethtool_stats
cmd
;
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
];
if
(
copy_to_user
(
addr
,
&
stats
,
sizeof
(
stats
)))
return
-
EFAULT
;
return
0
;
}
default:
return
-
EOPNOTSUPP
;
}
...
...
drivers/net/e1000/e1000_main.c
View file @
7f4174f1
...
...
@@ -59,7 +59,7 @@
char
e1000_driver_name
[]
=
"e1000"
;
char
e1000_driver_string
[]
=
"Intel(R) PRO/1000 Network Driver"
;
char
e1000_driver_version
[]
=
"4.4.19-k
1
"
;
char
e1000_driver_version
[]
=
"4.4.19-k
3
"
;
char
e1000_copyright
[]
=
"Copyright (c) 1999-2002 Intel Corporation."
;
/* e1000_pci_tbl - PCI Device ID Table
...
...
@@ -171,7 +171,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
static
void
e1000_restore_vlan
(
struct
e1000_adapter
*
adapter
);
static
int
e1000_notify_reboot
(
struct
notifier_block
*
,
unsigned
long
event
,
void
*
ptr
);
static
int
e1000_notify_netdev
(
struct
notifier_block
*
,
unsigned
long
event
,
void
*
ptr
);
static
int
e1000_suspend
(
struct
pci_dev
*
pdev
,
uint32_t
state
);
#ifdef CONFIG_PM
static
int
e1000_resume
(
struct
pci_dev
*
pdev
);
...
...
@@ -183,17 +182,9 @@ struct notifier_block e1000_notifier_reboot = {
.
priority
=
0
};
struct
notifier_block
e1000_notifier_netdev
=
{
.
notifier_call
=
e1000_notify_netdev
,
.
next
=
NULL
,
.
priority
=
0
};
/* Exported from other modules */
extern
void
e1000_check_options
(
struct
e1000_adapter
*
adapter
);
extern
void
e1000_proc_dev_setup
(
struct
e1000_adapter
*
adapter
);
extern
void
e1000_proc_dev_free
(
struct
e1000_adapter
*
adapter
);
extern
int
e1000_ethtool_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
);
static
struct
pci_driver
e1000_driver
=
{
...
...
@@ -229,10 +220,8 @@ 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
);
register_netdevice_notifier
(
&
e1000_notifier_netdev
);
}
return
ret
;
}
...
...
@@ -249,7 +238,6 @@ static void __exit
e1000_exit_module
(
void
)
{
unregister_reboot_notifier
(
&
e1000_notifier_reboot
);
unregister_netdevice_notifier
(
&
e1000_notifier_netdev
);
pci_unregister_driver
(
&
e1000_driver
);
}
...
...
@@ -433,10 +421,8 @@ e1000_probe(struct pci_dev *pdev,
netdev
->
features
=
NETIF_F_SG
;
}
#ifdef NETIF_F_TSO
if
(
adapter
->
hw
.
mac_type
>=
e1000_82544
)
netdev
->
features
|=
NETIF_F_TSO
;
#endif
if
(
pci_using_dac
)
netdev
->
features
|=
NETIF_F_HIGHDMA
;
...
...
@@ -490,7 +476,6 @@ e1000_probe(struct pci_dev *pdev,
printk
(
KERN_INFO
"%s: %s
\n
"
,
netdev
->
name
,
adapter
->
id_string
);
e1000_check_options
(
adapter
);
e1000_proc_dev_setup
(
adapter
);
/* Initial Wake on LAN setting
* If APM wake is enabled in the EEPROM,
...
...
@@ -548,8 +533,6 @@ e1000_remove(struct pci_dev *pdev)
e1000_phy_hw_reset
(
&
adapter
->
hw
);
e1000_proc_dev_free
(
adapter
);
iounmap
(
adapter
->
hw
.
hw_addr
);
pci_release_regions
(
pdev
);
...
...
@@ -1314,7 +1297,6 @@ e1000_watchdog(unsigned long data)
static
inline
boolean_t
e1000_tso
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
,
int
tx_flags
)
{
#ifdef NETIF_F_TSO
struct
e1000_context_desc
*
context_desc
;
int
i
;
uint8_t
ipcss
,
ipcso
,
tucss
,
tucso
,
hdr_len
;
...
...
@@ -1358,7 +1340,6 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
return
TRUE
;
}
#endif
return
FALSE
;
}
...
...
@@ -1398,6 +1379,8 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
int
len
,
offset
,
size
,
count
,
i
;
int
tso
=
skb_shinfo
(
skb
)
->
tso_size
;
int
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
int
f
;
len
=
skb
->
len
-
skb
->
data_len
;
...
...
@@ -1409,6 +1392,10 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
while
(
len
)
{
i
=
(
i
+
1
)
%
tx_ring
->
count
;
size
=
min
(
len
,
adapter
->
max_data_per_txd
);
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if
(
tso
&&
!
nr_frags
&&
size
==
len
&&
size
>
4
)
size
-=
4
;
tx_ring
->
buffer_info
[
i
].
length
=
size
;
tx_ring
->
buffer_info
[
i
].
dma
=
pci_map_single
(
adapter
->
pdev
,
...
...
@@ -1422,7 +1409,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
count
++
;
}
for
(
f
=
0
;
f
<
skb_shinfo
(
skb
)
->
nr_frags
;
f
++
)
{
for
(
f
=
0
;
f
<
nr_frags
;
f
++
)
{
struct
skb_frag_struct
*
frag
;
frag
=
&
skb_shinfo
(
skb
)
->
frags
[
f
];
...
...
@@ -1432,6 +1419,10 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
while
(
len
)
{
i
=
(
i
+
1
)
%
tx_ring
->
count
;
size
=
min
(
len
,
adapter
->
max_data_per_txd
);
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if
(
tso
&&
f
==
(
nr_frags
-
1
)
&&
size
==
len
&&
size
>
4
)
size
-=
4
;
tx_ring
->
buffer_info
[
i
].
length
=
size
;
tx_ring
->
buffer_info
[
i
].
dma
=
pci_map_page
(
adapter
->
pdev
,
...
...
@@ -1439,6 +1430,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
frag
->
page_offset
+
offset
,
size
,
PCI_DMA_TODEVICE
);
tx_ring
->
buffer_info
[
i
].
time_stamp
=
jiffies
;
len
-=
size
;
offset
+=
size
;
...
...
@@ -1520,13 +1512,8 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
for
(
f
=
0
;
f
<
skb_shinfo
(
skb
)
->
nr_frags
;
f
++
)
count
+=
TXD_USE_COUNT
(
skb_shinfo
(
skb
)
->
frags
[
f
].
size
,
adapter
->
max_data_per_txd
);
#ifdef NETIF_F_TSO
if
((
skb_shinfo
(
skb
)
->
tso_size
)
||
(
skb
->
ip_summed
==
CHECKSUM_HW
))
count
++
;
#else
if
(
skb
->
ip_summed
==
CHECKSUM_HW
)
count
++
;
#endif
if
(
E1000_DESC_UNUSED
(
&
adapter
->
tx_ring
)
<
count
)
{
netif_stop_queue
(
netdev
);
...
...
@@ -1823,7 +1810,10 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
#ifdef CONFIG_E1000_NAPI
if
(
netif_rx_schedule_prep
(
netdev
))
{
e1000_irq_disable
(
adapter
);
/* Disable interrupts and enable polling */
atomic_inc
(
&
adapter
->
irq_sem
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
~
0
);
E1000_WRITE_FLUSH
(
&
adapter
->
hw
);
__netif_rx_schedule
(
netdev
);
}
#else
...
...
@@ -2429,29 +2419,6 @@ e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
return
NOTIFY_DONE
;
}
static
int
e1000_notify_netdev
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
p
)
{
struct
e1000_adapter
*
adapter
;
struct
net_device
*
netdev
=
p
;
if
(
netdev
==
NULL
)
return
NOTIFY_DONE
;
switch
(
event
)
{
case
NETDEV_CHANGENAME
:
if
(
netdev
->
open
==
e1000_open
)
{
adapter
=
netdev
->
priv
;
/* rename the proc nodes the easy way */
e1000_proc_dev_free
(
adapter
);
memcpy
(
adapter
->
ifname
,
netdev
->
name
,
IFNAMSIZ
);
adapter
->
ifname
[
IFNAMSIZ
-
1
]
=
0
;
e1000_proc_dev_setup
(
adapter
);
}
break
;
}
return
NOTIFY_DONE
;
}
static
int
e1000_suspend
(
struct
pci_dev
*
pdev
,
uint32_t
state
)
{
...
...
drivers/net/e1000/e1000_proc.c
deleted
100644 → 0
View file @
3b76b263
/*******************************************************************************
Copyright(c) 1999 - 2002 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
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
Linux NICS <linux.nics@intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/*
* Proc fs support.
*
* Read-only files created by driver (if CONFIG_PROC_FS):
*
* /proc/net/PRO_LAN_Adapters/<ethx>.info
* /proc/net/PRO_LAN_Adapters/<ethx>/<attribute>
*
* where <ethx> is the system device name, i.e eth0.
* <attribute> is the driver attribute name.
*
* There is one file for each driver attribute, where the contents
* of the file is the attribute value. The ethx.info file contains
* a list of all driver attributes in one file.
*
*/
#include "e1000.h"
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
#define TAG_MAX_LENGTH 32
#define LINE_MAX_LENGTH 80
#define FIELD_MAX_LENGTH LINE_MAX_LENGTH - TAG_MAX_LENGTH - 3
extern
char
e1000_driver_name
[];
extern
char
e1000_driver_version
[];
/*
* The list of driver proc attributes is stored in a proc_list link
* list. The list is build with proc_list_setup and is used to
* build the proc fs nodes. The private data for each node is the
* corresponding link in the link list.
*/
struct
proc_list
{
struct
list_head
list
;
/* link list */
char
tag
[
TAG_MAX_LENGTH
+
1
];
/* attribute name */
void
*
data
;
/* attribute data */
size_t
len
;
/* sizeof data */
char
*
(
*
func
)(
void
*
,
size_t
,
char
*
);
/* format data func */
};
static
int
e1000_proc_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
)
{
int
len
=
strlen
(
page
);
page
[
len
++
]
=
'\n'
;
if
(
len
<=
off
+
count
)
*
eof
=
1
;
*
start
=
page
+
off
;
len
-=
off
;
if
(
len
>
count
)
len
=
count
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
static
int
e1000_proc_info_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
list_head
*
proc_list_head
=
data
,
*
curr
;
struct
proc_list
*
elem
;
char
*
p
=
page
;
char
buf
[
FIELD_MAX_LENGTH
+
1
];
list_for_each
(
curr
,
proc_list_head
)
{
elem
=
list_entry
(
curr
,
struct
proc_list
,
list
);
if
(
p
-
page
+
LINE_MAX_LENGTH
>=
PAGE_SIZE
)
break
;
if
(
!
strlen
(
elem
->
tag
))
p
+=
sprintf
(
p
,
"
\n
"
);
else
p
+=
sprintf
(
p
,
"%-*.*s %.*s
\n
"
,
TAG_MAX_LENGTH
,
TAG_MAX_LENGTH
,
elem
->
tag
,
FIELD_MAX_LENGTH
,
elem
->
func
(
elem
->
data
,
elem
->
len
,
buf
));
}
*
p
=
'\0'
;
return
e1000_proc_read
(
page
,
start
,
off
,
count
,
eof
);
}
static
int
e1000_proc_single_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
proc_list
*
elem
=
data
;
sprintf
(
page
,
"%.*s"
,
FIELD_MAX_LENGTH
,
elem
->
func
(
elem
->
data
,
elem
->
len
,
page
));
return
e1000_proc_read
(
page
,
start
,
off
,
count
,
eof
);
}
static
void
e1000_proc_dirs_free
(
char
*
name
,
struct
list_head
*
proc_list_head
)
{
struct
proc_dir_entry
*
intel_proc_dir
,
*
proc_dir
;
char
info_name
[
strlen
(
name
)
+
strlen
(
".info"
)];
for
(
intel_proc_dir
=
proc_net
->
subdir
;
intel_proc_dir
;
intel_proc_dir
=
intel_proc_dir
->
next
)
{
if
((
intel_proc_dir
->
namelen
==
strlen
(
ADAPTERS_PROC_DIR
))
&&
!
memcmp
(
intel_proc_dir
->
name
,
ADAPTERS_PROC_DIR
,
strlen
(
ADAPTERS_PROC_DIR
)))
break
;
}
if
(
!
intel_proc_dir
)
return
;
for
(
proc_dir
=
intel_proc_dir
->
subdir
;
proc_dir
;
proc_dir
=
proc_dir
->
next
)
{
if
((
proc_dir
->
namelen
==
strlen
(
name
))
&&
!
memcmp
(
proc_dir
->
name
,
name
,
strlen
(
name
)))
break
;
}
if
(
proc_dir
)
{
struct
list_head
*
curr
;
struct
proc_list
*
elem
;
list_for_each
(
curr
,
proc_list_head
)
{
elem
=
list_entry
(
curr
,
struct
proc_list
,
list
);
remove_proc_entry
(
elem
->
tag
,
proc_dir
);
}
strcpy
(
info_name
,
name
);
strcat
(
info_name
,
".info"
);
remove_proc_entry
(
info_name
,
intel_proc_dir
);
remove_proc_entry
(
name
,
intel_proc_dir
);
}
/* If the intel dir is empty, remove it */
for
(
proc_dir
=
intel_proc_dir
->
subdir
;
proc_dir
;
proc_dir
=
proc_dir
->
next
)
{
/* ignore . and .. */
if
(
*
(
proc_dir
->
name
)
==
'.'
)
continue
;
break
;
}
if
(
!
proc_dir
)
remove_proc_entry
(
ADAPTERS_PROC_DIR
,
proc_net
);
}
static
int
e1000_proc_singles_create
(
struct
proc_dir_entry
*
parent
,
struct
list_head
*
proc_list_head
)
{
struct
list_head
*
curr
;
struct
proc_list
*
elem
;
list_for_each
(
curr
,
proc_list_head
)
{
struct
proc_dir_entry
*
proc_entry
;
elem
=
list_entry
(
curr
,
struct
proc_list
,
list
);
if
(
!
strlen
(
elem
->
tag
))
continue
;
if
(
!
(
proc_entry
=
create_proc_entry
(
elem
->
tag
,
S_IFREG
,
parent
)))
return
0
;
proc_entry
->
read_proc
=
e1000_proc_single_read
;
proc_entry
->
data
=
elem
;
SET_MODULE_OWNER
(
proc_entry
);
}
return
1
;
}
static
void
e1000_proc_dirs_create
(
void
*
data
,
char
*
name
,
struct
list_head
*
proc_list_head
)
{
struct
proc_dir_entry
*
intel_proc_dir
,
*
proc_dir
,
*
info_entry
;
char
info_name
[
strlen
(
name
)
+
strlen
(
".info"
)];
for
(
intel_proc_dir
=
proc_net
->
subdir
;
intel_proc_dir
;
intel_proc_dir
=
intel_proc_dir
->
next
)
{
if
((
intel_proc_dir
->
namelen
==
strlen
(
ADAPTERS_PROC_DIR
))
&&
!
memcmp
(
intel_proc_dir
->
name
,
ADAPTERS_PROC_DIR
,
strlen
(
ADAPTERS_PROC_DIR
)))
break
;
}
if
(
!
intel_proc_dir
)
if
(
!
(
intel_proc_dir
=
create_proc_entry
(
ADAPTERS_PROC_DIR
,
S_IFDIR
,
proc_net
)))
return
;
if
(
!
(
proc_dir
=
create_proc_entry
(
name
,
S_IFDIR
,
intel_proc_dir
)))
return
;
SET_MODULE_OWNER
(
proc_dir
);
if
(
!
e1000_proc_singles_create
(
proc_dir
,
proc_list_head
))
return
;
strcpy
(
info_name
,
name
);
strcat
(
info_name
,
".info"
);
if
(
!
(
info_entry
=
create_proc_entry
(
info_name
,
S_IFREG
,
intel_proc_dir
)))
return
;
SET_MODULE_OWNER
(
info_entry
);
info_entry
->
read_proc
=
e1000_proc_info_read
;
info_entry
->
data
=
proc_list_head
;
}
static
void
e1000_proc_list_add
(
struct
list_head
*
proc_list_head
,
char
*
tag
,
void
*
data
,
size_t
len
,
char
*
(
*
func
)(
void
*
,
size_t
,
char
*
))
{
struct
proc_list
*
new
=
(
struct
proc_list
*
)
kmalloc
(
sizeof
(
struct
proc_list
),
GFP_KERNEL
);
if
(
!
new
)
return
;
strncpy
(
new
->
tag
,
tag
,
TAG_MAX_LENGTH
);
new
->
data
=
data
;
new
->
len
=
len
;
new
->
func
=
func
;
list_add_tail
(
&
new
->
list
,
proc_list_head
);
}
static
void
e1000_proc_list_free
(
struct
list_head
*
proc_list_head
)
{
struct
proc_list
*
elem
;
while
(
!
list_empty
(
proc_list_head
))
{
elem
=
list_entry
(
proc_list_head
->
next
,
struct
proc_list
,
list
);
list_del
(
&
elem
->
list
);
kfree
(
elem
);
}
}
/*
* General purpose formating functions
*/
static
char
*
e1000_proc_str
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
sprintf
(
buf
,
"%s"
,
(
char
*
)
data
);
return
buf
;
}
static
char
*
e1000_proc_hex
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
switch
(
len
)
{
case
sizeof
(
uint8_t
):
sprintf
(
buf
,
"0x%02x"
,
*
(
uint8_t
*
)
data
);
break
;
case
sizeof
(
uint16_t
):
sprintf
(
buf
,
"0x%04x"
,
*
(
uint16_t
*
)
data
);
break
;
case
sizeof
(
uint32_t
):
sprintf
(
buf
,
"0x%08x"
,
*
(
uint32_t
*
)
data
);
break
;
case
sizeof
(
uint64_t
):
sprintf
(
buf
,
"0x%08Lx"
,
(
unsigned
long
long
)
*
(
uint64_t
*
)
data
);
break
;
}
return
buf
;
}
static
char
*
e1000_proc_unsigned
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
switch
(
len
)
{
case
sizeof
(
uint8_t
):
sprintf
(
buf
,
"%u"
,
*
(
uint8_t
*
)
data
);
break
;
case
sizeof
(
uint16_t
):
sprintf
(
buf
,
"%u"
,
*
(
uint16_t
*
)
data
);
break
;
case
sizeof
(
uint32_t
):
sprintf
(
buf
,
"%u"
,
*
(
uint32_t
*
)
data
);
break
;
case
sizeof
(
uint64_t
):
sprintf
(
buf
,
"%Lu"
,
(
unsigned
long
long
)
*
(
uint64_t
*
)
data
);
break
;
}
return
buf
;
}
/*
* Specific formating functions
*/
static
char
*
e1000_proc_part_number
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
sprintf
(
buf
,
"%06x-%03x"
,
*
(
uint32_t
*
)
data
>>
8
,
*
(
uint32_t
*
)
data
&
0x000000FF
);
return
buf
;
}
static
char
*
e1000_proc_slot
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
sprintf
(
buf
,
"%u"
,
PCI_SLOT
(
adapter
->
pdev
->
devfn
));
return
buf
;
}
static
char
*
e1000_proc_bus_type
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
e1000_bus_type
bus_type
=
*
(
e1000_bus_type
*
)
data
;
sprintf
(
buf
,
bus_type
==
e1000_bus_type_pci
?
"PCI"
:
bus_type
==
e1000_bus_type_pcix
?
"PCI-X"
:
"UNKNOWN"
);
return
buf
;
}
static
char
*
e1000_proc_bus_speed
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
e1000_bus_speed
bus_speed
=
*
(
e1000_bus_speed
*
)
data
;
sprintf
(
buf
,
bus_speed
==
e1000_bus_speed_33
?
"33MHz"
:
bus_speed
==
e1000_bus_speed_66
?
"66MHz"
:
bus_speed
==
e1000_bus_speed_100
?
"100MHz"
:
bus_speed
==
e1000_bus_speed_133
?
"133MHz"
:
"UNKNOWN"
);
return
buf
;
}
static
char
*
e1000_proc_bus_width
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
e1000_bus_width
bus_width
=
*
(
e1000_bus_width
*
)
data
;
sprintf
(
buf
,
bus_width
==
e1000_bus_width_32
?
"32-bit"
:
bus_width
==
e1000_bus_width_64
?
"64-bit"
:
"UNKNOWN"
);
return
buf
;
}
static
char
*
e1000_proc_hwaddr
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
unsigned
char
*
hwaddr
=
data
;
sprintf
(
buf
,
"%02X:%02X:%02X:%02X:%02X:%02X"
,
hwaddr
[
0
],
hwaddr
[
1
],
hwaddr
[
2
],
hwaddr
[
3
],
hwaddr
[
4
],
hwaddr
[
5
]);
return
buf
;
}
static
char
*
e1000_proc_link
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
sprintf
(
buf
,
netif_running
(
adapter
->
netdev
)
?
netif_carrier_ok
(
adapter
->
netdev
)
?
"up"
:
"down"
:
"N/A"
);
return
buf
;
}
static
char
*
e1000_proc_link_speed
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
uint16_t
link_speed
=
*
(
uint16_t
*
)
data
;
sprintf
(
buf
,
link_speed
?
"%u"
:
"N/A"
,
link_speed
);
return
buf
;
}
static
char
*
e1000_proc_link_duplex
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
uint16_t
link_duplex
=
*
(
uint16_t
*
)
data
;
sprintf
(
buf
,
link_duplex
==
FULL_DUPLEX
?
"Full"
:
link_duplex
==
HALF_DUPLEX
?
"Half"
:
"N/A"
);
return
buf
;
}
static
char
*
e1000_proc_state
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
sprintf
(
buf
,
adapter
->
netdev
->
flags
&
IFF_UP
?
"up"
:
"down"
);
return
buf
;
}
static
char
*
e1000_proc_media_type
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
sprintf
(
buf
,
adapter
->
hw
.
media_type
==
e1000_media_type_copper
?
"Copper"
:
"Fiber"
);
return
buf
;
}
static
char
*
e1000_proc_cable_length
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
e1000_cable_length
cable_length
=
adapter
->
phy_info
.
cable_length
;
sprintf
(
buf
,
"%s%s"
,
cable_length
==
e1000_cable_length_50
?
"0-50"
:
cable_length
==
e1000_cable_length_50_80
?
"50-80"
:
cable_length
==
e1000_cable_length_80_110
?
"80-110"
:
cable_length
==
e1000_cable_length_110_140
?
"110-140"
:
cable_length
==
e1000_cable_length_140
?
"> 140"
:
"Unknown"
,
cable_length
!=
e1000_cable_length_undefined
?
" Meters (+/- 20 Meters)"
:
""
);
return
buf
;
}
static
char
*
e1000_proc_extended
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
e1000_10bt_ext_dist_enable
dist_enable
=
adapter
->
phy_info
.
extended_10bt_distance
;
sprintf
(
buf
,
dist_enable
==
e1000_10bt_ext_dist_enable_normal
?
"Disabled"
:
dist_enable
==
e1000_10bt_ext_dist_enable_lower
?
"Enabled"
:
"Unknown"
);
return
buf
;
}
static
char
*
e1000_proc_cable_polarity
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
e1000_rev_polarity
polarity
=
adapter
->
phy_info
.
cable_polarity
;
sprintf
(
buf
,
polarity
==
e1000_rev_polarity_normal
?
"Normal"
:
polarity
==
e1000_rev_polarity_reversed
?
"Reversed"
:
"Unknown"
);
return
buf
;
}
static
char
*
e1000_proc_polarity_correction
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
e1000_polarity_reversal
correction
=
adapter
->
phy_info
.
polarity_correction
;
sprintf
(
buf
,
correction
==
e1000_polarity_reversal_enabled
?
"Disabled"
:
correction
==
e1000_polarity_reversal_disabled
?
"Enabled"
:
"Unknown"
);
return
buf
;
}
static
char
*
e1000_proc_mdi_x_enabled
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
struct
e1000_adapter
*
adapter
=
data
;
e1000_auto_x_mode
mdix_mode
=
adapter
->
phy_info
.
mdix_mode
;
sprintf
(
buf
,
mdix_mode
==
e1000_auto_x_mode_manual_mdi
?
"MDI"
:
mdix_mode
==
e1000_auto_x_mode_manual_mdix
?
"MDI-X"
:
"Unknown"
);
return
buf
;
}
static
char
*
e1000_proc_rx_status
(
void
*
data
,
size_t
len
,
char
*
buf
)
{
e1000_1000t_rx_status
rx_status
=
*
(
e1000_1000t_rx_status
*
)
data
;
sprintf
(
buf
,
rx_status
==
e1000_1000t_rx_status_not_ok
?
"NOT_OK"
:
rx_status
==
e1000_1000t_rx_status_ok
?
"OK"
:
"Unknown"
);
return
buf
;
}
/*
* e1000_proc_list_setup - build link list of proc praramters
* @adapter: board private structure
*
* Order matters - ethx.info entries are ordered in the order links
* are added to list.
*/
#define LIST_ADD_F(T,D,F) \
e1000_proc_list_add(proc_list_head, (T), (D), sizeof(*(D)), (F))
#define LIST_ADD_BLANK() LIST_ADD_F("", NULL, NULL)
#define LIST_ADD_S(T,D) LIST_ADD_F((T), (D), e1000_proc_str)
#define LIST_ADD_H(T,D) LIST_ADD_F((T), (D), e1000_proc_hex)
#define LIST_ADD_U(T,D) LIST_ADD_F((T), (D), e1000_proc_unsigned)
static
void
e1000_proc_list_setup
(
struct
e1000_adapter
*
adapter
)
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
struct
list_head
*
proc_list_head
=
&
adapter
->
proc_list_head
;
INIT_LIST_HEAD
(
proc_list_head
);
LIST_ADD_S
(
"Description"
,
adapter
->
id_string
);
LIST_ADD_F
(
"Part_Number"
,
&
adapter
->
part_num
,
e1000_proc_part_number
);
LIST_ADD_S
(
"Driver_Name"
,
e1000_driver_name
);
LIST_ADD_S
(
"Driver_Version"
,
e1000_driver_version
);
LIST_ADD_H
(
"PCI_Vendor"
,
&
hw
->
vendor_id
);
LIST_ADD_H
(
"PCI_Device_ID"
,
&
hw
->
device_id
);
LIST_ADD_H
(
"PCI_Subsystem_Vendor"
,
&
hw
->
subsystem_vendor_id
);
LIST_ADD_H
(
"PCI_Subsystem_ID"
,
&
hw
->
subsystem_id
);
LIST_ADD_H
(
"PCI_Revision_ID"
,
&
hw
->
revision_id
);
LIST_ADD_U
(
"PCI_Bus"
,
&
adapter
->
pdev
->
bus
->
number
);
LIST_ADD_F
(
"PCI_Slot"
,
adapter
,
e1000_proc_slot
);
if
(
adapter
->
hw
.
mac_type
>=
e1000_82543
)
{
LIST_ADD_F
(
"PCI_Bus_Type"
,
&
hw
->
bus_type
,
e1000_proc_bus_type
);
LIST_ADD_F
(
"PCI_Bus_Speed"
,
&
hw
->
bus_speed
,
e1000_proc_bus_speed
);
LIST_ADD_F
(
"PCI_Bus_Width"
,
&
hw
->
bus_width
,
e1000_proc_bus_width
);
}
LIST_ADD_U
(
"IRQ"
,
&
adapter
->
pdev
->
irq
);
LIST_ADD_S
(
"System_Device_Name"
,
adapter
->
ifname
);
LIST_ADD_F
(
"Current_HWaddr"
,
adapter
->
netdev
->
dev_addr
,
e1000_proc_hwaddr
);
LIST_ADD_F
(
"Permanent_HWaddr"
,
adapter
->
hw
.
perm_mac_addr
,
e1000_proc_hwaddr
);
LIST_ADD_BLANK
();
LIST_ADD_F
(
"Link"
,
adapter
,
e1000_proc_link
);
LIST_ADD_F
(
"Speed"
,
&
adapter
->
link_speed
,
e1000_proc_link_speed
);
LIST_ADD_F
(
"Duplex"
,
&
adapter
->
link_duplex
,
e1000_proc_link_duplex
);
LIST_ADD_F
(
"State"
,
adapter
,
e1000_proc_state
);
LIST_ADD_BLANK
();
/* Standard net device stats */
LIST_ADD_U
(
"Rx_Packets"
,
&
adapter
->
net_stats
.
rx_packets
);
LIST_ADD_U
(
"Tx_Packets"
,
&
adapter
->
net_stats
.
tx_packets
);
LIST_ADD_U
(
"Rx_Bytes"
,
&
adapter
->
net_stats
.
rx_bytes
);
LIST_ADD_U
(
"Tx_Bytes"
,
&
adapter
->
net_stats
.
tx_bytes
);
LIST_ADD_U
(
"Rx_Errors"
,
&
adapter
->
net_stats
.
rx_errors
);
LIST_ADD_U
(
"Tx_Errors"
,
&
adapter
->
net_stats
.
tx_errors
);
LIST_ADD_U
(
"Rx_Dropped"
,
&
adapter
->
net_stats
.
rx_dropped
);
LIST_ADD_U
(
"Tx_Dropped"
,
&
adapter
->
net_stats
.
tx_dropped
);
LIST_ADD_U
(
"Multicast"
,
&
adapter
->
net_stats
.
multicast
);
LIST_ADD_U
(
"Collisions"
,
&
adapter
->
net_stats
.
collisions
);
LIST_ADD_U
(
"Rx_Length_Errors"
,
&
adapter
->
net_stats
.
rx_length_errors
);
LIST_ADD_U
(
"Rx_Over_Errors"
,
&
adapter
->
net_stats
.
rx_over_errors
);
LIST_ADD_U
(
"Rx_CRC_Errors"
,
&
adapter
->
net_stats
.
rx_crc_errors
);
LIST_ADD_U
(
"Rx_Frame_Errors"
,
&
adapter
->
net_stats
.
rx_frame_errors
);
LIST_ADD_U
(
"Rx_FIFO_Errors"
,
&
adapter
->
net_stats
.
rx_fifo_errors
);
LIST_ADD_U
(
"Rx_Missed_Errors"
,
&
adapter
->
net_stats
.
rx_missed_errors
);
LIST_ADD_U
(
"Tx_Aborted_Errors"
,
&
adapter
->
net_stats
.
tx_aborted_errors
);
LIST_ADD_U
(
"Tx_Carrier_Errors"
,
&
adapter
->
net_stats
.
tx_carrier_errors
);
LIST_ADD_U
(
"Tx_FIFO_Errors"
,
&
adapter
->
net_stats
.
tx_fifo_errors
);
LIST_ADD_U
(
"Tx_Heartbeat_Errors"
,
&
adapter
->
net_stats
.
tx_heartbeat_errors
);
LIST_ADD_U
(
"Tx_Window_Errors"
,
&
adapter
->
net_stats
.
tx_window_errors
);
/* 8254x-specific stats */
LIST_ADD_U
(
"Tx_Abort_Late_Coll"
,
&
adapter
->
stats
.
latecol
);
LIST_ADD_U
(
"Tx_Deferred_Ok"
,
&
adapter
->
stats
.
dc
);
LIST_ADD_U
(
"Tx_Single_Coll_Ok"
,
&
adapter
->
stats
.
scc
);
LIST_ADD_U
(
"Tx_Multi_Coll_Ok"
,
&
adapter
->
stats
.
mcc
);
LIST_ADD_U
(
"Rx_Long_Length_Errors"
,
&
adapter
->
stats
.
roc
);
LIST_ADD_U
(
"Rx_Short_Length_Errors"
,
&
adapter
->
stats
.
ruc
);
/* The 82542 does not have some of these stats */
if
(
adapter
->
hw
.
mac_type
>=
e1000_82543
)
{
LIST_ADD_U
(
"Rx_Align_Errors"
,
&
adapter
->
stats
.
algnerrc
);
LIST_ADD_U
(
"Tx_TCP_Seg_Good"
,
&
adapter
->
stats
.
tsctc
);
LIST_ADD_U
(
"Tx_TCP_Seg_Failed"
,
&
adapter
->
stats
.
tsctfc
);
}
LIST_ADD_U
(
"Rx_Flow_Control_XON"
,
&
adapter
->
stats
.
xonrxc
);
LIST_ADD_U
(
"Rx_Flow_Control_XOFF"
,
&
adapter
->
stats
.
xoffrxc
);
LIST_ADD_U
(
"Tx_Flow_Control_XON"
,
&
adapter
->
stats
.
xontxc
);
LIST_ADD_U
(
"Tx_Flow_Control_XOFF"
,
&
adapter
->
stats
.
xofftxc
);
LIST_ADD_U
(
"Rx_CSum_Offload_Good"
,
&
adapter
->
hw_csum_good
);
LIST_ADD_U
(
"Rx_CSum_Offload_Errors"
,
&
adapter
->
hw_csum_err
);
LIST_ADD_BLANK
();
/* Cable diags */
LIST_ADD_F
(
"PHY_Media_Type"
,
adapter
,
e1000_proc_media_type
);
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_copper
)
{
LIST_ADD_F
(
"PHY_Cable_Length"
,
adapter
,
e1000_proc_cable_length
);
LIST_ADD_F
(
"PHY_Extended_10Base_T_Distance"
,
adapter
,
e1000_proc_extended
);
LIST_ADD_F
(
"PHY_Cable_Polarity"
,
adapter
,
e1000_proc_cable_polarity
);
LIST_ADD_F
(
"PHY_Disable_Polarity_Correction"
,
adapter
,
e1000_proc_polarity_correction
);
LIST_ADD_U
(
"PHY_Idle_Errors"
,
&
adapter
->
phy_stats
.
idle_errors
);
LIST_ADD_U
(
"PHY_Receive_Errors"
,
&
adapter
->
phy_stats
.
receive_errors
);
LIST_ADD_F
(
"PHY_MDI_X_Enabled"
,
adapter
,
e1000_proc_mdi_x_enabled
);
LIST_ADD_F
(
"PHY_Local_Receiver_Status"
,
&
adapter
->
phy_info
.
local_rx
,
e1000_proc_rx_status
);
LIST_ADD_F
(
"PHY_Remote_Receiver_Status"
,
&
adapter
->
phy_info
.
remote_rx
,
e1000_proc_rx_status
);
}
}
/*
* e1000_proc_dev_setup - create proc fs nodes and link list
* @adapter: board private structure
*/
void
e1000_proc_dev_setup
(
struct
e1000_adapter
*
adapter
)
{
e1000_proc_list_setup
(
adapter
);
e1000_proc_dirs_create
(
adapter
,
adapter
->
ifname
,
&
adapter
->
proc_list_head
);
}
/*
* e1000_proc_dev_free - free proc fs nodes and link list
* @adapter: board private structure
*/
void
e1000_proc_dev_free
(
struct
e1000_adapter
*
adapter
)
{
e1000_proc_dirs_free
(
adapter
->
ifname
,
&
adapter
->
proc_list_head
);
e1000_proc_list_free
(
&
adapter
->
proc_list_head
);
}
#else
/* CONFIG_PROC_FS */
void
e1000_proc_dev_setup
(
struct
e1000_adapter
*
adapter
)
{}
void
e1000_proc_dev_free
(
struct
e1000_adapter
*
adapter
)
{}
#endif
/* CONFIG_PROC_FS */
drivers/net/tg3.c
View file @
7f4174f1
/*
$Id: tg3.c,v 1.43.2.80 2002/03/14 00:10:04 davem Exp $
/*
* tg3.c: Broadcom Tigon3 ethernet driver.
*
* Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
...
...
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.
2a
"
#define DRV_MODULE_RELDATE "
Dec 9, 2002
"
#define DRV_MODULE_VERSION "1.
4
"
#define DRV_MODULE_RELDATE "
Feb 1, 2003
"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
...
...
@@ -141,6 +141,12 @@ static struct pci_device_id tg3_pci_tbl[] __devinitdata = {
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_TIGON3_5703X
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_TIGON3_5704S
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_TIGON3_5702A3
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_BROADCOM
,
PCI_DEVICE_ID_TIGON3_5703A3
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_SYSKONNECT
,
0x4400
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_ALTIMA
,
PCI_DEVICE_ID_ALTIMA_AC1000
,
...
...
@@ -163,6 +169,8 @@ static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
spin_unlock_irqrestore
(
&
tp
->
indirect_lock
,
flags
);
}
else
{
writel
(
val
,
tp
->
regs
+
off
);
if
((
tp
->
tg3_flags
&
TG3_FLAG_5701_REG_WRITE_BUG
)
!=
0
)
readl
(
tp
->
regs
+
off
);
}
}
...
...
@@ -213,28 +221,11 @@ static void tg3_enable_ints(struct tg3 *tp)
tw32
(
TG3PCI_MISC_HOST_CTRL
,
(
tp
->
misc_host_ctrl
&
~
MISC_HOST_CTRL_MASK_PCI_INT
));
tw32_mailbox
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
,
0x00000000
);
if
(
tp
->
hw_status
->
status
&
SD_STATUS_UPDATED
)
{
tw32
(
GRC_LOCAL_CTRL
,
tp
->
grc_local_ctrl
|
GRC_LCLCTRL_SETINT
);
}
tr32
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
);
}
static
inline
void
tg3_mask_ints
(
struct
tg3
*
tp
)
{
tw32
(
TG3PCI_MISC_HOST_CTRL
,
(
tp
->
misc_host_ctrl
|
MISC_HOST_CTRL_MASK_PCI_INT
));
}
static
inline
void
tg3_unmask_ints
(
struct
tg3
*
tp
)
{
tw32
(
TG3PCI_MISC_HOST_CTRL
,
(
tp
->
misc_host_ctrl
&
~
MISC_HOST_CTRL_MASK_PCI_INT
));
if
(
tp
->
hw_status
->
status
&
SD_STATUS_UPDATED
)
{
if
(
tp
->
hw_status
->
status
&
SD_STATUS_UPDATED
)
tw32
(
GRC_LOCAL_CTRL
,
tp
->
grc_local_ctrl
|
GRC_LCLCTRL_SETINT
);
}
}
static
void
tg3_switch_clocks
(
struct
tg3
*
tp
)
...
...
@@ -900,6 +891,20 @@ static int tg3_setup_copper_phy(struct tg3 *tp)
tg3_writephy
(
tp
,
MII_TG3_AUX_CTRL
,
0x02
);
/* Some third-party PHYs need to be reset on link going
* down.
*
* XXX 5705 note: This workaround also applies to 5705_a0
*/
if
((
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5703
||
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
&&
netif_carrier_ok
(
tp
->
dev
))
{
tg3_readphy
(
tp
,
MII_BMSR
,
&
bmsr
);
tg3_readphy
(
tp
,
MII_BMSR
,
&
bmsr
);
if
(
!
(
bmsr
&
BMSR_LSTATUS
))
tg3_phy_reset
(
tp
,
1
);
}
if
((
tp
->
phy_id
&
PHY_ID_MASK
)
==
PHY_ID_BCM5401
)
{
tg3_readphy
(
tp
,
MII_BMSR
,
&
bmsr
);
tg3_readphy
(
tp
,
MII_BMSR
,
&
bmsr
);
...
...
@@ -1958,13 +1963,12 @@ static int tg3_rx(struct tg3 *tp, int budget)
}
if
((
tp
->
tg3_flags
&
TG3_FLAG_RX_CHECKSUMS
)
&&
(
desc
->
type_flags
&
RXD_FLAG_TCPUDP_CSUM
)
)
{
skb
->
csum
=
htons
((
desc
->
ip_tcp_csum
&
RXD_TCPCSUM_MASK
)
>>
RXD_TCPCSUM_SHIFT
);
skb
->
ip_summed
=
CHECKSUM_
HW
;
}
else
{
(
desc
->
type_flags
&
RXD_FLAG_TCPUDP_CSUM
)
&&
(
((
desc
->
ip_tcp_csum
&
RXD_TCPCSUM_MASK
)
>>
RXD_TCPCSUM_SHIFT
)
==
0xffff
))
skb
->
ip_summed
=
CHECKSUM_
UNNECESSARY
;
else
skb
->
ip_summed
=
CHECKSUM_NONE
;
}
skb
->
protocol
=
eth_type_trans
(
skb
,
tp
->
dev
);
#if TG3_VLAN_TAG_USED
...
...
@@ -2017,10 +2021,12 @@ static int tg3_poll(struct net_device *netdev, int *budget)
{
struct
tg3
*
tp
=
netdev
->
priv
;
struct
tg3_hw_status
*
sblk
=
tp
->
hw_status
;
unsigned
long
flags
;
int
done
;
spin_lock_irq
(
&
tp
->
lock
);
spin_lock_irq
save
(
&
tp
->
lock
,
flags
);
/* handle link change and other phy events */
if
(
!
(
tp
->
tg3_flags
&
(
TG3_FLAG_USE_LINKCHG_REG
|
TG3_FLAG_POLL_SERDES
)))
{
...
...
@@ -2031,12 +2037,14 @@ static int tg3_poll(struct net_device *netdev, int *budget)
}
}
/* run TX completion thread */
if
(
sblk
->
idx
[
0
].
tx_consumer
!=
tp
->
tx_cons
)
{
spin_lock
(
&
tp
->
tx_lock
);
tg3_tx
(
tp
);
spin_unlock
(
&
tp
->
tx_lock
);
}
/* run RX thread, within the bounds set by NAPI */
done
=
1
;
if
(
sblk
->
idx
[
0
].
rx_producer
!=
tp
->
rx_rcb_ptr
)
{
int
orig_budget
=
*
budget
;
...
...
@@ -2054,44 +2062,35 @@ static int tg3_poll(struct net_device *netdev, int *budget)
done
=
0
;
}
/* if no more work, tell net stack and NIC we're done */
if
(
done
)
{
netif_rx_complete
(
netdev
);
tg3_
unmask
_ints
(
tp
);
tg3_
enable
_ints
(
tp
);
}
spin_unlock_irq
(
&
tp
->
lock
);
spin_unlock_irq
restore
(
&
tp
->
lock
,
flags
);
return
(
done
?
0
:
1
);
}
static
__inline__
void
tg3_interrupt_main
_work
(
struct
net_device
*
dev
,
struct
tg3
*
tp
)
static
inline
unsigned
int
tg3_has
_work
(
struct
net_device
*
dev
,
struct
tg3
*
tp
)
{
struct
tg3_hw_status
*
sblk
=
tp
->
hw_status
;
int
work_exists
=
0
;
unsigned
int
work_exists
=
0
;
/* check for phy events */
if
(
!
(
tp
->
tg3_flags
&
(
TG3_FLAG_USE_LINKCHG_REG
|
TG3_FLAG_POLL_SERDES
)))
{
if
(
sblk
->
status
&
SD_STATUS_LINK_CHG
)
work_exists
=
1
;
}
/* check for RX/TX work to do */
if
(
sblk
->
idx
[
0
].
tx_consumer
!=
tp
->
tx_cons
||
sblk
->
idx
[
0
].
rx_producer
!=
tp
->
rx_rcb_ptr
)
work_exists
=
1
;
if
(
!
work_exists
)
return
;
if
(
netif_rx_schedule_prep
(
dev
))
{
/* NOTE: These writes are posted by the readback of
* the mailbox register done by our caller.
*/
tg3_mask_ints
(
tp
);
__netif_rx_schedule
(
dev
);
}
else
{
printk
(
KERN_ERR
PFX
"%s: Error, poll already scheduled
\n
"
,
dev
->
name
);
}
return
work_exists
;
}
static
void
tg3_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
...
...
@@ -2104,15 +2103,32 @@ static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_lock_irqsave
(
&
tp
->
lock
,
flags
);
if
(
sblk
->
status
&
SD_STATUS_UPDATED
)
{
/*
* writing any value to intr-mbox-0 clears PCI INTA# and
* chip-internal interrupt pending events.
* writing non-zero to intr-mbox-0 additional tells the
* NIC to stop sending us irqs, engaging "in-intr-handler"
* event coalescing.
*/
tw32_mailbox
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
,
0x00000001
);
/*
* Flush PCI write. This also guarantees that our
* status block has been flushed to host memory.
*/
tr32
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
);
sblk
->
status
&=
~
SD_STATUS_UPDATED
;
tg3_interrupt_main_work
(
dev
,
tp
);
tw32_mailbox
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
,
0x00000000
);
tr32
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
);
if
(
likely
(
tg3_has_work
(
dev
,
tp
)))
netif_rx_schedule
(
dev
);
/* schedule NAPI poll */
else
{
/* no work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
*/
tw32_mailbox
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
,
0x00000000
);
tr32
(
MAILBOX_INTERRUPT_0
+
TG3_64BIT_REG_LOW
);
}
}
spin_unlock_irqrestore
(
&
tp
->
lock
,
flags
);
...
...
@@ -2213,11 +2229,6 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
return
-
1
;
}
/* NOTE: Broadcom's driver botches this case up really bad.
* This is especially true if any of the frag pages
* are in highmem. It will instantly oops in that case.
*/
/* New SKB is guarenteed to be linear. */
entry
=
*
start
;
new_addr
=
pci_map_single
(
tp
->
pdev
,
new_skb
->
data
,
new_skb
->
len
,
...
...
@@ -2649,6 +2660,17 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
return
0
;
}
static
inline
void
tg3_set_mtu
(
struct
net_device
*
dev
,
struct
tg3
*
tp
,
int
new_mtu
)
{
dev
->
mtu
=
new_mtu
;
if
(
new_mtu
>
ETH_DATA_LEN
)
tp
->
tg3_flags
|=
TG3_FLAG_JUMBO_ENABLE
;
else
tp
->
tg3_flags
&=
~
TG3_FLAG_JUMBO_ENABLE
;
}
static
int
tg3_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
struct
tg3
*
tp
=
dev
->
priv
;
...
...
@@ -2660,7 +2682,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
/* We'll just catch it later when the
* device is up'd.
*/
dev
->
mtu
=
new_mtu
;
tg3_set_mtu
(
dev
,
tp
,
new_mtu
)
;
return
0
;
}
...
...
@@ -2669,12 +2691,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_halt
(
tp
);
dev
->
mtu
=
new_mtu
;
if
(
new_mtu
>
ETH_DATA_LEN
)
tp
->
tg3_flags
|=
TG3_FLAG_JUMBO_ENABLE
;
else
tp
->
tg3_flags
&=
~
TG3_FLAG_JUMBO_ENABLE
;
tg3_set_mtu
(
dev
,
tp
,
new_mtu
);
tg3_init_rings
(
tp
);
tg3_init_hw
(
tp
);
...
...
@@ -4285,6 +4302,12 @@ static int tg3_reset_hw(struct tg3 *tp)
if
(
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5703_A1
)
tw32
(
MAC_SERDES_CFG
,
0x616000
);
/* Prevent chip from dropping frames when flow control
* is enabled.
*/
tw32
(
MAC_LOW_WMARK_MAX_RX_FRAME
,
2
);
tr32
(
MAC_LOW_WMARK_MAX_RX_FRAME
);
err
=
tg3_setup_phy
(
tp
);
if
(
err
)
return
err
;
...
...
@@ -4353,8 +4376,9 @@ static int tg3_init_hw(struct tg3 *tp)
static
void
tg3_timer
(
unsigned
long
__opaque
)
{
struct
tg3
*
tp
=
(
struct
tg3
*
)
__opaque
;
unsigned
long
flags
;
spin_lock_irq
(
&
tp
->
lock
);
spin_lock_irq
save
(
&
tp
->
lock
,
flags
);
spin_lock
(
&
tp
->
tx_lock
);
/* All of this garbage is because when using non-tagged
...
...
@@ -4436,7 +4460,7 @@ static void tg3_timer(unsigned long __opaque)
}
spin_unlock
(
&
tp
->
tx_lock
);
spin_unlock_irq
(
&
tp
->
lock
);
spin_unlock_irq
restore
(
&
tp
->
lock
,
flags
);
tp
->
timer
.
expires
=
jiffies
+
tp
->
timer_offset
;
add_timer
(
&
tp
->
timer
);
...
...
@@ -5793,7 +5817,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
tg3_writephy
(
tp
,
MII_TG3_DSP_RW_PORT
,
0x2aaa
);
}
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
{
if
((
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
&&
(
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5704_A0
))
{
tg3_writephy
(
tp
,
0x1c
,
0x8d68
);
tg3_writephy
(
tp
,
0x1c
,
0x8d68
);
}
...
...
@@ -5999,6 +6024,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
pci_write_config_word
(
tp
->
pdev
,
PCI_COMMAND
,
pci_cmd
);
}
}
/* Back to back register writes can cause problems on this chip,
* the workaround is to read back all reg writes except those to
* mailbox regs. See tg3_write_indirect_reg32().
*/
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5701
)
tp
->
tg3_flags
|=
TG3_FLAG_5701_REG_WRITE_BUG
;
if
((
pci_state_reg
&
PCISTATE_BUS_SPEED_HIGH
)
!=
0
)
tp
->
tg3_flags
|=
TG3_FLAG_PCI_HIGH_SPEED
;
if
((
pci_state_reg
&
PCISTATE_BUS_32BIT
)
!=
0
)
...
...
@@ -6013,8 +6046,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* Force the chip into D0. */
err
=
tg3_set_power_state
(
tp
,
0
);
if
(
err
)
if
(
err
)
{
printk
(
KERN_ERR
PFX
"(%s) transition to D0 failed
\n
"
,
tp
->
pdev
->
slot_name
);
return
err
;
}
/* 5700 B0 chips do not support checksumming correctly due
* to hardware bugs.
...
...
@@ -6022,18 +6058,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if
(
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5700_B0
)
tp
->
tg3_flags
|=
TG3_FLAG_BROKEN_CHECKSUMS
;
/* Regardless of whether checksums work or not, we configure
* the StrongARM chips to not compute the pseudo header checksums
* in either direction. Because of the way Linux checksum support
* works we do not need the chips to do this, and taking the load
* off of the TX/RX onboard StrongARM cpus means that they will not be
* the bottleneck. Whoever wrote Broadcom's driver did not
* understand the situation at all. He could have bothered
* to read Jes's Acenic driver because the logic (and this part of
* the Tigon2 hardware/firmware) is pretty much identical.
/* Pseudo-header checksum is done by hardware logic and not
* the offload processers, so make the chip do the pseudo-
* header checksums on receive. For transmit it is more
* convenient to do the pseudo-header checksum in software
* as Linux does that on transmit for us in all cases.
*/
tp
->
tg3_flags
|=
TG3_FLAG_NO_TX_PSEUDO_CSUM
;
tp
->
tg3_flags
|=
TG3_FLAG_NO_RX_PSEUDO_CSUM
;
tp
->
tg3_flags
&=
~
TG3_FLAG_NO_RX_PSEUDO_CSUM
;
/* Derive initial jumbo mode from MTU assigned in
* ether_setup() via the alloc_etherdev() call
...
...
@@ -6111,19 +6143,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
if
(
tp
->
tg3_flags
&
TG3_FLAG_PCIX_TARGET_HWBUG
)
tp
->
tg3_flags
|=
TG3_FLAG_HOST_TXDS
;
/* Quick sanity check. Make sure we see an expected
* value here.
*/
grc_misc_cfg
=
tr32
(
GRC_MISC_CFG
);
grc_misc_cfg
&=
GRC_MISC_CFG_BOARD_ID_MASK
;
if
(
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5700
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5701
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5702FE
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5703
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5703S
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_5704
&&
grc_misc_cfg
!=
GRC_MISC_CFG_BOARD_ID_AC91002A1
)
return
-
ENODEV
;
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
&&
grc_misc_cfg
==
GRC_MISC_CFG_BOARD_ID_5704CIOBE
)
{
...
...
@@ -6131,14 +6152,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp
->
split_mode_max_reqs
=
SPLIT_MODE_5704_MAX_REQ
;
}
/* ROFL, you should see Broadcom's driver code implementing
* this, stuff like "if (a || b)" where a and b are always
* mutually exclusive. DaveM finds like 6 bugs today, hello!
*/
/* this one is limited to 10/100 only */
if
(
grc_misc_cfg
==
GRC_MISC_CFG_BOARD_ID_5702FE
)
tp
->
tg3_flags
|=
TG3_FLAG_10_100_ONLY
;
err
=
tg3_phy_probe
(
tp
);
if
(
err
)
{
printk
(
KERN_ERR
PFX
"(%s) phy probe failed, err %d
\n
"
,
tp
->
pdev
->
slot_name
,
err
);
/* ... but do not return immediately ... */
}
tg3_read_partno
(
tp
);
...
...
@@ -6192,17 +6215,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* 5700 chips can get confused if TX buffers straddle the
* 4GB address boundary in some cases.
*/
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5700
)
{
/* ROFL! Latest Broadcom driver disables NETIF_F_HIGHDMA
* in this case instead of fixing their workaround code.
*
* Like, hey, there is this skb_copy() thing guys,
* use it. Oh I can't stop laughing...
*/
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5700
)
tp
->
dev
->
hard_start_xmit
=
tg3_start_xmit_4gbug
;
}
else
{
else
tp
->
dev
->
hard_start_xmit
=
tg3_start_xmit
;
}
tp
->
rx_offset
=
2
;
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5701
&&
...
...
@@ -6368,6 +6384,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
(
0x7
<<
DMA_RWCTRL_WRITE_WATER_SHIFT
)
|
(
0x7
<<
DMA_RWCTRL_READ_WATER_SHIFT
)
|
(
0x0f
<<
DMA_RWCTRL_MIN_DMA_SHIFT
);
/* XXX 5705 note: set MIN_DMA to zero here */
}
else
{
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
tp
->
dma_rwctrl
=
...
...
@@ -6385,13 +6402,20 @@ static int __devinit tg3_test_dma(struct tg3 *tp)
(
0x0f
<<
DMA_RWCTRL_MIN_DMA_SHIFT
);
/* Wheee, some more chip bugs... */
if
(
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5703_A1
||
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5703_A2
||
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5703_A3
||
tp
->
pci_chip_rev_id
==
CHIPREV_ID_5704_A0
)
tp
->
dma_rwctrl
|=
DMA_RWCTRL_ONE_DMA
;
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5703
||
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
{
u32
ccval
=
(
tr32
(
TG3PCI_CLOCK_CTRL
)
&
0x1f
);
if
(
ccval
==
0x6
||
ccval
==
0x7
)
tp
->
dma_rwctrl
|=
DMA_RWCTRL_ONE_DMA
;
}
}
if
(
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5703
||
GET_ASIC_REV
(
tp
->
pci_chip_rev_id
)
==
ASIC_REV_5704
)
tp
->
dma_rwctrl
&=
~
(
DMA_RWCTRL_MIN_DMA
<<
DMA_RWCTRL_MIN_DMA_SHIFT
);
/* We don't do this on x86 because it seems to hurt performace.
* It does help things on other platforms though.
*/
...
...
drivers/net/tg3.h
View file @
7f4174f1
...
...
@@ -113,6 +113,8 @@
#define CHIPREV_ID_5703_A2 0x1002
#define CHIPREV_ID_5703_A3 0x1003
#define CHIPREV_ID_5704_A0 0x2000
#define CHIPREV_ID_5704_A1 0x2001
#define CHIPREV_ID_5704_A2 0x2002
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
...
...
@@ -454,6 +456,7 @@
#define RCV_RULE_DISABLE_MASK 0x7fffffff
#define MAC_RCV_RULE_CFG 0x00000500
#define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008
#define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504
/* 0x504 --> 0x590 unused */
#define MAC_SERDES_CFG 0x00000590
#define MAC_SERDES_STAT 0x00000594
...
...
@@ -1136,6 +1139,7 @@
#define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000
#define GRC_MISC_CFG_BOARD_ID_5704 0x00000000
#define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
#define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000
#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
#define GRC_LOCAL_CTRL 0x00006808
#define GRC_LCLCTRL_INT_ACTIVE 0x00000001
...
...
@@ -1791,6 +1795,7 @@ struct tg3 {
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
#define TG3_FLAG_ENABLE_ASF 0x00000020
#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040
#define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
...
...
include/linux/pci_ids.h
View file @
7f4174f1
...
...
@@ -1661,6 +1661,9 @@
#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d
#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
#define PCI_DEVICE_ID_BCM4401 0x4401
#define PCI_VENDOR_ID_SYBA 0x1592
...
...
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