Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
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