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
7991c128
Commit
7991c128
authored
May 27, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/spare/repo/netdev-2.6/e1000
into redhat.com:/spare/repo/net-drivers-2.6
parents
b54885f9
a1360dde
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
505 additions
and
611 deletions
+505
-611
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000.h
+8
-0
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_ethtool.c
+304
-414
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.c
+22
-11
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_hw.h
+9
-7
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_main.c
+106
-134
drivers/net/e1000/e1000_param.c
drivers/net/e1000/e1000_param.c
+56
-45
No files found.
drivers/net/e1000/e1000.h
View file @
7991c128
...
...
@@ -71,6 +71,7 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/moduleparam.h>
#define BAR_0 0
#define BAR_1 1
...
...
@@ -89,6 +90,12 @@ struct e1000_adapter;
#define E1000_ERR(args...) printk(KERN_ERR "e1000: " args)
#define PFX "e1000: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
__FUNCTION__ , ## args))
#define E1000_MAX_INTR 10
/* How many descriptors for TX and RX ? */
...
...
@@ -245,5 +252,6 @@ struct e1000_adapter {
uint32_t
pci_state
[
16
];
int
msg_enable
;
};
#endif
/* _E1000_H_ */
drivers/net/e1000/e1000_ethtool.c
View file @
7991c128
...
...
@@ -53,7 +53,7 @@ struct e1000_stats {
#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
offsetof(struct e1000_adapter, m)
static
struct
e1000_stats
e1000_gstrings_stats
[]
=
{
static
const
struct
e1000_stats
e1000_gstrings_stats
[]
=
{
{
"rx_packets"
,
E1000_STAT
(
net_stats
.
rx_packets
)
},
{
"tx_packets"
,
E1000_STAT
(
net_stats
.
tx_packets
)
},
{
"rx_bytes"
,
E1000_STAT
(
net_stats
.
rx_bytes
)
},
...
...
@@ -89,20 +89,22 @@ static struct e1000_stats e1000_gstrings_stats[] = {
{
"tx_flow_control_xon"
,
E1000_STAT
(
stats
.
xontxc
)
},
{
"tx_flow_control_xoff"
,
E1000_STAT
(
stats
.
xofftxc
)
},
{
"rx_csum_offload_good"
,
E1000_STAT
(
hw_csum_good
)
},
{
"rx_csum_offload_errors"
,
E1000_STAT
(
hw_csum_err
)
}
{
"rx_csum_offload_errors"
,
E1000_STAT
(
hw_csum_err
)
},
{
"rx_long_byte_count"
,
E1000_STAT
(
stats
.
gorcl
)
}
};
#define E1000_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
static
char
e1000_gstrings_test
[][
ETH_GSTRING_LEN
]
=
{
static
c
onst
c
har
e1000_gstrings_test
[][
ETH_GSTRING_LEN
]
=
{
"Register test (offline)"
,
"Eeprom test (offline)"
,
"Interrupt test (offline)"
,
"Loopback test (offline)"
,
"Link test (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
static
void
e1000_
ethtool_gset
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_cmd
*
ecmd
)
static
int
e1000_
get_settings
(
struct
net_device
*
netdev
,
struct
ethtool_cmd
*
ecmd
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
if
(
hw
->
media_type
==
e1000_media_type_copper
)
{
...
...
@@ -169,11 +171,13 @@ e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
}
ecmd
->
autoneg
=
(
hw
->
autoneg
?
AUTONEG_ENABLE
:
AUTONEG_DISABLE
);
return
0
;
}
static
int
e1000_
ethtool_sset
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_cmd
*
ecmd
)
e1000_
set_settings
(
struct
net_device
*
netdev
,
struct
ethtool_cmd
*
ecmd
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
...
...
@@ -195,42 +199,41 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
return
0
;
}
static
int
e1000_
ethtool_gpause
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_pauseparam
*
e
pause
)
static
void
e1000_
get_pauseparam
(
struct
net_device
*
netdev
,
struct
ethtool_pauseparam
*
pause
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
epause
->
autoneg
=
pause
->
autoneg
=
(
adapter
->
fc_autoneg
?
AUTONEG_ENABLE
:
AUTONEG_DISABLE
);
if
(
hw
->
fc
==
e1000_fc_rx_pause
)
e
pause
->
rx_pause
=
1
;
pause
->
rx_pause
=
1
;
else
if
(
hw
->
fc
==
e1000_fc_tx_pause
)
e
pause
->
tx_pause
=
1
;
pause
->
tx_pause
=
1
;
else
if
(
hw
->
fc
==
e1000_fc_full
)
{
e
pause
->
rx_pause
=
1
;
e
pause
->
tx_pause
=
1
;
pause
->
rx_pause
=
1
;
pause
->
tx_pause
=
1
;
}
return
0
;
}
static
int
e1000_
ethtool_spause
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_pauseparam
*
e
pause
)
static
int
e1000_
set_pauseparam
(
struct
net_device
*
netdev
,
struct
ethtool_pauseparam
*
pause
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
adapter
->
fc_autoneg
=
e
pause
->
autoneg
;
adapter
->
fc_autoneg
=
pause
->
autoneg
;
if
(
epause
->
rx_pause
&&
e
pause
->
tx_pause
)
if
(
pause
->
rx_pause
&&
pause
->
tx_pause
)
hw
->
fc
=
e1000_fc_full
;
else
if
(
epause
->
rx_pause
&&
!
e
pause
->
tx_pause
)
else
if
(
pause
->
rx_pause
&&
!
pause
->
tx_pause
)
hw
->
fc
=
e1000_fc_rx_pause
;
else
if
(
!
epause
->
rx_pause
&&
e
pause
->
tx_pause
)
else
if
(
!
pause
->
rx_pause
&&
pause
->
tx_pause
)
hw
->
fc
=
e1000_fc_tx_pause
;
else
if
(
!
epause
->
rx_pause
&&
!
e
pause
->
tx_pause
)
else
if
(
!
pause
->
rx_pause
&&
!
pause
->
tx_pause
)
hw
->
fc
=
e1000_fc_none
;
hw
->
original_fc
=
hw
->
fc
;
...
...
@@ -248,28 +251,124 @@ e1000_ethtool_spause(struct e1000_adapter *adapter,
return
0
;
}
static
uint32_t
e1000_get_rx_csum
(
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
return
adapter
->
rx_csum
;
}
static
int
e1000_set_rx_csum
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
adapter
->
rx_csum
=
data
;
if
(
netif_running
(
netdev
))
{
e1000_down
(
adapter
);
e1000_up
(
adapter
);
}
else
e1000_reset
(
adapter
);
return
0
;
}
static
uint32_t
e1000_get_tx_csum
(
struct
net_device
*
netdev
)
{
return
(
netdev
->
features
&
NETIF_F_HW_CSUM
)
!=
0
;
}
static
int
e1000_set_tx_csum
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
if
(
adapter
->
hw
.
mac_type
<
e1000_82543
)
{
if
(
!
data
)
return
-
EINVAL
;
return
0
;
}
if
(
data
)
netdev
->
features
|=
NETIF_F_HW_CSUM
;
else
netdev
->
features
&=
~
NETIF_F_HW_CSUM
;
return
0
;
}
static
uint32_t
e1000_get_sg
(
struct
net_device
*
netdev
)
{
return
(
netdev
->
features
&
NETIF_F_SG
)
!=
0
;
}
static
int
e1000_set_sg
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
if
(
data
)
netdev
->
features
|=
NETIF_F_SG
;
else
netdev
->
features
&=
~
NETIF_F_SG
;
return
0
;
}
#ifdef NETIF_F_TSO
static
uint32_t
e1000_get_tso
(
struct
net_device
*
netdev
)
{
return
(
netdev
->
features
&
NETIF_F_TSO
)
!=
0
;
}
static
int
e1000_set_tso
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
if
((
adapter
->
hw
.
mac_type
<
e1000_82544
)
||
(
adapter
->
hw
.
mac_type
==
e1000_82547
))
return
data
?
-
EINVAL
:
0
;
if
(
data
)
netdev
->
features
|=
NETIF_F_TSO
;
else
netdev
->
features
&=
~
NETIF_F_TSO
;
return
0
;
}
#endif
/* NETIF_F_TSO */
static
uint32_t
e1000_get_msglevel
(
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
return
adapter
->
msg_enable
;
}
static
void
e1000_ethtool_gdrvinfo
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_drvinfo
*
drvinfo
)
e1000_set_msglevel
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
adapter
->
msg_enable
=
data
;
}
static
int
e1000_get_regs_len
(
struct
net_device
*
netdev
)
{
strncpy
(
drvinfo
->
driver
,
e1000_driver_name
,
32
);
strncpy
(
drvinfo
->
version
,
e1000_driver_version
,
32
);
strncpy
(
drvinfo
->
fw_version
,
"N/A"
,
32
);
strncpy
(
drvinfo
->
bus_info
,
pci_name
(
adapter
->
pdev
),
32
);
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
drvinfo
->
testinfo_len
=
E1000_TEST_LEN
;
#define E1000_REGS_LEN 32
drvinfo
->
regdump_len
=
E1000_REGS_LEN
*
sizeof
(
uint32_t
);
drvinfo
->
eedump_len
=
adapter
->
hw
.
eeprom
.
word_size
*
2
;
return
E1000_REGS_LEN
*
sizeof
(
uint32_t
);
}
static
void
e1000_
ethtool_gregs
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_regs
*
regs
,
uint32_t
*
regs_buff
)
e1000_
get_regs
(
struct
net_device
*
netdev
,
struct
ethtool_regs
*
regs
,
void
*
p
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint32_t
*
regs_buff
=
p
;
uint16_t
phy_data
;
memset
(
p
,
0
,
E1000_REGS_LEN
*
sizeof
(
uint32_t
));
regs
->
version
=
(
1
<<
24
)
|
(
hw
->
revision_id
<<
16
)
|
hw
->
device_id
;
regs_buff
[
0
]
=
E1000_READ_REG
(
hw
,
CTRL
);
...
...
@@ -342,37 +441,39 @@ e1000_ethtool_gregs(struct e1000_adapter *adapter,
e1000_read_phy_reg
(
hw
,
PHY_1000T_STATUS
,
&
phy_data
);
regs_buff
[
24
]
=
(
uint32_t
)
phy_data
;
/* phy local receiver status */
regs_buff
[
25
]
=
regs_buff
[
24
];
/* phy remote receiver status */
}
return
;
static
int
e1000_get_eeprom_len
(
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
return
adapter
->
hw
.
eeprom
.
word_size
*
2
;
}
static
int
e1000_
ethtool_geeprom
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_eeprom
*
eeprom
,
uint
16_t
*
eeprom_buff
)
e1000_
get_eeprom
(
struct
net_device
*
netdev
,
struct
ethtool_eeprom
*
eeprom
,
uint
8_t
*
bytes
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
*
eeprom_buff
;
int
first_word
,
last_word
;
int
ret_val
=
0
;
uint16_t
i
;
if
(
eeprom
->
len
==
0
)
{
ret_val
=
-
EINVAL
;
goto
geeprom_error
;
}
if
(
eeprom
->
len
==
0
)
return
-
EINVAL
;
eeprom
->
magic
=
hw
->
vendor_id
|
(
hw
->
device_id
<<
16
);
if
(
eeprom
->
offset
>
eeprom
->
offset
+
eeprom
->
len
)
{
ret_val
=
-
EINVAL
;
goto
geeprom_error
;
}
if
((
eeprom
->
offset
+
eeprom
->
len
)
>
(
hw
->
eeprom
.
word_size
*
2
))
eeprom
->
len
=
((
hw
->
eeprom
.
word_size
*
2
)
-
eeprom
->
offset
);
first_word
=
eeprom
->
offset
>>
1
;
last_word
=
(
eeprom
->
offset
+
eeprom
->
len
-
1
)
>>
1
;
eeprom_buff
=
kmalloc
(
sizeof
(
uint16_t
)
*
(
last_word
-
first_word
+
1
),
GFP_KERNEL
);
if
(
!
eeprom_buff
)
return
-
ENOMEM
;
if
(
hw
->
eeprom
.
type
==
e1000_eeprom_spi
)
ret_val
=
e1000_read_eeprom
(
hw
,
first_word
,
last_word
-
first_word
+
1
,
...
...
@@ -388,14 +489,19 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
for
(
i
=
0
;
i
<
last_word
-
first_word
+
1
;
i
++
)
le16_to_cpus
(
&
eeprom_buff
[
i
]);
geeprom_error:
memcpy
(
bytes
,
(
uint8_t
*
)
eeprom_buff
+
(
eeprom
->
offset
%
2
),
eeprom
->
len
);
kfree
(
eeprom_buff
);
return
ret_val
;
}
static
int
e1000_
ethtool_seeprom
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_eeprom
*
eeprom
,
void
*
user_data
)
e1000_
set_eeprom
(
struct
net_device
*
netdev
,
struct
ethtool_eeprom
*
eeprom
,
uint8_t
*
bytes
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
*
eeprom_buff
;
void
*
ptr
;
...
...
@@ -410,9 +516,6 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
max_len
=
hw
->
eeprom
.
word_size
*
2
;
if
((
eeprom
->
offset
+
eeprom
->
len
)
>
max_len
)
eeprom
->
len
=
(
max_len
-
eeprom
->
offset
);
first_word
=
eeprom
->
offset
>>
1
;
last_word
=
(
eeprom
->
offset
+
eeprom
->
len
-
1
)
>>
1
;
eeprom_buff
=
kmalloc
(
max_len
,
GFP_KERNEL
);
...
...
@@ -439,11 +542,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
for
(
i
=
0
;
i
<
last_word
-
first_word
+
1
;
i
++
)
le16_to_cpus
(
&
eeprom_buff
[
i
]);
if
((
ret_val
!=
0
)
||
copy_from_user
(
ptr
,
user_data
,
eeprom
->
len
))
{
ret_val
=
-
EFAULT
;
goto
seeprom_error
;
}
memcpy
(
ptr
,
bytes
,
eeprom
->
len
);
for
(
i
=
0
;
i
<
last_word
-
first_word
+
1
;
i
++
)
eeprom_buff
[
i
]
=
cpu_to_le16
(
eeprom_buff
[
i
]);
...
...
@@ -454,15 +553,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if
((
ret_val
==
0
)
&&
first_word
<=
EEPROM_CHECKSUM_REG
)
e1000_update_eeprom_checksum
(
hw
);
seeprom_error:
kfree
(
eeprom_buff
);
return
ret_val
;
}
static
int
e1000_ethtool_gring
(
struct
e1000_adapter
*
adapter
,
static
void
e1000_get_drvinfo
(
struct
net_device
*
netdev
,
struct
ethtool_drvinfo
*
drvinfo
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
strncpy
(
drvinfo
->
driver
,
e1000_driver_name
,
32
);
strncpy
(
drvinfo
->
version
,
e1000_driver_version
,
32
);
strncpy
(
drvinfo
->
fw_version
,
"N/A"
,
32
);
strncpy
(
drvinfo
->
bus_info
,
pci_name
(
adapter
->
pdev
),
32
);
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
drvinfo
->
testinfo_len
=
E1000_TEST_LEN
;
drvinfo
->
regdump_len
=
e1000_get_regs_len
(
netdev
);
drvinfo
->
eedump_len
=
e1000_get_eeprom_len
(
netdev
);
}
static
void
e1000_get_ringparam
(
struct
net_device
*
netdev
,
struct
ethtool_ringparam
*
ring
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
e1000_mac_type
mac_type
=
adapter
->
hw
.
mac_type
;
struct
e1000_desc_ring
*
txdr
=
&
adapter
->
tx_ring
;
struct
e1000_desc_ring
*
rxdr
=
&
adapter
->
rx_ring
;
...
...
@@ -477,14 +592,14 @@ e1000_ethtool_gring(struct e1000_adapter *adapter,
ring
->
tx_pending
=
txdr
->
count
;
ring
->
rx_mini_pending
=
0
;
ring
->
rx_jumbo_pending
=
0
;
return
0
;
}
static
int
e1000_
ethtool_sring
(
struct
e1000_adapter
*
adapter
,
e1000_
set_ringparam
(
struct
net_device
*
netdev
,
struct
ethtool_ringparam
*
ring
)
{
int
err
;
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
e1000_mac_type
mac_type
=
adapter
->
hw
.
mac_type
;
struct
e1000_desc_ring
*
txdr
=
&
adapter
->
tx_ring
;
struct
e1000_desc_ring
*
rxdr
=
&
adapter
->
rx_ring
;
...
...
@@ -538,6 +653,7 @@ e1000_ethtool_sring(struct e1000_adapter *adapter,
return
err
;
}
#define REG_PATTERN_TEST(R, M, W) \
{ \
uint32_t pat, value; \
...
...
@@ -628,6 +744,7 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
for
(
i
=
0
;
i
<
E1000_MC_TBL_SIZE
;
i
++
)
REG_PATTERN_TEST
(
MTA
+
(
i
<<
2
),
0xFFFFFFFF
,
0xFFFFFFFF
);
*
data
=
0
;
return
0
;
}
...
...
@@ -939,8 +1056,6 @@ e1000_phy_disable_receiver(struct e1000_adapter *adapter)
e1000_write_phy_reg
(
&
adapter
->
hw
,
30
,
0x8FFC
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
29
,
0x001A
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
30
,
0x8FF0
);
return
;
}
static
void
...
...
@@ -1219,16 +1334,16 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
for
(
i
=
0
;
i
<
64
;
i
++
)
{
e1000_create_lbtest_frame
(
txdr
->
buffer_info
[
i
].
skb
,
1024
);
pci_dma_sync_single
_for_device
(
pdev
,
txdr
->
buffer_info
[
i
].
dma
,
txdr
->
buffer_info
[
i
].
length
,
PCI_DMA_TODEVICE
);
pci_dma_sync_single
(
pdev
,
txdr
->
buffer_info
[
i
].
dma
,
txdr
->
buffer_info
[
i
].
length
,
PCI_DMA_TODEVICE
);
}
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDT
,
i
);
msec_delay
(
200
);
pci_dma_sync_single
_for_cpu
(
pdev
,
rxdr
->
buffer_info
[
0
].
dma
,
rxdr
->
buffer_info
[
0
].
length
,
PCI_DMA_FROMDEVICE
);
pci_dma_sync_single
(
pdev
,
rxdr
->
buffer_info
[
0
].
dma
,
rxdr
->
buffer_info
[
0
].
length
,
PCI_DMA_FROMDEVICE
);
return
e1000_check_lbtest_frame
(
rxdr
->
buffer_info
[
0
].
skb
,
1024
);
}
...
...
@@ -1257,15 +1372,27 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
return
*
data
;
}
static
int
e1000_ethtool_test
(
struct
e1000_adapter
*
adapter
,
static
int
e1000_diag_test_count
(
struct
net_device
*
netdev
)
{
return
E1000_TEST_LEN
;
}
static
void
e1000_diag_test
(
struct
net_device
*
netdev
,
struct
ethtool_test
*
eth_test
,
uint64_t
*
data
)
{
boolean_t
if_running
=
netif_running
(
adapter
->
netdev
);
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
boolean_t
if_running
=
netif_running
(
netdev
);
if
(
eth_test
->
flags
==
ETH_TEST_FL_OFFLINE
)
{
/* Offline tests */
/* save speed, duplex, autoneg settings */
uint16_t
autoneg_advertised
=
adapter
->
hw
.
autoneg_advertised
;
uint8_t
forced_speed_duplex
=
adapter
->
hw
.
forced_speed_duplex
;
uint8_t
autoneg
=
adapter
->
hw
.
autoneg
;
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result */
if
(
e1000_link_test
(
adapter
,
&
data
[
4
]))
...
...
@@ -1291,6 +1418,10 @@ e1000_ethtool_test(struct e1000_adapter *adapter,
if
(
e1000_loopback_test
(
adapter
,
&
data
[
3
]))
eth_test
->
flags
|=
ETH_TEST_FL_FAILED
;
/* restore Autoneg/speed/duplex settings */
adapter
->
hw
.
autoneg_advertised
=
autoneg_advertised
;
adapter
->
hw
.
forced_speed_duplex
=
forced_speed_duplex
;
adapter
->
hw
.
autoneg
=
autoneg
;
e1000_reset
(
adapter
);
if
(
if_running
)
e1000_up
(
adapter
);
...
...
@@ -1305,12 +1436,12 @@ e1000_ethtool_test(struct e1000_adapter *adapter,
data
[
2
]
=
0
;
data
[
3
]
=
0
;
}
return
0
;
}
static
void
e1000_
ethtool_gwol
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_wolinfo
*
wol
)
e1000_
get_wol
(
struct
net_device
*
netdev
,
struct
ethtool_wolinfo
*
wol
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
switch
(
adapter
->
hw
.
device_id
)
{
...
...
@@ -1350,8 +1481,9 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
}
static
int
e1000_
ethtool_swol
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_wolinfo
*
wol
)
e1000_
set_wol
(
struct
net_device
*
netdev
,
struct
ethtool_wolinfo
*
wol
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
switch
(
adapter
->
hw
.
device_id
)
{
...
...
@@ -1387,7 +1519,6 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
return
0
;
}
/* toggle LED 4 times per second = 2 "blinks" per second */
#define E1000_ID_INTERVAL (HZ/4)
...
...
@@ -1408,8 +1539,13 @@ e1000_led_blink_callback(unsigned long data)
}
static
int
e1000_
ethtool_led_blink
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_value
*
id
)
e1000_
phys_id
(
struct
net_device
*
netdev
,
uint32_t
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
if
(
!
data
||
data
>
(
uint32_t
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
))
data
=
(
uint32_t
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
);
if
(
!
adapter
->
blink_timer
.
function
)
{
init_timer
(
&
adapter
->
blink_timer
);
adapter
->
blink_timer
.
function
=
e1000_led_blink_callback
;
...
...
@@ -1420,11 +1556,8 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
mod_timer
(
&
adapter
->
blink_timer
,
jiffies
);
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
id
->
data
)
schedule_timeout
(
id
->
data
*
HZ
);
else
schedule_timeout
(
MAX_SCHEDULE_TIMEOUT
);
schedule_timeout
(
data
*
HZ
);
del_timer_sync
(
&
adapter
->
blink_timer
);
e1000_led_off
(
&
adapter
->
hw
);
clear_bit
(
E1000_LED_ON
,
&
adapter
->
led_status
);
...
...
@@ -1433,345 +1566,102 @@ e1000_ethtool_led_blink(struct e1000_adapter *adapter, struct ethtool_value *id)
return
0
;
}
int
e1000_
ethtool_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
)
static
int
e1000_
nway_reset
(
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
void
*
addr
=
ifr
->
ifr_data
;
uint32_t
cmd
;
if
(
get_user
(
cmd
,
(
uint32_t
*
)
addr
))
return
-
EFAULT
;
switch
(
cmd
)
{
case
ETHTOOL_GSET
:
{
struct
ethtool_cmd
ecmd
=
{
ETHTOOL_GSET
};
e1000_ethtool_gset
(
adapter
,
&
ecmd
);
if
(
copy_to_user
(
addr
,
&
ecmd
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SSET
:
{
struct
ethtool_cmd
ecmd
;
if
(
copy_from_user
(
&
ecmd
,
addr
,
sizeof
(
ecmd
)))
return
-
EFAULT
;
return
e1000_ethtool_sset
(
adapter
,
&
ecmd
);
}
case
ETHTOOL_GDRVINFO
:
{
struct
ethtool_drvinfo
drvinfo
=
{
ETHTOOL_GDRVINFO
};
e1000_ethtool_gdrvinfo
(
adapter
,
&
drvinfo
);
if
(
copy_to_user
(
addr
,
&
drvinfo
,
sizeof
(
drvinfo
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GSTRINGS
:
{
struct
ethtool_gstrings
gstrings
=
{
ETHTOOL_GSTRINGS
};
char
*
strings
=
NULL
;
int
err
=
0
;
if
(
copy_from_user
(
&
gstrings
,
addr
,
sizeof
(
gstrings
)))
return
-
EFAULT
;
switch
(
gstrings
.
string_set
)
{
case
ETH_SS_TEST
:
gstrings
.
len
=
E1000_TEST_LEN
;
strings
=
kmalloc
(
E1000_TEST_LEN
*
ETH_GSTRING_LEN
,
GFP_KERNEL
);
if
(
!
strings
)
return
-
ENOMEM
;
memcpy
(
strings
,
e1000_gstrings_test
,
E1000_TEST_LEN
*
ETH_GSTRING_LEN
);
break
;
case
ETH_SS_STATS
:
{
int
i
;
gstrings
.
len
=
E1000_STATS_LEN
;
strings
=
kmalloc
(
E1000_STATS_LEN
*
ETH_GSTRING_LEN
,
GFP_KERNEL
);
if
(
!
strings
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
{
memcpy
(
&
strings
[
i
*
ETH_GSTRING_LEN
],
e1000_gstrings_stats
[
i
].
stat_string
,
ETH_GSTRING_LEN
);
}
break
;
}
default:
return
-
EOPNOTSUPP
;
}
if
(
copy_to_user
(
addr
,
&
gstrings
,
sizeof
(
gstrings
)))
err
=
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_gstrings
,
data
);
if
(
!
err
&&
copy_to_user
(
addr
,
strings
,
gstrings
.
len
*
ETH_GSTRING_LEN
))
err
=
-
EFAULT
;
kfree
(
strings
);
return
err
;
}
case
ETHTOOL_GREGS
:
{
struct
ethtool_regs
regs
=
{
ETHTOOL_GREGS
};
uint32_t
regs_buff
[
E1000_REGS_LEN
];
if
(
copy_from_user
(
&
regs
,
addr
,
sizeof
(
regs
)))
return
-
EFAULT
;
memset
(
regs_buff
,
0
,
sizeof
(
regs_buff
));
if
(
regs
.
len
>
E1000_REGS_LEN
)
regs
.
len
=
E1000_REGS_LEN
;
e1000_ethtool_gregs
(
adapter
,
&
regs
,
regs_buff
);
if
(
copy_to_user
(
addr
,
&
regs
,
sizeof
(
regs
)))
return
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_regs
,
data
);
if
(
copy_to_user
(
addr
,
regs_buff
,
regs
.
len
))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_NWAY_RST
:
{
if
(
netif_running
(
netdev
))
{
e1000_down
(
adapter
);
e1000_up
(
adapter
);
}
return
0
;
}
case
ETHTOOL_PHYS_ID
:
{
struct
ethtool_value
id
;
if
(
copy_from_user
(
&
id
,
addr
,
sizeof
(
id
)))
return
-
EFAULT
;
return
e1000_ethtool_led_blink
(
adapter
,
&
id
);
}
case
ETHTOOL_GLINK
:
{
struct
ethtool_value
link
=
{
ETHTOOL_GLINK
};
link
.
data
=
netif_carrier_ok
(
netdev
);
if
(
copy_to_user
(
addr
,
&
link
,
sizeof
(
link
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GWOL
:
{
struct
ethtool_wolinfo
wol
=
{
ETHTOOL_GWOL
};
e1000_ethtool_gwol
(
adapter
,
&
wol
);
if
(
copy_to_user
(
addr
,
&
wol
,
sizeof
(
wol
))
!=
0
)
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SWOL
:
{
struct
ethtool_wolinfo
wol
;
if
(
copy_from_user
(
&
wol
,
addr
,
sizeof
(
wol
))
!=
0
)
return
-
EFAULT
;
return
e1000_ethtool_swol
(
adapter
,
&
wol
);
}
case
ETHTOOL_GEEPROM
:
{
struct
ethtool_eeprom
eeprom
=
{
ETHTOOL_GEEPROM
};
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
*
eeprom_buff
;
void
*
ptr
;
int
err
=
0
;
if
(
copy_from_user
(
&
eeprom
,
addr
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
eeprom_buff
=
kmalloc
(
hw
->
eeprom
.
word_size
*
2
,
GFP_KERNEL
);
if
(
!
eeprom_buff
)
return
-
ENOMEM
;
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
))
err
=
-
EFAULT
;
err_geeprom_ioctl:
kfree
(
eeprom_buff
);
return
err
;
}
case
ETHTOOL_SEEPROM
:
{
struct
ethtool_eeprom
eeprom
;
if
(
copy_from_user
(
&
eeprom
,
addr
,
sizeof
(
eeprom
)))
return
-
EFAULT
;
addr
+=
offsetof
(
struct
ethtool_eeprom
,
data
);
return
e1000_ethtool_seeprom
(
adapter
,
&
eeprom
,
addr
);
}
case
ETHTOOL_GRINGPARAM
:
{
struct
ethtool_ringparam
ering
=
{
ETHTOOL_GRINGPARAM
};
e1000_ethtool_gring
(
adapter
,
&
ering
);
if
(
copy_to_user
(
addr
,
&
ering
,
sizeof
(
ering
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SRINGPARAM
:
{
struct
ethtool_ringparam
ering
;
if
(
copy_from_user
(
&
ering
,
addr
,
sizeof
(
ering
)))
return
-
EFAULT
;
return
e1000_ethtool_sring
(
adapter
,
&
ering
);
}
case
ETHTOOL_GPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
=
{
ETHTOOL_GPAUSEPARAM
};
e1000_ethtool_gpause
(
adapter
,
&
epause
);
if
(
copy_to_user
(
addr
,
&
epause
,
sizeof
(
epause
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SPAUSEPARAM
:
{
struct
ethtool_pauseparam
epause
;
if
(
copy_from_user
(
&
epause
,
addr
,
sizeof
(
epause
)))
return
-
EFAULT
;
return
e1000_ethtool_spause
(
adapter
,
&
epause
);
}
case
ETHTOOL_GSTATS
:
{
struct
{
struct
ethtool_stats
eth_stats
;
uint64_t
data
[
E1000_STATS_LEN
];
}
stats
=
{
{
ETHTOOL_GSTATS
,
E1000_STATS_LEN
}
};
int
i
;
e1000_update_stats
(
adapter
);
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
stats
.
data
[
i
]
=
(
e1000_gstrings_stats
[
i
].
sizeof_stat
==
sizeof
(
uint64_t
))
?
*
(
uint64_t
*
)((
char
*
)
adapter
+
e1000_gstrings_stats
[
i
].
stat_offset
)
:
*
(
uint32_t
*
)((
char
*
)
adapter
+
e1000_gstrings_stats
[
i
].
stat_offset
);
if
(
copy_to_user
(
addr
,
&
stats
,
sizeof
(
stats
)))
return
-
EFAULT
;
return
0
;
if
(
netif_running
(
netdev
))
{
e1000_down
(
adapter
);
e1000_up
(
adapter
);
}
case
ETHTOOL_TEST
:
{
struct
{
struct
ethtool_test
eth_test
;
uint64_t
data
[
E1000_TEST_LEN
];
}
test
=
{
{
ETHTOOL_TEST
}
};
int
err
;
if
(
copy_from_user
(
&
test
.
eth_test
,
addr
,
sizeof
(
test
.
eth_test
)))
return
-
EFAULT
;
test
.
eth_test
.
len
=
E1000_TEST_LEN
;
if
((
err
=
e1000_ethtool_test
(
adapter
,
&
test
.
eth_test
,
test
.
data
)))
return
err
;
return
0
;
}
if
(
copy_to_user
(
addr
,
&
test
,
sizeof
(
test
))
!=
0
)
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_GRXCSUM
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GRXCSUM
};
static
uint32_t
e1000_get_link
(
struct
net_device
*
netdev
)
{
return
netif_carrier_ok
(
netdev
);
}
edata
.
data
=
adapter
->
rx_csum
;
if
(
copy_to_user
(
addr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_SRXCSUM
:
{
struct
ethtool_value
edata
;
static
int
e1000_get_stats_count
(
struct
net_device
*
netdev
)
{
return
E1000_STATS_LEN
;
}
if
(
copy_from_user
(
&
edata
,
addr
,
sizeof
(
edata
)))
return
-
EFAULT
;
adapter
->
rx_csum
=
edata
.
data
;
if
(
netif_running
(
netdev
))
{
e1000_down
(
adapter
);
e1000_up
(
adapter
);
}
else
e1000_reset
(
adapter
);
return
0
;
}
case
ETHTOOL_GTXCSUM
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GTXCSUM
};
static
void
e1000_get_ethtool_stats
(
struct
net_device
*
netdev
,
struct
ethtool_stats
*
stats
,
uint64_t
*
data
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
int
i
;
edata
.
data
=
(
netdev
->
features
&
NETIF_F_HW_CSUM
)
!=
0
;
if
(
copy_to_user
(
addr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
e1000_update_stats
(
adapter
);
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
{
char
*
p
=
(
char
*
)
adapter
+
e1000_gstrings_stats
[
i
].
stat_offset
;
data
[
i
]
=
(
e1000_gstrings_stats
[
i
].
sizeof_stat
==
sizeof
(
uint64_t
))
?
*
(
uint64_t
*
)
p
:
*
(
uint32_t
*
)
p
;
}
case
ETHTOOL_STXCSUM
:
{
struct
ethtool_value
edata
;
}
if
(
copy_from_user
(
&
edata
,
addr
,
sizeof
(
edata
)))
return
-
EFAULT
;
static
void
e1000_get_strings
(
struct
net_device
*
netdev
,
uint32_t
stringset
,
uint8_t
*
data
)
{
int
i
;
if
(
adapter
->
hw
.
mac_type
<
e1000_82543
)
{
if
(
edata
.
data
!=
0
)
return
-
EINVAL
;
return
0
;
switch
(
stringset
)
{
case
ETH_SS_TEST
:
memcpy
(
data
,
*
e1000_gstrings_test
,
E1000_TEST_LEN
*
ETH_GSTRING_LEN
);
break
;
case
ETH_SS_STATS
:
for
(
i
=
0
;
i
<
E1000_STATS_LEN
;
i
++
)
{
memcpy
(
data
+
i
*
ETH_GSTRING_LEN
,
e1000_gstrings_stats
[
i
].
stat_string
,
ETH_GSTRING_LEN
);
}
if
(
edata
.
data
)
netdev
->
features
|=
NETIF_F_HW_CSUM
;
else
netdev
->
features
&=
~
NETIF_F_HW_CSUM
;
return
0
;
}
case
ETHTOOL_GSG
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GSG
};
edata
.
data
=
(
netdev
->
features
&
NETIF_F_SG
)
!=
0
;
if
(
copy_to_user
(
addr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
break
;
}
case
ETHTOOL_SSG
:
{
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
addr
,
sizeof
(
edata
)))
return
-
EFAULT
;
if
(
edata
.
data
)
netdev
->
features
|=
NETIF_F_SG
;
else
netdev
->
features
&=
~
NETIF_F_SG
;
}
return
0
;
}
struct
ethtool_ops
e1000_ethtool_ops
=
{
.
get_settings
=
e1000_get_settings
,
.
set_settings
=
e1000_set_settings
,
.
get_drvinfo
=
e1000_get_drvinfo
,
.
get_regs_len
=
e1000_get_regs_len
,
.
get_regs
=
e1000_get_regs
,
.
get_wol
=
e1000_get_wol
,
.
set_wol
=
e1000_set_wol
,
.
get_msglevel
=
e1000_get_msglevel
,
.
set_msglevel
=
e1000_set_msglevel
,
.
nway_reset
=
e1000_nway_reset
,
.
get_link
=
e1000_get_link
,
.
get_eeprom_len
=
e1000_get_eeprom_len
,
.
get_eeprom
=
e1000_get_eeprom
,
.
set_eeprom
=
e1000_set_eeprom
,
.
get_ringparam
=
e1000_get_ringparam
,
.
set_ringparam
=
e1000_set_ringparam
,
.
get_pauseparam
=
e1000_get_pauseparam
,
.
set_pauseparam
=
e1000_set_pauseparam
,
.
get_rx_csum
=
e1000_get_rx_csum
,
.
set_rx_csum
=
e1000_set_rx_csum
,
.
get_tx_csum
=
e1000_get_tx_csum
,
.
set_tx_csum
=
e1000_set_tx_csum
,
.
get_sg
=
e1000_get_sg
,
.
set_sg
=
e1000_set_sg
,
#ifdef NETIF_F_TSO
case
ETHTOOL_GTSO
:
{
struct
ethtool_value
edata
=
{
ETHTOOL_GTSO
};
edata
.
data
=
(
netdev
->
features
&
NETIF_F_TSO
)
!=
0
;
if
(
copy_to_user
(
addr
,
&
edata
,
sizeof
(
edata
)))
return
-
EFAULT
;
return
0
;
}
case
ETHTOOL_STSO
:
{
struct
ethtool_value
edata
;
if
(
copy_from_user
(
&
edata
,
addr
,
sizeof
(
edata
)))
return
-
EFAULT
;
if
((
adapter
->
hw
.
mac_type
<
e1000_82544
)
||
(
adapter
->
hw
.
mac_type
==
e1000_82547
))
{
if
(
edata
.
data
!=
0
)
return
-
EINVAL
;
return
0
;
}
if
(
edata
.
data
)
netdev
->
features
|=
NETIF_F_TSO
;
else
netdev
->
features
&=
~
NETIF_F_TSO
;
return
0
;
}
.
get_tso
=
e1000_get_tso
,
.
set_tso
=
e1000_set_tso
,
#endif
default:
return
-
EOPNOTSUPP
;
}
}
.
self_test_count
=
e1000_diag_test_count
,
.
self_test
=
e1000_diag_test
,
.
get_strings
=
e1000_get_strings
,
.
phys_id
=
e1000_phys_id
,
.
get_stats_count
=
e1000_get_stats_count
,
.
get_ethtool_stats
=
e1000_get_ethtool_stats
,
};
void
set_ethtool_ops
(
struct
net_device
*
netdev
)
{
SET_ETHTOOL_OPS
(
netdev
,
&
e1000_ethtool_ops
);
}
drivers/net/e1000/e1000_hw.c
View file @
7991c128
...
...
@@ -470,7 +470,6 @@ e1000_init_hw(struct e1000_hw *hw)
uint16_t
pcix_stat_hi_word
;
uint16_t
cmd_mmrbc
;
uint16_t
stat_mmrbc
;
DEBUGFUNC
(
"e1000_init_hw"
);
/* Initialize Identification LED */
...
...
@@ -910,6 +909,12 @@ e1000_setup_copper_link(struct e1000_hw *hw)
if
(
ret_val
)
return
ret_val
;
if
(
hw
->
mac_type
==
e1000_82545_rev_3
)
{
ret_val
=
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
);
phy_data
|=
0x00000008
;
ret_val
=
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
);
}
if
(
hw
->
mac_type
<=
e1000_82543
||
hw
->
mac_type
==
e1000_82541
||
hw
->
mac_type
==
e1000_82547
||
hw
->
mac_type
==
e1000_82541_rev_2
||
hw
->
mac_type
==
e1000_82547_rev_2
)
...
...
@@ -1961,7 +1966,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
int32_t
e1000_check_for_link
(
struct
e1000_hw
*
hw
)
{
uint32_t
rxcw
;
uint32_t
rxcw
=
0
;
uint32_t
ctrl
;
uint32_t
status
;
uint32_t
rctl
;
...
...
@@ -1971,16 +1976,23 @@ e1000_check_for_link(struct e1000_hw *hw)
DEBUGFUNC
(
"e1000_check_for_link"
);
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
status
=
E1000_READ_REG
(
hw
,
STATUS
);
/* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
* cleared when there is a signal. This applies to fiber media only.
*/
if
(
hw
->
media_type
==
e1000_media_type_fiber
)
signal
=
(
hw
->
mac_type
>
e1000_82544
)
?
E1000_CTRL_SWDPIN1
:
0
;
if
((
hw
->
media_type
==
e1000_media_type_fiber
)
||
(
hw
->
media_type
==
e1000_media_type_internal_serdes
))
{
rxcw
=
E1000_READ_REG
(
hw
,
RXCW
);
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
status
=
E1000_READ_REG
(
hw
,
STATUS
);
rxcw
=
E1000_READ_REG
(
hw
,
RXCW
);
if
(
hw
->
media_type
==
e1000_media_type_fiber
)
{
signal
=
(
hw
->
mac_type
>
e1000_82544
)
?
E1000_CTRL_SWDPIN1
:
0
;
if
(
status
&
E1000_STATUS_LU
)
hw
->
get_link_status
=
FALSE
;
}
}
/* If we have a copper PHY then we only want to go out to the PHY
* registers to see if Auto-Neg has completed and/or if our link
...
...
@@ -2093,8 +2105,8 @@ e1000_check_for_link(struct e1000_hw *hw)
* in. The autoneg_failed flag does this.
*/
else
if
((((
hw
->
media_type
==
e1000_media_type_fiber
)
&&
((
ctrl
&
E1000_CTRL_SWDPIN1
)
==
signal
))
||
(
hw
->
media_type
==
e1000_media_type_internal_serdes
))
&&
((
ctrl
&
E1000_CTRL_SWDPIN1
)
==
signal
))
||
(
hw
->
media_type
==
e1000_media_type_internal_serdes
))
&&
(
!
(
status
&
E1000_STATUS_LU
))
&&
(
!
(
rxcw
&
E1000_RXCW_C
)))
{
if
(
hw
->
autoneg_failed
==
0
)
{
...
...
@@ -2125,8 +2137,7 @@ e1000_check_for_link(struct e1000_hw *hw)
*/
else
if
(((
hw
->
media_type
==
e1000_media_type_fiber
)
||
(
hw
->
media_type
==
e1000_media_type_internal_serdes
))
&&
(
ctrl
&
E1000_CTRL_SLU
)
&&
(
rxcw
&
E1000_RXCW_C
))
{
(
ctrl
&
E1000_CTRL_SLU
)
&&
(
rxcw
&
E1000_RXCW_C
))
{
DEBUGOUT
(
"RXing /C/, enable AutoNeg and stop forcing link.
\r\n
"
);
E1000_WRITE_REG
(
hw
,
TXCW
,
hw
->
txcw
);
E1000_WRITE_REG
(
hw
,
CTRL
,
(
ctrl
&
~
E1000_CTRL_SLU
));
...
...
drivers/net/e1000/e1000_hw.h
View file @
7991c128
...
...
@@ -2019,7 +2019,7 @@ struct e1000_hw {
#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B
/* shift right 11 */
/* IGP01E1000 Specific Port Control Register - R/W */
#define IGP01E1000_PSCR_TP_LOOPBACK 0x00
01
#define IGP01E1000_PSCR_TP_LOOPBACK 0x00
10
#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
...
...
@@ -2029,16 +2029,18 @@ struct e1000_hw {
/* IGP01E1000 Specific Port Link Health Register */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
#define IGP01E1000_PLHR_MASTER_FAULT 0x2000
#define IGP01E1000_PLHR_MASTER_RESOLUTION 0x1000
#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800
/* LH */
#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400
/* LH */
#define IGP01E1000_PLHR_DATA_ERR_1 0x0200
/* LH */
#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
#define IGP01E1000_PLHR_AUTONEG_FAULT 0x00
1
0
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x00
08
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x000
4
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x000
2
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x000
1
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x000
0
#define IGP01E1000_PLHR_AUTONEG_FAULT 0x00
4
0
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x00
10
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x000
8
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x000
4
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x000
2
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x000
1
/* IGP01E1000 Channel Quality Register */
#define IGP01E1000_MSE_CHANNEL_D 0x000F
...
...
drivers/net/e1000/e1000_main.c
View file @
7991c128
...
...
@@ -27,55 +27,32 @@
*******************************************************************************/
#include "e1000.h"
#include <linux/rtnetlink.h>
/* Change Log
*
* 5.2.51 5/14/04
* o set default configuration to 'NAPI disabled'. NAPI enabled driver
* causes kernel panic when the interface is shutdown while data is being
* transferred.
* 5.2.47 5/04/04
* o fixed ethtool -t implementation
* 5.2.45 4/29/04
* o fixed ethtool -e implementation
* o Support for ethtool ops [Stephen Hemminger (shemminger@osdl.org)]
* 5.2.42 4/26/04
* o Added support for the DPRINTK macro for enhanced error logging. Some
* parts of the patch were supplied by Jon Mason.
* o Move the register_netdevice() donw in the probe routine due to a
* loading/unloading test issue.
* o Added a long RX byte count the the extra ethtool data members for BER
* testing purposes.
* 5.2.39 3/12/04
* o Added support to read/write eeprom data in proper order.
* By default device eeprom is always little-endian, word
* addressable
* o Disable TSO as the default for the driver until hangs
* reported against non-IA acrhs can be root-caused.
* o Back out the CSA fix for 82547 as it continues to cause
* systems lock-ups with production systems.
* o Fixed FC high/low water mark values to actually be in the
* range of the Rx FIFO area. It was a math error.
* [Dainis Jonitis (dainis_jonitis@exigengroup.lv)]
* o Handle failure to get new resources when doing ethtool
* ring paramater changes. Previously, driver would free old,
* but fails to allocate new, causing problems. Now, driver
* allocates new, and if sucessful, frees old.
* o Changed collision threshold from 16 to 15 to comply with IEEE
* spec.
* o Toggle chip-select when checking ready status on SPI eeproms.
* o Put PHY into class A mode to pass IEEE tests on some designs.
* Designs with EEPROM word 0x7, bit 15 set will have their PHYs
* set to class A mode, rather than the default class AB.
* o Handle failures of register_netdev. Stephen Hemminger
* [shemminger@osdl.org].
* o updated README & MAN pages, number of Transmit/Receive
* descriptors may be denied depending on system resources.
*
* 5.2.30 1/14/03
* o Set VLAN filtering to IEEE 802.1Q after reset so we don't break
* SoL connections that use VLANs.
* o Allow 1000/Full setting for AutoNeg param for Fiber connections
* Jon D Mason [jonmason@us.ibm.com].
* o Race between Tx queue and Tx clean fixed with a spin lock.
* o Added netpoll support.
* o Fixed endianess bug causing ethtool loopback diags to fail on ppc.
* o Use pdev->irq rather than netdev->irq in preparation for MSI support.
* o Report driver message on user override of InterruptThrottleRate
* module parameter.
* o Change I/O address storage from uint32_t to unsigned long.
* o Added ethtool RINGPARAM support.
*
* 5.2.22 10/15/03
*/
char
e1000_driver_name
[]
=
"e1000"
;
char
e1000_driver_string
[]
=
"Intel(R) PRO/1000 Network Driver"
;
char
e1000_driver_version
[]
=
"5.2.
39
-k2"
;
char
e1000_driver_version
[]
=
"5.2.
52
-k2"
;
char
e1000_copyright
[]
=
"Copyright (c) 1999-2004 Intel Corporation."
;
/* e1000_pci_tbl - PCI Device ID Table
...
...
@@ -170,6 +147,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
static
int
e1000_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
,
int
cmd
);
static
int
e1000_mii_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
,
int
cmd
);
void
set_ethtool_ops
(
struct
net_device
*
netdev
);
static
void
e1000_enter_82542_rst
(
struct
e1000_adapter
*
adapter
);
static
void
e1000_leave_82542_rst
(
struct
e1000_adapter
*
adapter
);
static
inline
void
e1000_rx_checksum
(
struct
e1000_adapter
*
adapter
,
...
...
@@ -206,7 +184,7 @@ struct notifier_block e1000_notifier_reboot = {
/* Exported from other modules */
extern
void
e1000_check_options
(
struct
e1000_adapter
*
adapter
);
extern
int
e1000_ethtool_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
);
static
struct
pci_driver
e1000_driver
=
{
.
name
=
e1000_driver_name
,
...
...
@@ -224,6 +202,10 @@ MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION
(
"Intel(R) PRO/1000 Network Driver"
);
MODULE_LICENSE
(
"GPL"
);
static
int
debug
=
3
;
module_param
(
debug
,
int
,
0
);
MODULE_PARM_DESC
(
debug
,
"Debug level (0=none,...,16=all)"
);
/**
* e1000_init_module - Driver Registration Routine
*
...
...
@@ -419,6 +401,12 @@ e1000_probe(struct pci_dev *pdev,
adapter
->
netdev
=
netdev
;
adapter
->
pdev
=
pdev
;
adapter
->
hw
.
back
=
adapter
;
adapter
->
msg_enable
=
(
1
<<
debug
)
-
1
;
rtnl_lock
();
/* we need to set the name early since the DPRINTK macro needs it set */
if
(
dev_alloc_name
(
netdev
,
netdev
->
name
)
<
0
)
goto
err_free_unlock
;
mmio_start
=
pci_resource_start
(
pdev
,
BAR_0
);
mmio_len
=
pci_resource_len
(
pdev
,
BAR_0
);
...
...
@@ -446,6 +434,7 @@ e1000_probe(struct pci_dev *pdev,
netdev
->
set_mac_address
=
&
e1000_set_mac
;
netdev
->
change_mtu
=
&
e1000_change_mtu
;
netdev
->
do_ioctl
=
&
e1000_ioctl
;
set_ethtool_ops
(
netdev
);
netdev
->
tx_timeout
=
&
e1000_tx_timeout
;
netdev
->
watchdog_timeo
=
5
*
HZ
;
#ifdef CONFIG_E1000_NAPI
...
...
@@ -502,7 +491,7 @@ e1000_probe(struct pci_dev *pdev,
/* make sure the EEPROM is good */
if
(
e1000_validate_eeprom_checksum
(
&
adapter
->
hw
)
<
0
)
{
printk
(
KERN_ERR
"The EEPROM Checksum Is Not Valid
\n
"
);
DPRINTK
(
PROBE
,
ERR
,
"The EEPROM Checksum Is Not Valid
\n
"
);
err
=
-
EIO
;
goto
err_eeprom
;
}
...
...
@@ -536,16 +525,12 @@ e1000_probe(struct pci_dev *pdev,
INIT_WORK
(
&
adapter
->
tx_timeout_task
,
(
void
(
*
)(
void
*
))
e1000_tx_timeout_task
,
netdev
);
if
((
err
=
register_netdev
(
netdev
)))
goto
err_register
;
/* we're going to reset, so assume we have no link for now */
netif_carrier_off
(
netdev
);
netif_stop_queue
(
netdev
);
printk
(
KERN_INFO
"%s: Intel(R) PRO/1000 Network Connection
\n
"
,
netdev
->
name
);
DPRINTK
(
PROBE
,
INFO
,
"Intel(R) PRO/1000 Network Connection
\n
"
);
e1000_check_options
(
adapter
);
/* Initial Wake on LAN setting
...
...
@@ -579,7 +564,12 @@ e1000_probe(struct pci_dev *pdev,
e1000_reset
(
adapter
);
/* since we are holding the rtnl lock already, call the no-lock version */
if
((
err
=
register_netdevice
(
netdev
)))
goto
err_register
;
cards_found
++
;
rtnl_unlock
();
return
0
;
err_register:
...
...
@@ -587,6 +577,8 @@ e1000_probe(struct pci_dev *pdev,
err_eeprom:
iounmap
(
adapter
->
hw
.
hw_addr
);
err_ioremap:
err_free_unlock:
rtnl_unlock
();
free_netdev
(
netdev
);
err_alloc_etherdev:
pci_release_regions
(
pdev
);
...
...
@@ -664,7 +656,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
/* identify the MAC */
if
(
e1000_set_mac_type
(
hw
))
{
E1000_ERR
(
"Unknown MAC Type
\n
"
);
DPRINTK
(
PROBE
,
ERR
,
"Unknown MAC Type
\n
"
);
return
-
EIO
;
}
...
...
@@ -1391,9 +1383,8 @@ e1000_watchdog(unsigned long data)
&
adapter
->
link_speed
,
&
adapter
->
link_duplex
);
printk
(
KERN_INFO
"e1000: %s NIC Link is Up %d Mbps %s
\n
"
,
netdev
->
name
,
adapter
->
link_speed
,
DPRINTK
(
LINK
,
INFO
,
"NIC Link is Up %d Mbps %s
\n
"
,
adapter
->
link_speed
,
adapter
->
link_duplex
==
FULL_DUPLEX
?
"Full Duplex"
:
"Half Duplex"
);
...
...
@@ -1406,9 +1397,7 @@ e1000_watchdog(unsigned long data)
if
(
netif_carrier_ok
(
netdev
))
{
adapter
->
link_speed
=
0
;
adapter
->
link_duplex
=
0
;
printk
(
KERN_INFO
"e1000: %s NIC Link is Down
\n
"
,
netdev
->
name
);
DPRINTK
(
LINK
,
INFO
,
"NIC Link is Down
\n
"
);
netif_carrier_off
(
netdev
);
netif_stop_queue
(
netdev
);
mod_timer
(
&
adapter
->
phy_info_timer
,
jiffies
+
2
*
HZ
);
...
...
@@ -1560,33 +1549,17 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
static
inline
int
e1000_tx_map
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
,
unsigned
int
first
)
unsigned
int
first
,
unsigned
int
max_per_txd
,
unsigned
int
nr_frags
,
unsigned
int
mss
)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
struct
e1000_tx_desc
*
tx_desc
;
struct
e1000_buffer
*
buffer_info
;
unsigned
int
len
=
skb
->
len
,
max_per_txd
=
E1000_MAX_DATA_PER_TXD
;
unsigned
int
len
=
skb
->
len
;
unsigned
int
offset
=
0
,
size
,
count
=
0
,
i
;
#ifdef NETIF_F_TSO
unsigned
int
mss
;
#endif
unsigned
int
nr_frags
;
unsigned
int
f
;
#ifdef NETIF_F_TSO
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
/* The controller does a simple calculation to
* make sure there is enough room in the FIFO before
* initiating the DMA for each buffer. The calc is:
* 4 = ceil(buffer len/mss). To make sure we don't
* overrun the FIFO, adjust the max buffer len if mss
* drops. */
if
(
mss
)
max_per_txd
=
min
(
mss
<<
2
,
max_per_txd
);
#endif
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
len
-=
skb
->
data_len
;
i
=
tx_ring
->
next_to_use
;
while
(
len
)
{
...
...
@@ -1658,46 +1631,6 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
}
if
(
E1000_DESC_UNUSED
(
&
adapter
->
tx_ring
)
<
count
+
2
)
{
/* There aren't enough descriptors available to queue up
* this send (need: count + 1 context desc + 1 desc gap
* to keep tail from touching head), so undo the mapping
* and abort the send. We could have done the check before
* we mapped the skb, but because of all the workarounds
* (above), it's too difficult to predict how many we're
* going to need.*/
i
=
tx_ring
->
next_to_use
;
if
(
i
==
first
)
{
/* Cleanup after e1000_tx_[csum|tso] scribbling
* on descriptors. */
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
first
);
tx_desc
->
buffer_addr
=
0
;
tx_desc
->
lower
.
data
=
0
;
tx_desc
->
upper
.
data
=
0
;
}
while
(
count
--
)
{
buffer_info
=
&
tx_ring
->
buffer_info
[
i
];
if
(
buffer_info
->
dma
)
{
pci_unmap_page
(
adapter
->
pdev
,
buffer_info
->
dma
,
buffer_info
->
length
,
PCI_DMA_TODEVICE
);
buffer_info
->
dma
=
0
;
}
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
tx_ring
->
next_to_use
=
first
;
return
0
;
}
i
=
(
i
==
0
)
?
tx_ring
->
count
-
1
:
i
-
1
;
tx_ring
->
buffer_info
[
i
].
skb
=
skb
;
tx_ring
->
buffer_info
[
first
].
next_to_watch
=
i
;
...
...
@@ -1792,27 +1725,72 @@ e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
return
0
;
}
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
static
int
e1000_xmit_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
unsigned
int
first
;
unsigned
int
first
,
max_per_txd
=
E1000_MAX_DATA_PER_TXD
;
unsigned
int
max_txd_pwr
=
E1000_MAX_TXD_PWR
;
unsigned
int
tx_flags
=
0
;
unsigned
long
flags
;
int
count
;
unsigned
int
len
=
skb
->
len
;
int
count
=
0
;
unsigned
int
mss
=
0
;
unsigned
int
nr_frags
=
0
;
unsigned
int
f
;
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
len
-=
skb
->
data_len
;
if
(
skb
->
len
<=
0
)
{
dev_kfree_skb_any
(
skb
);
return
0
;
}
#ifdef NETIF_F_TSO
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
/* The controller does a simple calculation to
* make sure there is enough room in the FIFO before
* initiating the DMA for each buffer. The calc is:
* 4 = ceil(buffer len/mss). To make sure we don't
* overrun the FIFO, adjust the max buffer len if mss
* drops. */
if
(
mss
)
{
max_per_txd
=
min
(
mss
<<
2
,
max_per_txd
);
max_txd_pwr
=
fls
(
max_per_txd
)
-
1
;
}
if
((
mss
)
||
(
skb
->
ip_summed
==
CHECKSUM_HW
))
count
++
;
count
++
;
/*for sentinel desc*/
#else
if
(
skb
->
ip_summed
==
CHECKSUM_HW
)
count
++
;
#endif
count
+=
TXD_USE_COUNT
(
len
,
max_txd_pwr
);
if
(
adapter
->
pcix_82544
)
count
++
;
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
for
(
f
=
0
;
f
<
nr_frags
;
f
++
)
count
+=
TXD_USE_COUNT
(
skb_shinfo
(
skb
)
->
frags
[
f
].
size
,
max_txd_pwr
);
if
(
adapter
->
pcix_82544
)
count
+=
nr_frags
;
spin_lock_irqsave
(
&
adapter
->
tx_lock
,
flags
);
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
if
(
E1000_DESC_UNUSED
(
&
adapter
->
tx_ring
)
<
count
+
2
)
{
netif_stop_queue
(
netdev
);
spin_unlock_irqrestore
(
&
adapter
->
tx_lock
,
flags
);
return
1
;
}
spin_unlock_irqrestore
(
&
adapter
->
tx_lock
,
flags
);
if
(
adapter
->
hw
.
mac_type
==
e1000_82547
)
{
if
(
e1000_82547_fifo_workaround
(
adapter
,
skb
))
{
netif_stop_queue
(
netdev
);
mod_timer
(
&
adapter
->
tx_fifo_stall_timer
,
jiffies
);
spin_unlock_irqrestore
(
&
adapter
->
tx_lock
,
flags
);
return
1
;
}
}
...
...
@@ -1829,18 +1807,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else
if
(
e1000_tx_csum
(
adapter
,
skb
))
tx_flags
|=
E1000_TX_FLAGS_CSUM
;
if
((
count
=
e1000_tx_map
(
adapter
,
skb
,
first
)))
e1000_tx_queue
(
adapter
,
count
,
tx_flags
);
else
{
netif_stop_queue
(
netdev
);
spin_unlock_irqrestore
(
&
adapter
->
tx_lock
,
flags
);
return
1
;
}
e1000_tx_queue
(
adapter
,
e1000_tx_map
(
adapter
,
skb
,
first
,
max_per_txd
,
nr_frags
,
mss
),
tx_flags
);
netdev
->
trans_start
=
jiffies
;
spin_unlock_irqrestore
(
&
adapter
->
tx_lock
,
flags
);
return
0
;
}
...
...
@@ -1903,7 +1875,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
if
((
max_frame
<
MINIMUM_ETHERNET_FRAME_SIZE
)
||
(
max_frame
>
MAX_JUMBO_FRAME_SIZE
))
{
E1000_ERR
(
"Invalid MTU setting
\n
"
);
DPRINTK
(
PROBE
,
ERR
,
"Invalid MTU setting
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -1911,7 +1883,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
adapter
->
rx_buffer_len
=
E1000_RXBUFFER_2048
;
}
else
if
(
adapter
->
hw
.
mac_type
<
e1000_82543
)
{
E1000_ERR
(
"Jumbo Frames not supported on 82542
\n
"
);
DPRINTK
(
PROBE
,
ERR
,
"Jumbo Frames not supported on 82542
\n
"
);
return
-
EINVAL
;
}
else
if
(
max_frame
<=
E1000_RXBUFFER_4096
)
{
...
...
@@ -2193,7 +2165,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
unsigned
int
i
,
eop
;
boolean_t
cleaned
=
FALSE
;
spin_lock
(
&
adapter
->
tx_lock
);
i
=
tx_ring
->
next_to_clean
;
eop
=
tx_ring
->
buffer_info
[
i
].
next_to_watch
;
...
...
@@ -2236,6 +2207,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring
->
next_to_clean
=
i
;
spin_lock
(
&
adapter
->
tx_lock
);
if
(
cleaned
&&
netif_queue_stopped
(
netdev
)
&&
netif_carrier_ok
(
netdev
))
netif_wake_queue
(
netdev
);
...
...
@@ -2296,7 +2269,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
/* All receives must fit into a single buffer */
E1000_DBG
(
"Receive packet consumed multiple buffers
\n
"
);
E1000_DBG
(
"%s: Receive packet consumed multiple buffers
\n
"
,
netdev
->
name
);
dev_kfree_skb_irq
(
skb
);
rx_desc
->
status
=
0
;
...
...
@@ -2513,8 +2487,6 @@ e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case
SIOCGMIIREG
:
case
SIOCSMIIREG
:
return
e1000_mii_ioctl
(
netdev
,
ifr
,
cmd
);
case
SIOCETHTOOL
:
return
e1000_ethtool_ioctl
(
netdev
,
ifr
);
default:
return
-
EOPNOTSUPP
;
}
...
...
drivers/net/e1000/e1000_param.c
View file @
7991c128
...
...
@@ -234,7 +234,8 @@ struct e1000_option {
};
static
int
__devinit
e1000_validate_option
(
int
*
value
,
struct
e1000_option
*
opt
)
e1000_validate_option
(
int
*
value
,
struct
e1000_option
*
opt
,
struct
e1000_adapter
*
adapter
)
{
if
(
*
value
==
OPTION_UNSET
)
{
*
value
=
opt
->
def
;
...
...
@@ -245,16 +246,17 @@ e1000_validate_option(int *value, struct e1000_option *opt)
case
enable_option
:
switch
(
*
value
)
{
case
OPTION_ENABLED
:
printk
(
KERN_INFO
"%s Enabled
\n
"
,
opt
->
name
);
DPRINTK
(
PROBE
,
INFO
,
"%s Enabled
\n
"
,
opt
->
name
);
return
0
;
case
OPTION_DISABLED
:
printk
(
KERN_INFO
"%s Disabled
\n
"
,
opt
->
name
);
DPRINTK
(
PROBE
,
INFO
,
"%s Disabled
\n
"
,
opt
->
name
);
return
0
;
}
break
;
case
range_option
:
if
(
*
value
>=
opt
->
arg
.
r
.
min
&&
*
value
<=
opt
->
arg
.
r
.
max
)
{
printk
(
KERN_INFO
"%s set to %i
\n
"
,
opt
->
name
,
*
value
);
DPRINTK
(
PROBE
,
INFO
,
"%s set to %i
\n
"
,
opt
->
name
,
*
value
);
return
0
;
}
break
;
...
...
@@ -266,7 +268,7 @@ e1000_validate_option(int *value, struct e1000_option *opt)
ent
=
&
opt
->
arg
.
l
.
p
[
i
];
if
(
*
value
==
ent
->
i
)
{
if
(
ent
->
str
[
0
]
!=
'\0'
)
printk
(
KERN_INFO
"%s
\n
"
,
ent
->
str
);
DPRINTK
(
PROBE
,
INFO
,
"%s
\n
"
,
ent
->
str
);
return
0
;
}
}
...
...
@@ -276,7 +278,7 @@ e1000_validate_option(int *value, struct e1000_option *opt)
BUG
();
}
printk
(
KERN_INFO
"Invalid %s specified (%i) %s
\n
"
,
DPRINTK
(
PROBE
,
INFO
,
"Invalid %s specified (%i) %s
\n
"
,
opt
->
name
,
*
value
,
opt
->
err
);
*
value
=
opt
->
def
;
return
-
1
;
...
...
@@ -300,9 +302,9 @@ e1000_check_options(struct e1000_adapter *adapter)
{
int
bd
=
adapter
->
bd_number
;
if
(
bd
>=
E1000_MAX_NIC
)
{
printk
(
KERN_NOTICE
DPRINTK
(
PROBE
,
NOTICE
,
"Warning: no configuration for board #%i
\n
"
,
bd
);
printk
(
KERN_NOTICE
"Using defaults for all values
\n
"
);
DPRINTK
(
PROBE
,
NOTICE
,
"Using defaults for all values
\n
"
);
bd
=
E1000_MAX_NIC
;
}
...
...
@@ -321,7 +323,7 @@ e1000_check_options(struct e1000_adapter *adapter)
E1000_MAX_TXD
:
E1000_MAX_82544_TXD
;
tx_ring
->
count
=
TxDescriptors
[
bd
];
e1000_validate_option
(
&
tx_ring
->
count
,
&
opt
);
e1000_validate_option
(
&
tx_ring
->
count
,
&
opt
,
adapter
);
E1000_ROUNDUP
(
tx_ring
->
count
,
REQ_TX_DESCRIPTOR_MULTIPLE
);
}
{
/* Receive Descriptor Count */
...
...
@@ -339,7 +341,7 @@ e1000_check_options(struct e1000_adapter *adapter)
E1000_MAX_82544_RXD
;
rx_ring
->
count
=
RxDescriptors
[
bd
];
e1000_validate_option
(
&
rx_ring
->
count
,
&
opt
);
e1000_validate_option
(
&
rx_ring
->
count
,
&
opt
,
adapter
);
E1000_ROUNDUP
(
rx_ring
->
count
,
REQ_RX_DESCRIPTOR_MULTIPLE
);
}
{
/* Checksum Offload Enable/Disable */
...
...
@@ -351,7 +353,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
int
rx_csum
=
XsumRX
[
bd
];
e1000_validate_option
(
&
rx_csum
,
&
opt
);
e1000_validate_option
(
&
rx_csum
,
&
opt
,
adapter
);
adapter
->
rx_csum
=
rx_csum
;
}
{
/* Flow Control */
...
...
@@ -373,7 +375,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
int
fc
=
FlowControl
[
bd
];
e1000_validate_option
(
&
fc
,
&
opt
);
e1000_validate_option
(
&
fc
,
&
opt
,
adapter
);
adapter
->
hw
.
fc
=
adapter
->
hw
.
original_fc
=
fc
;
}
{
/* Transmit Interrupt Delay */
...
...
@@ -387,7 +389,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter
->
tx_int_delay
=
TxIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
tx_int_delay
,
&
opt
);
e1000_validate_option
(
&
adapter
->
tx_int_delay
,
&
opt
,
adapter
);
}
{
/* Transmit Absolute Interrupt Delay */
struct
e1000_option
opt
=
{
...
...
@@ -400,7 +402,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter
->
tx_abs_int_delay
=
TxAbsIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
tx_abs_int_delay
,
&
opt
);
e1000_validate_option
(
&
adapter
->
tx_abs_int_delay
,
&
opt
,
adapter
);
}
{
/* Receive Interrupt Delay */
struct
e1000_option
opt
=
{
...
...
@@ -413,7 +415,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter
->
rx_int_delay
=
RxIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
rx_int_delay
,
&
opt
);
e1000_validate_option
(
&
adapter
->
rx_int_delay
,
&
opt
,
adapter
);
}
{
/* Receive Absolute Interrupt Delay */
struct
e1000_option
opt
=
{
...
...
@@ -426,7 +428,7 @@ e1000_check_options(struct e1000_adapter *adapter)
};
adapter
->
rx_abs_int_delay
=
RxAbsIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
rx_abs_int_delay
,
&
opt
);
e1000_validate_option
(
&
adapter
->
rx_abs_int_delay
,
&
opt
,
adapter
);
}
{
/* Interrupt Throttling Rate */
struct
e1000_option
opt
=
{
...
...
@@ -444,13 +446,14 @@ e1000_check_options(struct e1000_adapter *adapter)
adapter
->
itr
=
1
;
break
;
case
0
:
printk
(
KERN_INFO
"%s turned off
\n
"
,
opt
.
name
);
DPRINTK
(
PROBE
,
INFO
,
"%s turned off
\n
"
,
opt
.
name
);
break
;
case
1
:
printk
(
KERN_INFO
"%s set to dynamic mode
\n
"
,
opt
.
name
);
DPRINTK
(
PROBE
,
INFO
,
"%s set to dynamic mode
\n
"
,
opt
.
name
);
break
;
default:
e1000_validate_option
(
&
adapter
->
itr
,
&
opt
);
e1000_validate_option
(
&
adapter
->
itr
,
&
opt
,
adapter
);
break
;
}
}
...
...
@@ -482,15 +485,15 @@ e1000_check_fiber_options(struct e1000_adapter *adapter)
bd
=
bd
>
E1000_MAX_NIC
?
E1000_MAX_NIC
:
bd
;
if
((
Speed
[
bd
]
!=
OPTION_UNSET
))
{
printk
(
KERN_INFO
"Speed not valid for fiber adapters, "
DPRINTK
(
PROBE
,
INFO
,
"Speed not valid for fiber adapters, "
"parameter ignored
\n
"
);
}
if
((
Duplex
[
bd
]
!=
OPTION_UNSET
))
{
printk
(
KERN_INFO
"Duplex not valid for fiber adapters, "
DPRINTK
(
PROBE
,
INFO
,
"Duplex not valid for fiber adapters, "
"parameter ignored
\n
"
);
}
if
((
AutoNeg
[
bd
]
!=
OPTION_UNSET
)
&&
(
AutoNeg
[
bd
]
!=
0x20
))
{
printk
(
KERN_INFO
"AutoNeg other than Full/1000 is "
DPRINTK
(
PROBE
,
INFO
,
"AutoNeg other than Full/1000 is "
"not valid for fiber adapters, parameter ignored
\n
"
);
}
}
...
...
@@ -525,7 +528,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
speed
=
Speed
[
bd
];
e1000_validate_option
(
&
speed
,
&
opt
);
e1000_validate_option
(
&
speed
,
&
opt
,
adapter
);
}
{
/* Duplex */
struct
e1000_opt_list
dplx_list
[]
=
{{
0
,
""
},
...
...
@@ -542,11 +545,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
dplx
=
Duplex
[
bd
];
e1000_validate_option
(
&
dplx
,
&
opt
);
e1000_validate_option
(
&
dplx
,
&
opt
,
adapter
);
}
if
(
AutoNeg
[
bd
]
!=
OPTION_UNSET
&&
(
speed
!=
0
||
dplx
!=
0
))
{
printk
(
KERN_INFO
DPRINTK
(
PROBE
,
INFO
,
"AutoNeg specified along with Speed or Duplex, "
"parameter ignored
\n
"
);
adapter
->
hw
.
autoneg_advertised
=
AUTONEG_ADV_DEFAULT
;
...
...
@@ -595,7 +598,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
};
int
an
=
AutoNeg
[
bd
];
e1000_validate_option
(
&
an
,
&
opt
);
e1000_validate_option
(
&
an
,
&
opt
,
adapter
);
adapter
->
hw
.
autoneg_advertised
=
an
;
}
...
...
@@ -603,78 +606,85 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
case
0
:
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
if
(
Speed
[
bd
]
!=
OPTION_UNSET
||
Duplex
[
bd
]
!=
OPTION_UNSET
)
printk
(
KERN_INFO
DPRINTK
(
PROBE
,
INFO
,
"Speed and duplex autonegotiation enabled
\n
"
);
break
;
case
HALF_DUPLEX
:
printk
(
KERN_INFO
"Half Duplex specified without Speed
\n
"
);
printk
(
KERN_INFO
"Using Autonegotiation at Half Duplex only
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Half Duplex specified without Speed
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at Half Duplex only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_10_HALF
|
ADVERTISE_100_HALF
;
break
;
case
FULL_DUPLEX
:
printk
(
KERN_INFO
"Full Duplex specified without Speed
\n
"
);
printk
(
KERN_INFO
"Using Autonegotiation at Full Duplex only
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Full Duplex specified without Speed
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at Full Duplex only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_10_FULL
|
ADVERTISE_100_FULL
|
ADVERTISE_1000_FULL
;
break
;
case
SPEED_10
:
printk
(
KERN_INFO
"10 Mbps Speed specified without Duplex
\n
"
);
printk
(
KERN_INFO
"Using Autonegotiation at 10 Mbps only
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"10 Mbps Speed specified without Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at 10 Mbps only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_10_HALF
|
ADVERTISE_10_FULL
;
break
;
case
SPEED_10
+
HALF_DUPLEX
:
printk
(
KERN_INFO
"Forcing to 10 Mbps Half Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Forcing to 10 Mbps Half Duplex
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
0
;
adapter
->
hw
.
forced_speed_duplex
=
e1000_10_half
;
adapter
->
hw
.
autoneg_advertised
=
0
;
break
;
case
SPEED_10
+
FULL_DUPLEX
:
printk
(
KERN_INFO
"Forcing to 10 Mbps Full Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Forcing to 10 Mbps Full Duplex
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
0
;
adapter
->
hw
.
forced_speed_duplex
=
e1000_10_full
;
adapter
->
hw
.
autoneg_advertised
=
0
;
break
;
case
SPEED_100
:
printk
(
KERN_INFO
"100 Mbps Speed specified without Duplex
\n
"
);
printk
(
KERN_INFO
"Using Autonegotiation at 100 Mbps only
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"100 Mbps Speed specified without Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at 100 Mbps only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_100_HALF
|
ADVERTISE_100_FULL
;
break
;
case
SPEED_100
+
HALF_DUPLEX
:
printk
(
KERN_INFO
"Forcing to 100 Mbps Half Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Forcing to 100 Mbps Half Duplex
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
0
;
adapter
->
hw
.
forced_speed_duplex
=
e1000_100_half
;
adapter
->
hw
.
autoneg_advertised
=
0
;
break
;
case
SPEED_100
+
FULL_DUPLEX
:
printk
(
KERN_INFO
"Forcing to 100 Mbps Full Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Forcing to 100 Mbps Full Duplex
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
0
;
adapter
->
hw
.
forced_speed_duplex
=
e1000_100_full
;
adapter
->
hw
.
autoneg_advertised
=
0
;
break
;
case
SPEED_1000
:
printk
(
KERN_INFO
"1000 Mbps Speed specified without Duplex
\n
"
);
printk
(
KERN_INFO
DPRINTK
(
PROBE
,
INFO
,
"1000 Mbps Speed specified without Duplex
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at 1000 Mbps Full Duplex only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_1000_FULL
;
break
;
case
SPEED_1000
+
HALF_DUPLEX
:
printk
(
KERN_INFO
"Half Duplex is not supported at 1000 Mbps
\n
"
);
printk
(
KERN_INFO
DPRINTK
(
PROBE
,
INFO
,
"Half Duplex is not supported at 1000 Mbps
\n
"
);
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at 1000 Mbps Full Duplex only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_1000_FULL
;
break
;
case
SPEED_1000
+
FULL_DUPLEX
:
printk
(
KERN_INFO
DPRINTK
(
PROBE
,
INFO
,
"Using Autonegotiation at 1000 Mbps Full Duplex only
\n
"
);
adapter
->
hw
.
autoneg
=
adapter
->
fc_autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_1000_FULL
;
...
...
@@ -685,7 +695,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
/* Speed, AutoNeg and MDI/MDI-X must all play nice */
if
(
e1000_validate_mdi_setting
(
&
(
adapter
->
hw
))
<
0
)
{
printk
(
KERN_INFO
"Speed, AutoNeg and MDI-X specifications are "
DPRINTK
(
PROBE
,
INFO
,
"Speed, AutoNeg and MDI-X specifications are "
"incompatible. Setting MDI-X to a compatible value.
\n
"
);
}
}
...
...
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