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
nexedi
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
Show 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
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
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
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. */
...
...
@@ -279,9 +299,8 @@ 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,17 +220,23 @@ 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,16 +2103,33 @@ 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
);
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,12 +6402,19 @@ 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
)
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