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
e5c136c0
Commit
e5c136c0
authored
Mar 20, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/garz/repo/e1000-2.5
into redhat.com:/garz/repo/net-drivers-2.5
parents
605cafbe
3cddbbc6
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
2325 additions
and
937 deletions
+2325
-937
Documentation/networking/e1000.txt
Documentation/networking/e1000.txt
+73
-59
MAINTAINERS
MAINTAINERS
+3
-2
drivers/net/Kconfig
drivers/net/Kconfig
+1
-0
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000.h
+25
-7
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_ethtool.c
+39
-65
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.c
+1323
-447
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_hw.h
+265
-38
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_main.c
+524
-282
drivers/net/e1000/e1000_osdep.h
drivers/net/e1000/e1000_osdep.h
+11
-13
drivers/net/e1000/e1000_param.c
drivers/net/e1000/e1000_param.c
+61
-24
No files found.
Documentation/networking/e1000.txt
View file @
e5c136c0
Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
===============================================================
October 12, 2002
January 8, 2003
Contents
...
...
@@ -20,33 +20,17 @@ In This Release
===============
This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
of Adapters, version
4.4
.x. This driver includes support for
of Adapters, version
5.0
.x. This driver includes support for
Itanium(TM)-based systems.
This release version includes the following:
- Support for the ethtool 1.6 interface. A third-party application can use
the ethtool interface to get and set driver parameters.
- Zero copy. This feature provides faster data throughput. Enabled by
default in supporting kernels. It is not supported on the Intel(R)
PRO/1000 Gigabit Server Adapter.
Features include:
- Support for the 82545 and 82546-based adapters listed below
- Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
based adapters
- Adaptive IFS for increased performance at half duplex
Native VLANs are now available with supported kernels.
Supported Adapters
==================
The following Intel network adapters are compatible with the drivers in this
The following Intel network adapters are compatible with the drivers in this
release:
Controller Adapter Name Board IDs
...
...
@@ -65,6 +49,7 @@ release:
82544 PRO/1000 T Desktop Adapter A62947-xxx
82540 PRO/1000 MT Desktop Adapter A78408-xxx
82541 C91016-xxx
82545 PRO/1000 MT Server Adapter A92165-xxx
...
...
@@ -77,33 +62,42 @@ release:
82546 PRO/1000 MF Dual Port Server Adapter A91620-xxx
To verify your Intel adapter is supported, find the board ID number on the
adapter. Look for a label that has a barcode and a number in the format of
123456-001 (six digits hyphen three digits). Match this to the list of
numbers above.
For more information on how to identify your adapter, go to the Adapter &
To verify your Intel adapter is supported, find the board ID number on the
adapter. Look for a label that has a barcode and a number in the format
A12345-001. Match this to the list of numbers above.
For more information on how to identify your adapter, go to the Adapter &
Driver ID Guide at:
http://support.intel.com/support/network/adapter/pro100/21397.htm
For the latest Intel network drivers for Linux,
go to:
For the latest Intel network drivers for Linux,
refer to the following
http://
apps
r.intel.com/scripts-df/support_intel.asp
http://
downloadfinde
r.intel.com/scripts-df/support_intel.asp
Command Line Parameters
=======================
If the driver is built as a module, the following optional parameters are
used by entering them on the command line with the modprobe or insmod command.
If the driver is built as a module, the following optional parameters are
used by entering them on the command line with the modprobe or insmod command
using this syntax:
modprobe e1000 [<option>=<VAL1>,<VAL2>,...]
insmod e1000 [<option>=<VAL1>,<VAL2>,...]
For example, with two PRO/1000 PCI adapters, entering:
insmod e1000 TxDescriptors=80,128
insmod e1000 TxDescriptors=80,128
loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
resources for the second adapter.
The default value for each parameter is generally the recommended setting,
unless otherwise noted.
For more information about the AutoNeg, Duplex, and Speed parameters, see the
"Speed and Duplex Configuration" section in this document.
...
...
@@ -129,6 +123,20 @@ Default: Read flow control settings from the EEPROM
This parameter controls the automatic generation(Tx) and response(Rx) to
Ethernet PAUSE frames.
InterruptThrottleRate
Valid Range: 100-100000 (0=off, 1=dynamic)
Default Value: 1
This value represents the maximum number of interrupts per second the
controller generates. InterruptThrottleRate is another setting used in
interrupt moderation. Dynamic mode uses a heuristic algorithm to adjust
InterruptThrottleRate based on the current traffic load.
NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and
RxAbsIntDelay parameters. In other words, minimizing the receive
and/or transmit absolute delays does not force the controller to
generate more interrupts than what the Interrupt Throttle Rate
allows.
RxDescriptors
Valid Range: 80-256 for 82542 and 82543-based adapters
80-4096 for 82540, 82544, 82545, and 82546-based adapters
...
...
@@ -154,9 +162,9 @@ Default Value: 0
descriptors.
CAUTION: When setting RxIntDelay to a value other than 0, adapters may
hang (stop transmitting) under certain network conditions. If
hang (stop transmitting) under certain network conditions. If
this occurs a NETDEV WATCHDOG message is logged in the system
event log. In addition, the controller is automatically reset,
event log. In addition, the controller is automatically reset,
restoring the network connection. To eliminate the potential for
the hang ensure that RxIntDelay is set to 0.
...
...
@@ -176,7 +184,7 @@ Default Value: 0 (auto-negotiate at all supported speeds)
Speed forces the line speed to the specified value in megabits per second
(Mbps). If this parameter is not specified or is set to 0 and the link
partner is set to auto-negotiate, the board will auto-detect the correct
speed. Duplex
must
also be set when Speed is set to either 10 or 100.
speed. Duplex
should
also be set when Speed is set to either 10 or 100.
TxDescriptors
Valid Range: 80-256 for 82542 and 82543-based adapters
...
...
@@ -190,7 +198,7 @@ TxIntDelay
Valid Range: 0-65535 (0=off)
Default Value: 64
This value delays the generation of transmit interrupts in units of
1.024 microseconds.
Transmit interrupt reduction can improve CPU
1.024 microseconds. Transmit interrupt reduction can improve CPU
efficiency if properly tuned for specific network traffic. If the
system is reporting dropped transmits, this value may be set too high
causing the driver to run out of available transmit descriptors.
...
...
@@ -205,7 +213,7 @@ Default Value: 64
along with TxIntDelay, may improve traffic throughput in specific
network conditions.
XsumRX (not available on the
PRO/1000 Gigabit Server A
dapter)
XsumRX (not available on the
82542-based a
dapter)
Valid Range: 0-1
Default Value: 1
A value of '1' indicates that the driver should enable IP checksum
...
...
@@ -215,10 +223,10 @@ Default Value: 1
Speed and Duplex Configuration
==============================
Three keywords are used to control the speed and duplex configuration. These
Three keywords are used to control the speed and duplex configuration. These
keywords are Speed, Duplex, and AutoNeg.
If the board uses a fiber interface, these keywords are ignored, and the
If the board uses a fiber interface, these keywords are ignored, and the
fiber interface board only links at 1000 Mbps full-duplex.
For copper-based boards, the keywords interact as follows:
...
...
@@ -230,23 +238,23 @@ For copper-based boards, the keywords interact as follows:
If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
advertised (The 1000BaseT spec requires auto-negotiation.)
If Speed = 10 or 100, then both Speed and Duplex
must
be set. Auto-
negotiation is disabled, and the AutoNeg parameter is ignored. Partner
MUST
If Speed = 10 or 100, then both Speed and Duplex
should
be set. Auto-
negotiation is disabled, and the AutoNeg parameter is ignored. Partner
SHOULD
also be forced.
The AutoNeg parameter is used when more control is required over the auto-
negotiation process. When this parameter is used, Speed and Duplex must not
be specified. This parameter is a bitmap that specifies which speed and
negotiation process. When this parameter is used, Speed and Duplex must not
be specified. This parameter is a bitmap that specifies which speed and
duplex settings are advertised to the link partner.
Bit 7 6 5 4 3 2 1 0
Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10
Duplex Full Full Half Full Half
Note that setting AutoNeg does not guarantee that the board will link at the
highest specified speed or duplex mode, but the board will link at the
Note that setting AutoNeg does not guarantee that the board will link at the
highest specified speed or duplex mode, but the board will link at the
highest possible speed/duplex of the link partner IF the link partner is also
set to auto-negotiate. If the link partner is forced speed/duplex, the
set to auto-negotiate. If the link partner is forced speed/duplex, the
adapter MUST be forced to the same speed/duplex.
...
...
@@ -256,13 +264,19 @@ Additional Configurations
Jumbo Frames
------------
The driver supports Jumbo Frames for all adapters except 82542-based
adapters.
Jumbo Frames support is enabled by changing the MTU to a value
larger than the default of 1500.
Use the ifconfig command to increase the
The driver supports Jumbo Frames for all adapters except 82542-based
adapters.
Jumbo Frames support is enabled by changing the MTU to a value
larger than the default of 1500.
Use the ifconfig command to increase the
MTU size. For example:
ifconfig ethx mtu 9000 up
The maximum MTU setting for Jumbo Frames is 16110. This value coincides
with the maximum Jumbo Frames size of 16128.
NOTE: Jumbo Frames are supported at 1000 Mbps only. Using Jumbo Frames at
10 or 100 Mbps may result in poor performance or loss of link.
Known Issues
============
...
...
@@ -270,33 +284,33 @@ Known Issues
Jumbo Frames System Requirement
-------------------------------
Memory allocation failures have been observed on Linux systems with 64 MB
of RAM or less that are running Jumbo Frames. If you are using Jumbo
Frames, your system may require more than the advertised minimum
Memory allocation failures have been observed on Linux systems with 64 MB
of RAM or less that are running Jumbo Frames. If you are using Jumbo
Frames, your system may require more than the advertised minimum
requirement of 64 MB of system memory.
Support
=======
For general information
and support
, go to the Intel support website at:
For general information, go to the Intel support website at:
http://support.intel.com
If an issue is identified with the released source code on the supported
kernel with a supported adapter, email the specific information related to
kernel with a supported adapter, email the specific information related to
the issue to linux.nics@intel.com.
License
=======
This software program is released under the terms of a license agreement
between you ('Licensee') and Intel. Do not use or load this software or any
associated materials (collectively, the 'Software') until you have carefully
read the full terms and conditions of the LICENSE located in this software
package. By loading or using the Software, you agree to the terms of this
Agreement. If you do not agree with the terms of this Agreement, do not
This software program is released under the terms of a license agreement
between you ('Licensee') and Intel. Do not use or load this software or any
associated materials (collectively, the 'Software') until you have carefully
read the full terms and conditions of the LICENSE located in this software
package. By loading or using the Software, you agree to the terms of this
Agreement. If you do not agree with the terms of this Agreement, do not
install or use the Software.
* Other names and brands may be claimed as the property of others.
MAINTAINERS
View file @
e5c136c0
...
...
@@ -923,10 +923,11 @@ M: scott.feldman@intel.com
S: Supported
INTEL PRO/1000 GIGABIT ETHERNET SUPPORT
P:
Chris Leech
M: c
hristopher.leech
@intel.com
P:
Jeb Cramer
M: c
ramerj
@intel.com
P: Scott Feldman
M: scott.feldman@intel.com
W: http://sourceforge.net/projects/e1000/
S: Supported
INTERMEZZO FILE SYSTEM
...
...
drivers/net/Kconfig
View file @
e5c136c0
...
...
@@ -1953,6 +1953,7 @@ config E1000
82544 PRO/1000 XF Server Adapter A50484-xxx
82544 PRO/1000 T Desktop Adapter A62947-xxx
82540 PRO/1000 MT Desktop Adapter A78408-xxx
82541 PRO/1000 MT Desktop Adapter C91016-xxx
82545 PRO/1000 MT Server Adapter A92165-xxx
82546 PRO/1000 MT Dual Port Server Adapter A92111-xxx
82545 PRO/1000 MF Server Adapter A91622-xxx
...
...
drivers/net/e1000/e1000.h
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -65,6 +65,7 @@
#include <linux/reboot.h>
#include <net/checksum.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
...
...
@@ -95,6 +96,15 @@ struct e1000_adapter;
#define E1000_RXBUFFER_8192 8192
#define E1000_RXBUFFER_16384 16384
/* SmartSpeed delimiters */
#define E1000_SMARTSPEED_DOWNSHIFT 3
#define E1000_SMARTSPEED_MAX 15
/* Packet Buffer allocations */
#define E1000_TX_FIFO_SIZE_SHIFT 0xA
#define E1000_TX_HEAD_ADDR_SHIFT 7
#define E1000_PBA_TX_MASK 0xFFFF0000
/* Flow Control High-Watermark: 43464 bytes */
#define E1000_FC_HIGH_THRESH 0xA9C8
...
...
@@ -107,10 +117,7 @@ struct e1000_adapter;
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define E1000_TX_QUEUE_WAKE 16
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE 16
#define E1000_JUMBO_PBA 0x00000028
#define E1000_DEFAULT_PBA 0x00000030
#define E1000_RX_BUFFER_WRITE 16
/* Must be power of 2 */
#define AUTO_ALL_MODES 0
#define E1000_EEPROM_APME 4
...
...
@@ -145,7 +152,8 @@ struct e1000_desc_ring {
};
#define E1000_DESC_UNUSED(R) \
((((R)->next_to_clean + (R)->count) - ((R)->next_to_use + 1)) % ((R)->count))
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
(R)->next_to_clean - (R)->next_to_use - 1)
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
...
...
@@ -155,6 +163,7 @@ struct e1000_desc_ring {
/* board specific private data structure */
struct
e1000_adapter
{
struct
timer_list
tx_fifo_stall_timer
;
struct
timer_list
watchdog_timer
;
struct
timer_list
phy_info_timer
;
struct
vlan_group
*
vlgrp
;
...
...
@@ -163,6 +172,7 @@ struct e1000_adapter {
uint32_t
rx_buffer_len
;
uint32_t
part_num
;
uint32_t
wol
;
uint32_t
smartspeed
;
uint16_t
link_speed
;
uint16_t
link_duplex
;
spinlock_t
stats_lock
;
...
...
@@ -177,7 +187,11 @@ struct e1000_adapter {
uint32_t
txd_cmd
;
uint32_t
tx_int_delay
;
uint32_t
tx_abs_int_delay
;
int
max_data_per_txd
;
uint32_t
gotcl
;
uint32_t
tx_fifo_head
;
uint32_t
tx_head_addr
;
uint32_t
tx_fifo_size
;
atomic_t
tx_fifo_stall
;
/* RX */
struct
e1000_desc_ring
rx_ring
;
...
...
@@ -186,6 +200,10 @@ struct e1000_adapter {
uint32_t
rx_int_delay
;
uint32_t
rx_abs_int_delay
;
boolean_t
rx_csum
;
uint32_t
gorcl
;
/* Interrupt Throttle Rate */
uint32_t
itr
;
/* OS defined structs */
struct
net_device
*
netdev
;
...
...
drivers/net/e1000/e1000_ethtool.c
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -38,6 +38,7 @@ extern char e1000_driver_version[];
extern
int
e1000_up
(
struct
e1000_adapter
*
adapter
);
extern
void
e1000_down
(
struct
e1000_adapter
*
adapter
);
extern
void
e1000_reset
(
struct
e1000_adapter
*
adapter
);
extern
int
e1000_set_spd_dplx
(
struct
e1000_adapter
*
adapter
,
uint16_t
spddplx
);
static
char
e1000_gstrings_stats
[][
ETH_GSTRING_LEN
]
=
{
"rx_packets"
,
"tx_packets"
,
"rx_bytes"
,
"tx_bytes"
,
"rx_errors"
,
...
...
@@ -129,30 +130,9 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
hw
->
autoneg
=
1
;
hw
->
autoneg_advertised
=
0x002F
;
ecmd
->
advertising
=
0x002F
;
}
else
{
hw
->
autoneg
=
0
;
switch
(
ecmd
->
speed
+
ecmd
->
duplex
)
{
case
SPEED_10
+
DUPLEX_HALF
:
hw
->
forced_speed_duplex
=
e1000_10_half
;
break
;
case
SPEED_10
+
DUPLEX_FULL
:
hw
->
forced_speed_duplex
=
e1000_10_full
;
break
;
case
SPEED_100
+
DUPLEX_HALF
:
hw
->
forced_speed_duplex
=
e1000_100_half
;
break
;
case
SPEED_100
+
DUPLEX_FULL
:
hw
->
forced_speed_duplex
=
e1000_100_full
;
break
;
case
SPEED_1000
+
DUPLEX_FULL
:
hw
->
autoneg
=
1
;
hw
->
autoneg_advertised
=
ADVERTISE_1000_FULL
;
break
;
case
SPEED_1000
+
DUPLEX_HALF
:
/* not supported */
default:
}
else
if
(
e1000_set_spd_dplx
(
adapter
,
ecmd
->
speed
+
ecmd
->
duplex
))
return
-
EINVAL
;
}
}
/* reset the link */
...
...
@@ -165,16 +145,6 @@ e1000_ethtool_sset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
return
0
;
}
static
inline
int
e1000_eeprom_size
(
struct
e1000_hw
*
hw
)
{
if
((
hw
->
mac_type
>
e1000_82544
)
&&
(
E1000_READ_REG
(
hw
,
EECD
)
&
E1000_EECD_SIZE
))
return
512
;
else
return
128
;
}
static
void
e1000_ethtool_gdrvinfo
(
struct
e1000_adapter
*
adapter
,
struct
ethtool_drvinfo
*
drvinfo
)
...
...
@@ -186,7 +156,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
drvinfo
->
n_stats
=
E1000_STATS_LEN
;
#define E1000_REGS_LEN 32
drvinfo
->
regdump_len
=
E1000_REGS_LEN
*
sizeof
(
uint32_t
);
drvinfo
->
eedump_len
=
e1000_eeprom_size
(
&
adapter
->
hw
)
;
drvinfo
->
eedump_len
=
adapter
->
hw
.
eeprom
.
word_size
*
2
;
}
static
void
...
...
@@ -220,9 +190,8 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
struct
ethtool_eeprom
*
eeprom
,
uint16_t
*
eeprom_buff
)
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
int
max_len
,
first_word
,
last_word
;
int
first_word
,
last_word
;
int
ret_val
=
0
;
int
i
;
if
(
eeprom
->
len
==
0
)
{
ret_val
=
-
EINVAL
;
...
...
@@ -231,22 +200,28 @@ e1000_ethtool_geeprom(struct e1000_adapter *adapter,
eeprom
->
magic
=
hw
->
vendor_id
|
(
hw
->
device_id
<<
16
);
max_len
=
e1000_eeprom_size
(
hw
);
if
(
eeprom
->
offset
>
eeprom
->
offset
+
eeprom
->
len
)
{
ret_val
=
-
EINVAL
;
goto
geeprom_error
;
}
if
((
eeprom
->
offset
+
eeprom
->
len
)
>
max_len
)
eeprom
->
len
=
(
max_len
-
eeprom
->
offset
);
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
;
for
(
i
=
0
;
i
<=
(
last_word
-
first_word
);
i
++
)
e1000_read_eeprom
(
hw
,
first_word
+
i
,
&
eeprom_buff
[
i
]);
if
(
hw
->
eeprom
.
type
==
e1000_eeprom_spi
)
ret_val
=
e1000_read_eeprom
(
hw
,
first_word
,
last_word
-
first_word
+
1
,
eeprom_buff
);
else
{
uint16_t
i
;
for
(
i
=
0
;
i
<
last_word
-
first_word
+
1
;
i
++
)
if
((
ret_val
=
e1000_read_eeprom
(
hw
,
first_word
+
i
,
1
,
&
eeprom_buff
[
i
])))
break
;
}
geeprom_error:
return
ret_val
;
}
...
...
@@ -257,9 +232,8 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
{
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
*
eeprom_buff
;
int
max_len
,
first_word
,
last_word
;
void
*
ptr
;
int
i
;
int
max_len
,
first_word
,
last_word
,
ret_val
=
0
;
if
(
eeprom
->
len
==
0
)
return
-
EOPNOTSUPP
;
...
...
@@ -267,7 +241,7 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if
(
eeprom
->
magic
!=
(
hw
->
vendor_id
|
(
hw
->
device_id
<<
16
)))
return
-
EFAULT
;
max_len
=
e1000_eeprom_size
(
hw
)
;
max_len
=
hw
->
eeprom
.
word_size
*
2
;
if
((
eeprom
->
offset
+
eeprom
->
len
)
>
max_len
)
eeprom
->
len
=
(
max_len
-
eeprom
->
offset
);
...
...
@@ -283,30 +257,31 @@ e1000_ethtool_seeprom(struct e1000_adapter *adapter,
if
(
eeprom
->
offset
&
1
)
{
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
e1000_read_eeprom
(
hw
,
first_word
,
&
eeprom_buff
[
0
]);
ret_val
=
e1000_read_eeprom
(
hw
,
first_word
,
1
,
&
eeprom_buff
[
0
]);
ptr
++
;
}
if
((
eeprom
->
offset
+
eeprom
->
len
)
&
1
)
{
if
((
(
eeprom
->
offset
+
eeprom
->
len
)
&
1
)
&&
(
ret_val
==
0
)
)
{
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
e1000_read_eeprom
(
hw
,
last_word
,
ret_val
=
e1000_read_eeprom
(
hw
,
last_word
,
1
,
&
eeprom_buff
[
last_word
-
first_word
]);
}
if
(
copy_from_user
(
ptr
,
user_data
,
eeprom
->
len
))
{
kfree
(
eeprom_buff
)
;
return
-
EFAULT
;
if
(
(
ret_val
!=
0
)
||
copy_from_user
(
ptr
,
user_data
,
eeprom
->
len
))
{
ret_val
=
-
EFAULT
;
goto
seeprom_error
;
}
for
(
i
=
0
;
i
<=
(
last_word
-
first_word
);
i
++
)
e1000_write_eeprom
(
hw
,
first_word
+
i
,
eeprom_buff
[
i
]
);
ret_val
=
e1000_write_eeprom
(
hw
,
first_word
,
last_word
-
first_word
+
1
,
eeprom_buff
);
/* Update the checksum over the first part of the EEPROM if needed */
if
(
first_word
<=
EEPROM_CHECKSUM_REG
)
if
(
(
ret_val
==
0
)
&&
first_word
<=
EEPROM_CHECKSUM_REG
)
e1000_update_eeprom_checksum
(
hw
);
seeprom_error:
kfree
(
eeprom_buff
);
return
0
;
return
ret_val
;
}
static
void
...
...
@@ -333,8 +308,8 @@ e1000_ethtool_gwol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */
default:
wol
->
supported
=
WAKE_UCAST
|
WAKE_MCAST
|
WAKE_BCAST
|
WAKE_MAGIC
;
wol
->
supported
=
WAKE_UCAST
|
WAKE_MCAST
|
WAKE_BCAST
|
WAKE_MAGIC
;
wol
->
wolopts
=
0
;
if
(
adapter
->
wol
&
E1000_WUFC_EX
)
...
...
@@ -368,7 +343,7 @@ e1000_ethtool_swol(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
/* Fall Through */
default:
if
(
wol
->
wolopts
&
(
WAKE_
ARP
|
WAKE_MAGICSECURE
|
WAKE_PHY
))
if
(
wol
->
wolopts
&
(
WAKE_
PHY
|
WAKE_ARP
|
WAKE_MAGICSECURE
))
return
-
EOPNOTSUPP
;
adapter
->
wol
=
0
;
...
...
@@ -542,13 +517,12 @@ e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
}
case
ETHTOOL_GEEPROM
:
{
struct
ethtool_eeprom
eeprom
=
{
ETHTOOL_GEEPROM
};
struct
e1000_hw
*
hw
=
&
adapter
->
hw
;
uint16_t
*
eeprom_buff
;
void
*
ptr
;
int
max_len
,
err
=
0
;
max_len
=
e1000_eeprom_size
(
&
adapter
->
hw
);
int
err
=
0
;
eeprom_buff
=
kmalloc
(
max_len
,
GFP_KERNEL
);
eeprom_buff
=
kmalloc
(
hw
->
eeprom
.
word_size
*
2
,
GFP_KERNEL
);
if
(
eeprom_buff
==
NULL
)
return
-
ENOMEM
;
...
...
drivers/net/e1000/e1000_hw.c
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -32,6 +32,8 @@
#include "e1000_hw.h"
static
int32_t
e1000_set_phy_type
(
struct
e1000_hw
*
hw
);
static
void
e1000_phy_init_script
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_setup_fiber_link
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_setup_copper_link
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_phy_force_speed_duplex
(
struct
e1000_hw
*
hw
);
...
...
@@ -42,19 +44,103 @@ static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
static
void
e1000_shift_out_mdi_bits
(
struct
e1000_hw
*
hw
,
uint32_t
data
,
uint16_t
count
);
static
uint16_t
e1000_shift_in_mdi_bits
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_phy_reset_dsp
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_write_eeprom_spi
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
words
,
uint16_t
*
data
);
static
int32_t
e1000_write_eeprom_microwire
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
words
,
uint16_t
*
data
);
static
int32_t
e1000_spi_eeprom_ready
(
struct
e1000_hw
*
hw
);
static
void
e1000_raise_ee_clk
(
struct
e1000_hw
*
hw
,
uint32_t
*
eecd
);
static
void
e1000_lower_ee_clk
(
struct
e1000_hw
*
hw
,
uint32_t
*
eecd
);
static
void
e1000_shift_out_ee_bits
(
struct
e1000_hw
*
hw
,
uint16_t
data
,
uint16_t
count
);
static
uint16_t
e1000_shift_in_ee_bits
(
struct
e1000_hw
*
hw
);
static
void
e1000_setup_eeprom
(
struct
e1000_hw
*
hw
);
static
void
e1000_clock_eeprom
(
struct
e1000_hw
*
hw
);
static
void
e1000_cleanup_eeprom
(
struct
e1000_hw
*
hw
);
static
uint16_t
e1000_shift_in_ee_bits
(
struct
e1000_hw
*
hw
,
uint16_t
count
);
static
int32_t
e1000_acquire_eeprom
(
struct
e1000_hw
*
hw
);
static
void
e1000_release_eeprom
(
struct
e1000_hw
*
hw
);
static
void
e1000_standby_eeprom
(
struct
e1000_hw
*
hw
);
static
int32_t
e1000_id_led_init
(
struct
e1000_hw
*
hw
);
/******************************************************************************
* Set the phy type member in the hw struct.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
int32_t
e1000_set_phy_type
(
struct
e1000_hw
*
hw
)
{
DEBUGFUNC
(
"e1000_set_phy_type"
);
switch
(
hw
->
phy_id
)
{
case
M88E1000_E_PHY_ID
:
case
M88E1000_I_PHY_ID
:
case
M88E1011_I_PHY_ID
:
hw
->
phy_type
=
e1000_phy_m88
;
break
;
case
IGP01E1000_I_PHY_ID
:
hw
->
phy_type
=
e1000_phy_igp
;
break
;
default:
/* Should never have loaded on this device */
hw
->
phy_type
=
e1000_phy_undefined
;
return
-
E1000_ERR_PHY_TYPE
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* IGP phy init script - initializes the GbE PHY
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static
void
e1000_phy_init_script
(
struct
e1000_hw
*
hw
)
{
DEBUGFUNC
(
"e1000_phy_init_script"
);
if
(
hw
->
phy_init_script
)
{
msec_delay
(
10
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0000
);
e1000_write_phy_reg
(
hw
,
0x0000
,
0x0140
);
msec_delay
(
5
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F95
);
e1000_write_phy_reg
(
hw
,
0x0015
,
0x0001
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F71
);
e1000_write_phy_reg
(
hw
,
0x0011
,
0xBD21
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F79
);
e1000_write_phy_reg
(
hw
,
0x0019
,
0x0018
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F30
);
e1000_write_phy_reg
(
hw
,
0x0010
,
0x1600
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F31
);
e1000_write_phy_reg
(
hw
,
0x0011
,
0x0014
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F32
);
e1000_write_phy_reg
(
hw
,
0x0012
,
0x161C
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F94
);
e1000_write_phy_reg
(
hw
,
0x0014
,
0x0003
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x1F96
);
e1000_write_phy_reg
(
hw
,
0x0016
,
0x003F
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x2010
);
e1000_write_phy_reg
(
hw
,
0x0010
,
0x0008
);
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0000
);
e1000_write_phy_reg
(
hw
,
0x0000
,
0x3300
);
}
}
/******************************************************************************
* Set the mac type member in the hw struct.
*
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
int32_t
...
...
@@ -101,10 +187,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
case
E1000_DEV_ID_82546EB_FIBER
:
hw
->
mac_type
=
e1000_82546
;
break
;
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
hw
->
mac_type
=
e1000_82541
;
break
;
case
E1000_DEV_ID_82547EI
:
hw
->
mac_type
=
e1000_82547
;
break
;
default:
/* Should never have loaded on this device */
return
-
E1000_ERR_MAC_TYPE
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
...
...
@@ -119,9 +214,10 @@ e1000_reset_hw(struct e1000_hw *hw)
uint32_t
ctrl_ext
;
uint32_t
icr
;
uint32_t
manc
;
uint32_t
led_ctrl
;
DEBUGFUNC
(
"e1000_reset_hw"
);
/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
if
(
hw
->
mac_type
==
e1000_82542_rev2_0
)
{
DEBUGOUT
(
"Disabling MWI on 82542 rev 2.0
\n
"
);
...
...
@@ -145,7 +241,7 @@ e1000_reset_hw(struct e1000_hw *hw)
/* Delay to allow any outstanding PCI transactions to complete before
* resetting the device
*/
*/
msec_delay
(
10
);
/* Issue a global reset to the MAC. This will reset the chip's
...
...
@@ -156,6 +252,12 @@ e1000_reset_hw(struct e1000_hw *hw)
DEBUGOUT
(
"Issuing a global reset to MAC
\n
"
);
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
/* Must reset the PHY before resetting the MAC */
if
((
hw
->
mac_type
==
e1000_82541
)
||
(
hw
->
mac_type
==
e1000_82547
))
{
E1000_WRITE_REG_IO
(
hw
,
CTRL
,
(
ctrl
|
E1000_CTRL_PHY_RST
));
msec_delay
(
5
);
}
if
(
hw
->
mac_type
>
e1000_82543
)
E1000_WRITE_REG_IO
(
hw
,
CTRL
,
(
ctrl
|
E1000_CTRL_RST
));
else
...
...
@@ -173,13 +275,25 @@ e1000_reset_hw(struct e1000_hw *hw)
msec_delay
(
2
);
}
else
{
/* Wait for EEPROM reload (it happens automatically) */
msec_delay
(
4
);
msec_delay
(
5
);
/* Dissable HW ARPs on ASF enabled adapters */
manc
=
E1000_READ_REG
(
hw
,
MANC
);
manc
&=
~
(
E1000_MANC_ARP_EN
);
E1000_WRITE_REG
(
hw
,
MANC
,
manc
);
}
if
((
hw
->
mac_type
==
e1000_82541
)
||
(
hw
->
mac_type
==
e1000_82547
))
{
e1000_phy_init_script
(
hw
);
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
}
/* Clear interrupt mask to stop board from generating interrupts */
DEBUGOUT
(
"Masking off all interrupts
\n
"
);
E1000_WRITE_REG
(
hw
,
IMC
,
0xffffffff
);
...
...
@@ -198,8 +312,8 @@ e1000_reset_hw(struct e1000_hw *hw)
* Performs basic configuration of the adapter.
*
* hw - Struct containing variables accessed by shared code
*
* Assumes that the controller has previously been reset and is in a
*
* Assumes that the controller has previously been reset and is in a
* post-reset uninitialized state. Initializes the receive address registers,
* multicast table, and VLAN filter table. Calls routines to setup link
* configuration and flow control settings. Clears all on-chip counters. Leaves
...
...
@@ -224,7 +338,7 @@ e1000_init_hw(struct e1000_hw *hw)
DEBUGOUT
(
"Error Initializing Identification LED
\n
"
);
return
ret_val
;
}
/* Set the Media Type and exit with error if it is not valid. */
if
(
hw
->
mac_type
!=
e1000_82543
)
{
/* tbi_compatibility is only valid on 82543 */
...
...
@@ -327,13 +441,13 @@ e1000_init_hw(struct e1000_hw *hw)
/******************************************************************************
* Configures flow control and link settings.
*
*
* hw - Struct containing variables accessed by shared code
*
*
* Determines which flow control settings to use. Calls the apropriate media-
* specific link configuration function. Configures the flow control settings.
* Assuming the adapter has a valid link partner, a valid link should be
* established. Assumes the hardware has previously been reset and the
* established. Assumes the hardware has previously been reset and the
* transmitter and receiver are not enabled.
*****************************************************************************/
int32_t
...
...
@@ -353,7 +467,7 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
if
(
e1000_read_eeprom
(
hw
,
EEPROM_INIT_CONTROL2_REG
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
EEPROM_INIT_CONTROL2_REG
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -361,7 +475,7 @@ e1000_setup_link(struct e1000_hw *hw)
if
(
hw
->
fc
==
e1000_fc_default
)
{
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
0
)
hw
->
fc
=
e1000_fc_none
;
else
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
else
if
((
eeprom_data
&
EEPROM_WORD0F_PAUSE_MASK
)
==
EEPROM_WORD0F_ASM_DIR
)
hw
->
fc
=
e1000_fc_tx_pause
;
else
...
...
@@ -390,7 +504,7 @@ e1000_setup_link(struct e1000_hw *hw)
* or e1000_phy_setup() is called.
*/
if
(
hw
->
mac_type
==
e1000_82543
)
{
ctrl_ext
=
((
eeprom_data
&
EEPROM_WORD0F_SWPDIO_EXT
)
<<
ctrl_ext
=
((
eeprom_data
&
EEPROM_WORD0F_SWPDIO_EXT
)
<<
SWDPIO__EXT_SHIFT
);
E1000_WRITE_REG
(
hw
,
CTRL_EXT
,
ctrl_ext
);
}
...
...
@@ -416,7 +530,7 @@ e1000_setup_link(struct e1000_hw *hw)
* these registers will be set to a default threshold that may be
* adjusted later by the driver's runtime code. However, if the
* ability to transmit pause frames in not enabled, then these
* registers will be set to 0.
* registers will be set to 0.
*/
if
(
!
(
hw
->
fc
&
e1000_fc_tx_pause
))
{
E1000_WRITE_REG
(
hw
,
FCRTL
,
0
);
...
...
@@ -445,7 +559,7 @@ e1000_setup_link(struct e1000_hw *hw)
* link. Assumes the hardware has been previously reset and the transmitter
* and receiver are not enabled.
*****************************************************************************/
static
int32_t
static
int32_t
e1000_setup_fiber_link
(
struct
e1000_hw
*
hw
)
{
uint32_t
ctrl
;
...
...
@@ -457,29 +571,29 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
DEBUGFUNC
(
"e1000_setup_fiber_link"
);
/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
/* On adapters with a MAC newer that 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
*/
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
if
(
hw
->
mac_type
>
e1000_82544
)
signal
=
E1000_CTRL_SWDPIN1
;
else
signal
=
0
;
/* Take the link out of reset */
ctrl
&=
~
(
E1000_CTRL_LRST
);
e1000_config_collision_dist
(
hw
);
/* Check for a software override of the flow control settings, and setup
* the device accordingly. If auto-negotiation is enabled, then software
* will have to set the "PAUSE" bits to the correct value in the Tranmsit
* Config Word Register (TXCW) and re-start auto-negotiation. However, if
* auto-negotiation is disabled, then software will have to manually
* auto-negotiation is disabled, then software will have to manually
* configure the two flow control enable bits in the CTRL register.
*
* The possible values of the "fc" parameter are:
* 0: Flow control is completely disabled
* 1: Rx flow control is enabled (we can receive pause frames, but
* 1: Rx flow control is enabled (we can receive pause frames, but
* not send pause frames).
* 2: Tx flow control is enabled (we can send pause frames but we do
* not support receiving pause frames).
...
...
@@ -491,8 +605,8 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
txcw
=
(
E1000_TXCW_ANE
|
E1000_TXCW_FD
);
break
;
case
e1000_fc_rx_pause
:
/* RX Flow control is enabled and TX Flow control is disabled by a
* software over-ride. Since there really isn't a way to advertise
/* RX Flow control is enabled and TX Flow control is disabled by a
* software over-ride. Since there really isn't a way to advertise
* that we are capable of RX Pause ONLY, we will advertise that we
* support both symmetric and asymmetric RX PAUSE. Later, we will
* disable the adapter's ability to send PAUSE frames.
...
...
@@ -500,7 +614,7 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
txcw
=
(
E1000_TXCW_ANE
|
E1000_TXCW_FD
|
E1000_TXCW_PAUSE_MASK
);
break
;
case
e1000_fc_tx_pause
:
/* TX Flow control is enabled, and RX Flow control is disabled, by a
/* TX Flow control is enabled, and RX Flow control is disabled, by a
* software over-ride.
*/
txcw
=
(
E1000_TXCW_ANE
|
E1000_TXCW_FD
|
E1000_TXCW_ASM_DIR
);
...
...
@@ -531,8 +645,8 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
msec_delay
(
1
);
/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
* indication in the Device Status Register. Time-out if a link isn't
* seen in 500 milliseconds seconds (Auto-negotiation should complete in
* indication in the Device Status Register. Time-out if a link isn't
* seen in 500 milliseconds seconds (Auto-negotiation should complete in
* less than 500 milliseconds even if the other end is doing it in SW).
*/
if
((
E1000_READ_REG
(
hw
,
CTRL
)
&
E1000_CTRL_SWDPIN1
)
==
signal
)
{
...
...
@@ -543,7 +657,7 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
if
(
status
&
E1000_STATUS_LU
)
break
;
}
if
(
i
==
(
LINK_UP_TIMEOUT
/
10
))
{
/* AutoNeg failed to achieve a link, so we'll call
/* AutoNeg failed to achieve a link, so we'll call
* e1000_check_for_link. This routine will force the link up if we
* detect a signal. This will allow us to communicate with
* non-autonegotiating link partners.
...
...
@@ -571,10 +685,10 @@ e1000_setup_fiber_link(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static
int32_t
static
int32_t
e1000_setup_copper_link
(
struct
e1000_hw
*
hw
)
{
uint32_t
ctrl
;
uint32_t
ctrl
,
led_ctrl
;
int32_t
ret_val
;
uint16_t
i
;
uint16_t
phy_data
;
...
...
@@ -604,80 +718,148 @@ e1000_setup_copper_link(struct e1000_hw *hw)
}
DEBUGOUT1
(
"Phy ID = %x
\n
"
,
hw
->
phy_id
);
/* Enable CRS on TX. This must be set for half-duplex operation. */
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_PSCR_ASSERT_CRS_ON_TX
;
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
/* Options:
* MDI/MDI-X = 0 (default)
* 0 - Auto for all speeds
* 1 - MDI mode
* 2 - MDI-X mode
* 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
*/
phy_data
&=
~
M88E1000_PSCR_AUTO_X_MODE
;
ret_val
=
e1000_phy_reset
(
hw
);
if
(
ret_val
<
0
)
{
DEBUGOUT
(
"Error Resetting the PHY
\n
"
);
return
ret_val
;
}
switch
(
hw
->
mdix
)
{
case
1
:
phy_data
|=
M88E1000_PSCR_MDI_MANUAL_MODE
;
break
;
case
2
:
phy_data
|=
M88E1000_PSCR_MDIX_MANUAL_MODE
;
break
;
case
3
:
phy_data
|=
M88E1000_PSCR_AUTO_X_1000T
;
break
;
case
0
:
default:
phy_data
|=
M88E1000_PSCR_AUTO_X_MODE
;
break
;
}
/* Wait 10ms for MAC to configure PHY from eeprom settings */
msec_delay
(
15
);
/* Options:
* disable_polarity_correction = 0 (default)
* Automatic Correction for Reversed Cable Polarity
* 0 - Disabled
* 1 - Enabled
*/
phy_data
&=
~
M88E1000_PSCR_POLARITY_REVERSAL
;
if
(
hw
->
disable_polarity_correction
==
1
)
phy_data
|=
M88E1000_PSCR_POLARITY_REVERSAL
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0000
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_EPSCR_TX_CLK_25
;
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
if
(
hw
->
autoneg_advertised
==
ADVERTISE_1000_FULL
)
{
/* Disable SmartSpeed */
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CONFIG
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
&=
~
IGP01E1000_PSCFR_SMART_SPEED
;
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CONFIG
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* Set auto Master/Slave resolution process */
if
(
e1000_read_phy_reg
(
hw
,
PHY_1000T_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
&=
~
CR_1000T_MS_ENABLE
;
if
(
e1000_write_phy_reg
(
hw
,
PHY_1000T_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
}
if
(
hw
->
phy_revision
<
M88E1011_I_REV_4
)
{
/* Configure Master and Slave downshift values */
phy_data
&=
~
(
M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK
|
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK
);
phy_data
|=
(
M88E1000_EPSCR_MASTER_DOWNSHIFT_1X
|
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X
);
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* Force MDI for IGP PHY */
phy_data
&=
~
(
IGP01E1000_PSCR_AUTO_MDIX
|
IGP01E1000_PSCR_FORCE_MDI_MDIX
);
hw
->
mdix
=
1
;
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
}
/* SW Reset the PHY so all changes take effect */
ret_val
=
e1000_phy_reset
(
hw
);
if
(
ret_val
<
0
)
{
DEBUGOUT
(
"Error Resetting the PHY
\n
"
);
return
ret_val
;
}
else
{
/* Enable CRS on TX. This must be set for half-duplex operation. */
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_PSCR_ASSERT_CRS_ON_TX
;
/* Options:
* MDI/MDI-X = 0 (default)
* 0 - Auto for all speeds
* 1 - MDI mode
* 2 - MDI-X mode
* 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
*/
phy_data
&=
~
M88E1000_PSCR_AUTO_X_MODE
;
switch
(
hw
->
mdix
)
{
case
1
:
phy_data
|=
M88E1000_PSCR_MDI_MANUAL_MODE
;
break
;
case
2
:
phy_data
|=
M88E1000_PSCR_MDIX_MANUAL_MODE
;
break
;
case
3
:
phy_data
|=
M88E1000_PSCR_AUTO_X_1000T
;
break
;
case
0
:
default:
phy_data
|=
M88E1000_PSCR_AUTO_X_MODE
;
break
;
}
/* Options:
* disable_polarity_correction = 0 (default)
* Automatic Correction for Reversed Cable Polarity
* 0 - Disabled
* 1 - Enabled
*/
phy_data
&=
~
M88E1000_PSCR_POLARITY_REVERSAL
;
if
(
hw
->
disable_polarity_correction
==
1
)
phy_data
|=
M88E1000_PSCR_POLARITY_REVERSAL
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_EPSCR_TX_CLK_25
;
if
(
hw
->
phy_revision
<
M88E1011_I_REV_4
)
{
/* Configure Master and Slave downshift values */
phy_data
&=
~
(
M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK
|
M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK
);
phy_data
|=
(
M88E1000_EPSCR_MASTER_DOWNSHIFT_1X
|
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X
);
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
}
/* SW Reset the PHY so all changes take effect */
ret_val
=
e1000_phy_reset
(
hw
);
if
(
ret_val
<
0
)
{
DEBUGOUT
(
"Error Resetting the PHY
\n
"
);
return
ret_val
;
}
}
/* Options:
* autoneg = 1 (default)
* PHY will advertise value(s) parsed from
...
...
@@ -736,6 +918,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
return
ret_val
;
}
}
hw
->
get_link_status
=
TRUE
;
}
else
{
DEBUGOUT
(
"Forcing speed and duplex
\n
"
);
ret_val
=
e1000_phy_force_speed_duplex
(
hw
);
...
...
@@ -1014,23 +1197,41 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
/* Write the configured values back to the Device Control Reg. */
E1000_WRITE_REG
(
hw
,
CTRL
,
ctrl
);
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
hw
->
phy_type
==
e1000_phy_m88
)
{
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed are duplex are forced.
*/
phy_data
&=
~
M88E1000_PSCR_AUTO_X_MODE
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
DEBUGOUT1
(
"M88E1000 PSCR: %x
\n
"
,
phy_data
);
/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed are duplex are forced.
*/
phy_data
&=
~
M88E1000_PSCR_AUTO_X_MODE
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
DEBUGOUT1
(
"M88E1000 PSCR: %x
\n
"
,
phy_data
);
/* Need to reset the PHY or these changes will be ignored */
mii_ctrl_reg
|=
MII_CR_RESET
;
/* Need to reset the PHY or these changes will be ignored */
mii_ctrl_reg
|=
MII_CR_RESET
;
}
else
{
/* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed or duplex are forced.
*/
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
&=
~
IGP01E1000_PSCR_AUTO_MDIX
;
phy_data
&=
~
IGP01E1000_PSCR_FORCE_MDI_MDIX
;
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
}
/* Write back the modified PHY MII control register. */
if
(
e1000_write_phy_reg
(
hw
,
PHY_CTRL
,
mii_ctrl_reg
)
<
0
)
{
...
...
@@ -1069,7 +1270,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
}
if
(
i
==
0
)
{
/* We didn't get link */
/* Reset the DSP and wait again for link. */
ret_val
=
e1000_phy_reset_dsp
(
hw
);
if
(
ret_val
<
0
)
{
DEBUGOUT
(
"Error Resetting PHY DSP
\n
"
);
...
...
@@ -1093,32 +1294,34 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
}
}
}
/* Because we reset the PHY above, we need to re-force TX_CLK in the
* Extended PHY Specific Control Register to 25MHz clock. This value
* defaults back to a 2.5MHz clock when the PHY is reset.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_EPSCR_TX_CLK_25
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* In addition, because of the s/w reset above, we need to enable CRS on
* TX. This must be set for both full and half duplex operation.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_PSCR_ASSERT_CRS_ON_TX
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
if
(
hw
->
phy_type
==
e1000_phy_m88
)
{
/* Because we reset the PHY above, we need to re-force TX_CLK in the
* Extended PHY Specific Control Register to 25MHz clock. This value
* defaults back to a 2.5MHz clock when the PHY is reset.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_EPSCR_TX_CLK_25
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_EXT_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
/* In addition, because of the s/w reset above, we need to enable CRS on
* TX. This must be set for both full and half duplex operation.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
phy_data
|=
M88E1000_PSCR_ASSERT_CRS_ON_TX
;
if
(
e1000_write_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
}
return
0
;
}
...
...
@@ -1136,6 +1339,8 @@ e1000_config_collision_dist(struct e1000_hw *hw)
{
uint32_t
tctl
;
DEBUGFUNC
(
"e1000_config_collision_dist"
);
tctl
=
E1000_READ_REG
(
hw
,
TCTL
);
tctl
&=
~
E1000_TCTL_COLD
;
...
...
@@ -1172,22 +1377,43 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
/* Set up duplex in the Device Control and Transmit Control
* registers depending on negotiated values.
*/
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
phy_data
&
M88E1000_PSSR_DPLX
)
ctrl
|=
E1000_CTRL_FD
;
else
ctrl
&=
~
E1000_CTRL_FD
;
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
phy_data
&
IGP01E1000_PSSR_FULL_DUPLEX
)
ctrl
|=
E1000_CTRL_FD
;
else
ctrl
&=
~
E1000_CTRL_FD
;
e1000_config_collision_dist
(
hw
);
e1000_config_collision_dist
(
hw
);
/* Set up speed in the Device Control register depending on
* negotiated values.
*/
if
((
phy_data
&
M88E1000_PSSR_SPEED
)
==
M88E1000_PSSR_1000MBS
)
ctrl
|=
E1000_CTRL_SPD_1000
;
else
if
((
phy_data
&
M88E1000_PSSR_SPEED
)
==
M88E1000_PSSR_100MBS
)
ctrl
|=
E1000_CTRL_SPD_100
;
/* Set up speed in the Device Control register depending on
* negotiated values.
*/
if
((
phy_data
&
IGP01E1000_PSSR_SPEED_MASK
)
==
IGP01E1000_PSSR_SPEED_1000MBPS
)
ctrl
|=
E1000_CTRL_SPD_1000
;
else
if
((
phy_data
&
IGP01E1000_PSSR_SPEED_MASK
)
==
IGP01E1000_PSSR_SPEED_100MBPS
)
ctrl
|=
E1000_CTRL_SPD_100
;
}
else
{
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
phy_data
&
M88E1000_PSSR_DPLX
)
ctrl
|=
E1000_CTRL_FD
;
else
ctrl
&=
~
E1000_CTRL_FD
;
e1000_config_collision_dist
(
hw
);
/* Set up speed in the Device Control register depending on
* negotiated values.
*/
if
((
phy_data
&
M88E1000_PSSR_SPEED
)
==
M88E1000_PSSR_1000MBS
)
ctrl
|=
E1000_CTRL_SPD_1000
;
else
if
((
phy_data
&
M88E1000_PSSR_SPEED
)
==
M88E1000_PSSR_100MBS
)
ctrl
|=
E1000_CTRL_SPD_100
;
}
/* Write the configured values back to the Device Control Reg. */
E1000_WRITE_REG
(
hw
,
CTRL
,
ctrl
);
return
0
;
...
...
@@ -1195,7 +1421,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
/******************************************************************************
* Forces the MAC's flow control settings.
*
*
* hw - Struct containing variables accessed by shared code
*
* Sets the TFCE and RFCE bits in the device control register to reflect
...
...
@@ -1262,7 +1488,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
/******************************************************************************
* Configures flow control settings after link is established
*
*
* hw - Struct containing variables accessed by shared code
*
* Should be called immediately after a valid link has been established.
...
...
@@ -1484,9 +1710,9 @@ e1000_check_for_link(struct e1000_hw *hw)
uint16_t
lp_capability
;
DEBUGFUNC
(
"e1000_check_for_link"
);
/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
* set when the optics detect a signal. On older adapters, it will be
/* On adapters with a MAC newer that 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
*/
if
(
hw
->
mac_type
>
e1000_82544
)
signal
=
E1000_CTRL_SWDPIN1
;
...
...
@@ -1519,6 +1745,10 @@ e1000_check_for_link(struct e1000_hw *hw)
if
(
phy_data
&
MII_SR_LINK_STATUS
)
{
hw
->
get_link_status
=
FALSE
;
/* Check if there was DownShift, must be checked immediately after
* link-up */
e1000_check_downshift
(
hw
);
}
else
{
/* No link detected */
return
0
;
...
...
@@ -1547,7 +1777,7 @@ e1000_check_for_link(struct e1000_hw *hw)
}
}
/* Configure Flow Control now that Auto-Neg has completed. First, we
/* Configure Flow Control now that Auto-Neg has completed. First, we
* need to restore the desired flow control settings because we may
* have had to re-autoneg with a different link partner.
*/
...
...
@@ -1576,7 +1806,7 @@ e1000_check_for_link(struct e1000_hw *hw)
NWAY_LPAR_100TX_HD_CAPS
|
NWAY_LPAR_100TX_FD_CAPS
|
NWAY_LPAR_100T4_CAPS
))
{
/* If our link partner advertises anything in addition to
/* If our link partner advertises anything in addition to
* gigabit, we do not need to enable TBI compatibility.
*/
if
(
hw
->
tbi_compatibility_on
)
{
...
...
@@ -1780,7 +2010,7 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
uint32_t
mask
;
/* We need to shift "count" number of bits out to the PHY. So, the value
* in the "data" parameter will be shifted out to the PHY one bit at a
* in the "data" parameter will be shifted out to the PHY one bit at a
* time. In order to do this, "data" must be broken down into bits.
*/
mask
=
0x01
;
...
...
@@ -1817,7 +2047,7 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
*
* hw - Struct containing variables accessed by shared code
*
* Bits are shifted in in MSB to LSB order.
* Bits are shifted in in MSB to LSB order.
******************************************************************************/
static
uint16_t
e1000_shift_in_mdi_bits
(
struct
e1000_hw
*
hw
)
...
...
@@ -1832,7 +2062,7 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
* These two bits are ignored by us and thrown away. Bits are "shifted in"
* by raising the input to the Management Data Clock (setting the MDC bit),
* and then reading the value of the MDIO bit.
*/
*/
ctrl
=
E1000_READ_REG
(
hw
,
CTRL
);
/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
...
...
@@ -1892,7 +2122,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
* PHY to retrieve the desired data.
*/
mdic
=
((
reg_addr
<<
E1000_MDIC_REG_SHIFT
)
|
(
phy_addr
<<
E1000_MDIC_PHY_SHIFT
)
|
(
phy_addr
<<
E1000_MDIC_PHY_SHIFT
)
|
(
E1000_MDIC_OP_READ
));
E1000_WRITE_REG
(
hw
,
MDIC
,
mdic
);
...
...
@@ -1930,7 +2160,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
* READ operation is performed. These two bits are thrown away
* followed by a shift in of 16 bits which contains the desired data.
*/
mdic
=
((
reg_addr
)
|
(
phy_addr
<<
5
)
|
mdic
=
((
reg_addr
)
|
(
phy_addr
<<
5
)
|
(
PHY_OP_READ
<<
10
)
|
(
PHY_SOF
<<
12
));
e1000_shift_out_mdi_bits
(
hw
,
mdic
,
14
);
...
...
@@ -1974,7 +2204,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
*/
mdic
=
(((
uint32_t
)
phy_data
)
|
(
reg_addr
<<
E1000_MDIC_REG_SHIFT
)
|
(
phy_addr
<<
E1000_MDIC_PHY_SHIFT
)
|
(
phy_addr
<<
E1000_MDIC_PHY_SHIFT
)
|
(
E1000_MDIC_OP_WRITE
));
E1000_WRITE_REG
(
hw
,
MDIC
,
mdic
);
...
...
@@ -1992,12 +2222,12 @@ e1000_write_phy_reg(struct e1000_hw *hw,
}
else
{
/* We'll need to use the SW defined pins to shift the write command
* out to the PHY. We first send a preamble to the PHY to signal the
* beginning of the MII instruction. This is done by sending 32
* beginning of the MII instruction. This is done by sending 32
* consecutive "1" bits.
*/
e1000_shift_out_mdi_bits
(
hw
,
PHY_PREAMBLE
,
PHY_PREAMBLE_SIZE
);
/* Now combine the remaining required fields that will indicate a
/* Now combine the remaining required fields that will indicate a
* write operation. We use this method instead of calling the
* e1000_shift_out_mdi_bits routine for each field in the command. The
* format of a MII write instruction is as follows:
...
...
@@ -2010,6 +2240,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
e1000_shift_out_mdi_bits
(
hw
,
mdic
,
32
);
}
return
0
;
}
...
...
@@ -2021,8 +2252,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
void
e1000_phy_hw_reset
(
struct
e1000_hw
*
hw
)
{
uint32_t
ctrl
;
uint32_t
ctrl_ext
;
uint32_t
ctrl
,
ctrl_ext
,
led_ctrl
;
DEBUGFUNC
(
"e1000_phy_hw_reset"
);
...
...
@@ -2053,6 +2283,21 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
E1000_WRITE_FLUSH
(
hw
);
}
udelay
(
150
);
if
((
hw
->
mac_type
==
e1000_82541
)
||
(
hw
->
mac_type
==
e1000_82547
))
{
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0000
)
<
0
)
{
DEBUGOUT
(
"PHY Write Error
\n
"
);
return
;
}
/* Configure activity LED after PHY reset */
led_ctrl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
led_ctrl
&=
IGP_ACTIVITY_LED_MASK
;
led_ctrl
|=
IGP_ACTIVITY_LED_ENABLE
;
if
(
hw
->
mac_type
==
e1000_82547
)
led_ctrl
|=
IGP_LED3_MODE
;
E1000_WRITE_REG
(
hw
,
LEDCTL
,
led_ctrl
);
}
}
/******************************************************************************
...
...
@@ -2079,6 +2324,9 @@ e1000_phy_reset(struct e1000_hw *hw)
return
-
E1000_ERR_PHY
;
}
udelay
(
1
);
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
e1000_phy_init_script
(
hw
);
}
return
0
;
}
...
...
@@ -2092,6 +2340,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
{
uint16_t
phy_id_high
,
phy_id_low
;
boolean_t
match
=
FALSE
;
int32_t
phy_init_status
;
DEBUGFUNC
(
"e1000_detect_gig_phy"
);
...
...
@@ -2101,7 +2350,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
return
-
E1000_ERR_PHY
;
}
hw
->
phy_id
=
(
uint32_t
)
(
phy_id_high
<<
16
);
udelay
(
2
);
udelay
(
2
0
);
if
(
e1000_read_phy_reg
(
hw
,
PHY_ID2
,
&
phy_id_low
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
...
...
@@ -2121,11 +2370,17 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
case
e1000_82546
:
if
(
hw
->
phy_id
==
M88E1011_I_PHY_ID
)
match
=
TRUE
;
break
;
case
e1000_82541
:
case
e1000_82547
:
if
(
hw
->
phy_id
==
IGP01E1000_I_PHY_ID
)
match
=
TRUE
;
break
;
default:
DEBUGOUT1
(
"Invalid MAC type %d
\n
"
,
hw
->
mac_type
);
return
-
E1000_ERR_CONFIG
;
}
if
(
match
)
{
phy_init_status
=
e1000_set_phy_type
(
hw
);
if
((
match
)
&&
(
phy_init_status
==
E1000_SUCCESS
))
{
DEBUGOUT1
(
"PHY ID 0x%X detected
\n
"
,
hw
->
phy_id
);
return
0
;
}
...
...
@@ -2143,7 +2398,7 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
{
int32_t
ret_val
=
-
E1000_ERR_PHY
;
DEBUGFUNC
(
"e1000_phy_reset_dsp"
);
do
{
if
(
e1000_write_phy_reg
(
hw
,
29
,
0x001d
)
<
0
)
break
;
if
(
e1000_write_phy_reg
(
hw
,
30
,
0x00c1
)
<
0
)
break
;
...
...
@@ -2156,74 +2411,177 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
}
/******************************************************************************
* Get PHY information from various PHY registers
* Get PHY information from various PHY registers
for igp PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
)
e1000_phy_igp_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
)
{
int32_t
ret_val
=
-
E1000_ERR_PHY
;
uint16_t
phy_data
;
uint16_t
phy_data
,
polarity
,
min_length
,
max_length
,
average
;
DEBUGFUNC
(
"e1000_phy_get_info"
);
DEBUGFUNC
(
"e1000_phy_
igp_
get_info"
);
phy_info
->
cable_length
=
e1000_cable_length_undefined
;
phy_info
->
extended_10bt_distance
=
e1000_10bt_ext_dist_enable_undefined
;
phy_info
->
cable_polarity
=
e1000_rev_polarity_undefined
;
phy_info
->
polarity_correction
=
e1000_polarity_reversal_undefined
;
phy_info
->
mdix_mode
=
e1000_auto_x_mode_undefined
;
phy_info
->
local_rx
=
e1000_1000t_rx_status_undefined
;
phy_info
->
remote_rx
=
e1000_1000t_rx_status_undefined
;
/* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */
phy_info
->
downshift
=
hw
->
speed_downgraded
;
if
(
hw
->
media_type
!=
e1000_media_type_copper
)
{
DEBUGOUT
(
"PHY info is only valid for copper media
\n
"
);
return
-
E1000_ERR_CONFIG
;
}
/* IGP01E1000 does not need to support it. */
phy_info
->
extended_10bt_distance
=
e1000_10bt_ext_dist_enable_normal
;
do
{
if
(
e1000_read_phy_reg
(
hw
,
PHY_STATUS
,
&
phy_data
)
<
0
)
break
;
if
(
e1000_read_phy_reg
(
hw
,
PHY_STATUS
,
&
phy_data
)
<
0
)
break
;
if
((
phy_data
&
MII_SR_LINK_STATUS
)
!=
MII_SR_LINK_STATUS
)
{
DEBUGOUT
(
"PHY info is only valid if link is up
\n
"
);
return
-
E1000_ERR_CONFIG
;
}
/* IGP01E1000 always correct polarity reversal */
phy_info
->
polarity_correction
=
e1000_polarity_reversal_enabled
;
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
break
;
phy_info
->
extended_10bt_distance
=
(
phy_data
&
M88E1000_PSCR_10BT_EXT_DIST_ENABLE
)
>>
M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT
;
phy_info
->
polarity_correction
=
(
phy_data
&
M88E1000_PSCR_POLARITY_REVERSAL
)
>>
M88E1000_PSCR_POLARITY_REVERSAL_SHIFT
;
/* Check polarity status */
if
(
e1000_check_polarity
(
hw
,
&
polarity
)
<
0
)
return
-
E1000_ERR_PHY
;
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
break
;
phy_info
->
cable_polarity
=
(
phy_data
&
M88E1000_PSSR_REV_POLARITY
)
>>
M88E1000_PSSR_REV_POLARITY_SHIFT
;
phy_info
->
mdix_mode
=
(
phy_data
&
M88E1000_PSSR_MDIX
)
>>
M88E1000_PSSR_MDIX_SHIFT
;
if
(
phy_data
&
M88E1000_PSSR_1000MBS
)
{
/* Cable Length Estimation and Local/Remote Receiver Informatoion
* are only valid at 1000 Mbps
*/
phy_info
->
cable_length
=
((
phy_data
&
M88E1000_PSSR_CABLE_LENGTH
)
>>
M88E1000_PSSR_CABLE_LENGTH_SHIFT
);
if
(
e1000_read_phy_reg
(
hw
,
PHY_1000T_STATUS
,
&
phy_data
)
<
0
)
break
;
phy_info
->
local_rx
=
(
phy_data
&
SR_1000T_LOCAL_RX_STATUS
)
>>
SR_1000T_LOCAL_RX_STATUS_SHIFT
;
phy_info
->
remote_rx
=
(
phy_data
&
SR_1000T_REMOTE_RX_STATUS
)
>>
SR_1000T_REMOTE_RX_STATUS_SHIFT
;
}
ret_val
=
0
;
}
while
(
0
);
phy_info
->
cable_polarity
=
polarity
;
if
(
ret_val
<
0
)
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
ret_val
;
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
mdix_mode
=
(
phy_data
&
IGP01E1000_PSSR_MDIX
)
>>
IGP01E1000_PSSR_MDIX_SHIFT
;
if
((
phy_data
&
IGP01E1000_PSSR_SPEED_MASK
)
==
IGP01E1000_PSSR_SPEED_1000MBPS
)
{
/* Local/Remote Receiver Information are only valid at 1000 Mbps */
if
(
e1000_read_phy_reg
(
hw
,
PHY_1000T_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
local_rx
=
(
phy_data
&
SR_1000T_LOCAL_RX_STATUS
)
>>
SR_1000T_LOCAL_RX_STATUS_SHIFT
;
phy_info
->
remote_rx
=
(
phy_data
&
SR_1000T_REMOTE_RX_STATUS
)
>>
SR_1000T_REMOTE_RX_STATUS_SHIFT
;
/* Get cable length */
if
(
e1000_get_cable_length
(
hw
,
&
min_length
,
&
max_length
)
<
0
)
return
-
E1000_ERR_PHY
;
/* transalte to old method */
average
=
(
max_length
+
min_length
)
/
2
;
if
(
average
<=
e1000_igp_cable_length_50
)
phy_info
->
cable_length
=
e1000_cable_length_50
;
else
if
(
average
<=
e1000_igp_cable_length_80
)
phy_info
->
cable_length
=
e1000_cable_length_50_80
;
else
if
(
average
<=
e1000_igp_cable_length_110
)
phy_info
->
cable_length
=
e1000_cable_length_80_110
;
else
if
(
average
<=
e1000_igp_cable_length_140
)
phy_info
->
cable_length
=
e1000_cable_length_110_140
;
else
phy_info
->
cable_length
=
e1000_cable_length_140
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* Get PHY information from various PHY registers fot m88 PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_m88_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
)
{
uint16_t
phy_data
,
polarity
;
DEBUGFUNC
(
"e1000_phy_m88_get_info"
);
/* The downshift status is checked only once, after link is established,
* and it stored in the hw->speed_downgraded parameter. */
phy_info
->
downshift
=
hw
->
speed_downgraded
;
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_CTRL
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
extended_10bt_distance
=
(
phy_data
&
M88E1000_PSCR_10BT_EXT_DIST_ENABLE
)
>>
M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT
;
phy_info
->
polarity_correction
=
(
phy_data
&
M88E1000_PSCR_POLARITY_REVERSAL
)
>>
M88E1000_PSCR_POLARITY_REVERSAL_SHIFT
;
/* Check polarity status */
if
(
e1000_check_polarity
(
hw
,
&
polarity
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
cable_polarity
=
polarity
;
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
mdix_mode
=
(
phy_data
&
M88E1000_PSSR_MDIX
)
>>
M88E1000_PSSR_MDIX_SHIFT
;
if
(
phy_data
&
M88E1000_PSSR_1000MBS
)
{
/* Cable Length Estimation and Local/Remote Receiver Informatoion
* are only valid at 1000 Mbps
*/
phy_info
->
cable_length
=
((
phy_data
&
M88E1000_PSSR_CABLE_LENGTH
)
>>
M88E1000_PSSR_CABLE_LENGTH_SHIFT
);
if
(
e1000_read_phy_reg
(
hw
,
PHY_1000T_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
phy_info
->
local_rx
=
(
phy_data
&
SR_1000T_LOCAL_RX_STATUS
)
>>
SR_1000T_LOCAL_RX_STATUS_SHIFT
;
phy_info
->
remote_rx
=
(
phy_data
&
SR_1000T_REMOTE_RX_STATUS
)
>>
SR_1000T_REMOTE_RX_STATUS_SHIFT
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* Get PHY information from various PHY registers
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
int32_t
e1000_phy_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
)
{
uint16_t
phy_data
;
DEBUGFUNC
(
"e1000_phy_get_info"
);
phy_info
->
cable_length
=
e1000_cable_length_undefined
;
phy_info
->
extended_10bt_distance
=
e1000_10bt_ext_dist_enable_undefined
;
phy_info
->
cable_polarity
=
e1000_rev_polarity_undefined
;
phy_info
->
downshift
=
e1000_downshift_undefined
;
phy_info
->
polarity_correction
=
e1000_polarity_reversal_undefined
;
phy_info
->
mdix_mode
=
e1000_auto_x_mode_undefined
;
phy_info
->
local_rx
=
e1000_1000t_rx_status_undefined
;
phy_info
->
remote_rx
=
e1000_1000t_rx_status_undefined
;
if
(
hw
->
media_type
!=
e1000_media_type_copper
)
{
DEBUGOUT
(
"PHY info is only valid for copper media
\n
"
);
return
-
E1000_ERR_CONFIG
;
}
if
(
e1000_read_phy_reg
(
hw
,
PHY_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
(
e1000_read_phy_reg
(
hw
,
PHY_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
if
((
phy_data
&
MII_SR_LINK_STATUS
)
!=
MII_SR_LINK_STATUS
)
{
DEBUGOUT
(
"PHY info is only valid if link is up
\n
"
);
return
-
E1000_ERR_CONFIG
;
}
if
(
hw
->
phy_type
==
e1000_phy_igp
)
return
e1000_phy_igp_get_info
(
hw
,
phy_info
);
else
return
e1000_phy_m88_get_info
(
hw
,
phy_info
);
}
int32_t
...
...
@@ -2239,6 +2597,109 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
return
0
;
}
/******************************************************************************
* Sets up eeprom variables in the hw struct. Must be called after mac_type
* is configured.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
void
e1000_init_eeprom_params
(
struct
e1000_hw
*
hw
)
{
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
uint16_t
eeprom_size
;
DEBUGFUNC
(
"e1000_init_eeprom_params"
);
switch
(
hw
->
mac_type
)
{
case
e1000_82542_rev2_0
:
case
e1000_82542_rev2_1
:
case
e1000_82543
:
case
e1000_82544
:
eeprom
->
type
=
e1000_eeprom_microwire
;
eeprom
->
word_size
=
64
;
eeprom
->
opcode_bits
=
3
;
eeprom
->
address_bits
=
6
;
eeprom
->
delay_usec
=
50
;
break
;
case
e1000_82540
:
case
e1000_82545
:
case
e1000_82546
:
eeprom
->
type
=
e1000_eeprom_microwire
;
eeprom
->
opcode_bits
=
3
;
eeprom
->
delay_usec
=
50
;
if
(
eecd
&
E1000_EECD_SIZE
)
{
eeprom
->
word_size
=
256
;
eeprom
->
address_bits
=
8
;
}
else
{
eeprom
->
word_size
=
64
;
eeprom
->
address_bits
=
6
;
}
break
;
case
e1000_82541
:
case
e1000_82547
:
default:
if
(
eecd
&
E1000_EECD_TYPE
)
{
eeprom
->
type
=
e1000_eeprom_spi
;
eeprom
->
opcode_bits
=
8
;
eeprom
->
delay_usec
=
1
;
if
(
eecd
&
E1000_EECD_ADDR_BITS
)
{
eeprom
->
page_size
=
32
;
eeprom
->
address_bits
=
16
;
}
else
{
eeprom
->
page_size
=
8
;
eeprom
->
address_bits
=
8
;
}
}
else
{
eeprom
->
type
=
e1000_eeprom_microwire
;
eeprom
->
opcode_bits
=
3
;
eeprom
->
delay_usec
=
50
;
if
(
eecd
&
E1000_EECD_ADDR_BITS
)
{
eeprom
->
word_size
=
256
;
eeprom
->
address_bits
=
8
;
}
else
{
eeprom
->
word_size
=
64
;
eeprom
->
address_bits
=
6
;
}
}
break
;
}
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
{
eeprom
->
word_size
=
64
;
if
(
e1000_read_eeprom
(
hw
,
EEPROM_CFG
,
1
,
&
eeprom_size
)
==
0
)
{
eeprom_size
&=
EEPROM_SIZE_MASK
;
switch
(
eeprom_size
)
{
case
EEPROM_SIZE_16KB
:
eeprom
->
word_size
=
8192
;
break
;
case
EEPROM_SIZE_8KB
:
eeprom
->
word_size
=
4096
;
break
;
case
EEPROM_SIZE_4KB
:
eeprom
->
word_size
=
2048
;
break
;
case
EEPROM_SIZE_2KB
:
eeprom
->
word_size
=
1024
;
break
;
case
EEPROM_SIZE_1KB
:
eeprom
->
word_size
=
512
;
break
;
case
EEPROM_SIZE_512B
:
eeprom
->
word_size
=
256
;
break
;
case
EEPROM_SIZE_128B
:
default:
eeprom
->
word_size
=
64
;
break
;
}
}
}
}
/******************************************************************************
* Raises the EEPROM's clock input.
*
...
...
@@ -2255,26 +2716,26 @@ e1000_raise_ee_clk(struct e1000_hw *hw,
*
eecd
=
*
eecd
|
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
*
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
udelay
(
hw
->
eeprom
.
delay_usec
);
}
/******************************************************************************
* Lowers the EEPROM's clock input.
*
* hw - Struct containing variables accessed by shared code
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
static
void
e1000_lower_ee_clk
(
struct
e1000_hw
*
hw
,
uint32_t
*
eecd
)
{
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
*/
*
eecd
=
*
eecd
&
~
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
*
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
udelay
(
hw
->
eeprom
.
delay_usec
);
}
/******************************************************************************
...
...
@@ -2289,16 +2750,21 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
uint16_t
data
,
uint16_t
count
)
{
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
eecd
;
uint32_t
mask
;
/* We need to shift "count" bits out to the EEPROM. So, value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
* In order to do this, "data" must be broken down into bits.
*/
mask
=
0x01
<<
(
count
-
1
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
eecd
&=
~
(
E1000_EECD_DO
|
E1000_EECD_DI
);
if
(
eeprom
->
type
==
e1000_eeprom_microwire
)
{
eecd
&=
~
E1000_EECD_DO
;
}
else
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
{
eecd
|=
E1000_EECD_DO
;
}
do
{
/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
* and then raising and then lowering the clock (the SK bit controls
...
...
@@ -2313,7 +2779,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
udelay
(
eeprom
->
delay_usec
);
e1000_raise_ee_clk
(
hw
,
&
eecd
);
e1000_lower_ee_clk
(
hw
,
&
eecd
);
...
...
@@ -2333,7 +2799,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static
uint16_t
e1000_shift_in_ee_bits
(
struct
e1000_hw
*
hw
)
e1000_shift_in_ee_bits
(
struct
e1000_hw
*
hw
,
uint16_t
count
)
{
uint32_t
eecd
;
uint32_t
i
;
...
...
@@ -2351,7 +2817,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
eecd
&=
~
(
E1000_EECD_DO
|
E1000_EECD_DI
);
data
=
0
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
count
;
i
++
)
{
data
=
data
<<
1
;
e1000_raise_ee_clk
(
hw
,
&
eecd
);
...
...
@@ -2372,104 +2838,196 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
*
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM.
*****************************************************************************/
static
void
e1000_
setup
_eeprom
(
struct
e1000_hw
*
hw
)
static
int32_t
e1000_
acquire
_eeprom
(
struct
e1000_hw
*
hw
)
{
uint32_t
eecd
;
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
eecd
,
i
=
0
;
DEBUGFUNC
(
"e1000_acquire_eeprom"
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
/* Clear SK and DI */
eecd
&=
~
(
E1000_EECD_SK
|
E1000_EECD_DI
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Request EEPROM Access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
|=
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
while
((
!
(
eecd
&
E1000_EECD_GNT
))
&&
(
i
<
E1000_EEPROM_GRANT_ATTEMPTS
))
{
i
++
;
udelay
(
5
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
}
if
(
!
(
eecd
&
E1000_EECD_GNT
))
{
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
DEBUGOUT
(
"Could not acquire EEPROM grant
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
}
/* Set CS */
eecd
|=
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Setup EEPROM for Read/Write */
if
(
eeprom
->
type
==
e1000_eeprom_microwire
)
{
/* Clear SK and DI */
eecd
&=
~
(
E1000_EECD_DI
|
E1000_EECD_SK
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Set CS */
eecd
|=
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
}
else
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
{
/* Clear SK and CS */
eecd
&=
~
(
E1000_EECD_CS
|
E1000_EECD_SK
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
udelay
(
1
);
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* Returns EEPROM to a "standby" state
*
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static
void
e1000_standby_eeprom
(
struct
e1000_hw
*
hw
)
{
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
eecd
;
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
/* Deselct EEPROM */
eecd
&=
~
(
E1000_EECD_CS
|
E1000_EECD_SK
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
if
(
eeprom
->
type
==
e1000_eeprom_microwire
)
{
eecd
&=
~
(
E1000_EECD_CS
|
E1000_EECD_SK
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
/* Clock high */
eecd
|=
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
/* Clock high */
eecd
|=
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
/* Select EEPROM */
eecd
|=
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
/* Select EEPROM */
eecd
|=
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
/* Clock low */
eecd
&=
~
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
/* Clock low */
eecd
&=
~
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
}
else
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
{
/* Toggle CS to flush commands */
eecd
|=
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
eecd
&=
~
E1000_EECD_CS
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
eeprom
->
delay_usec
);
}
}
/******************************************************************************
*
Raises then lowers the EEPROM's clock
pin
*
Terminates a command by inverting the EEPROM's chip select
pin
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static
void
e1000_
clock
_eeprom
(
struct
e1000_hw
*
hw
)
e1000_
release
_eeprom
(
struct
e1000_hw
*
hw
)
{
uint32_t
eecd
;
DEBUGFUNC
(
"e1000_release_eeprom"
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
/* Rising edge of clock */
eecd
|=
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
if
(
hw
->
eeprom
.
type
==
e1000_eeprom_spi
)
{
eecd
|=
E1000_EECD_CS
;
/* Pull CS high */
eecd
&=
~
E1000_EECD_SK
;
/* Lower SCK */
/* Falling edge of clock */
eecd
&=
~
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
50
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
udelay
(
hw
->
eeprom
.
delay_usec
);
}
else
if
(
hw
->
eeprom
.
type
==
e1000_eeprom_microwire
)
{
/* cleanup eeprom */
/* CS on Microwire is active-high */
eecd
&=
~
(
E1000_EECD_CS
|
E1000_EECD_DI
);
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Rising edge of clock */
eecd
|=
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
hw
->
eeprom
.
delay_usec
);
/* Falling edge of clock */
eecd
&=
~
E1000_EECD_SK
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
E1000_WRITE_FLUSH
(
hw
);
udelay
(
hw
->
eeprom
.
delay_usec
);
}
/* Stop requesting EEPROM access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
}
}
/******************************************************************************
*
Terminates a command by lowering the EEPROM's chip select pin
*
Reads a 16 bit word from the EEPROM.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
static
void
e1000_
cleanup_eeprom
(
struct
e1000_hw
*
hw
)
int32_t
e1000_
spi_eeprom_ready
(
struct
e1000_hw
*
hw
)
{
uint32_t
eecd
;
uint16_t
retry_count
=
0
;
uint8_t
spi_stat_reg
;
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
DEBUGFUNC
(
"e1000_spi_eeprom_ready"
);
eecd
&=
~
(
E1000_EECD_CS
|
E1000_EECD_DI
);
/* Read "Status Register" repeatedly until the LSB is cleared. The
* EEPROM will signal that the command has been completed by clearing
* bit 0 of the internal status register. If it's not cleared within
* 5 milliseconds, then error out.
*/
retry_count
=
0
;
do
{
e1000_shift_out_ee_bits
(
hw
,
EEPROM_RDSR_OPCODE_SPI
,
hw
->
eeprom
.
opcode_bits
);
spi_stat_reg
=
(
uint8_t
)
e1000_shift_in_ee_bits
(
hw
,
8
);
if
(
!
(
spi_stat_reg
&
EEPROM_STATUS_RDY_SPI
))
break
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
udelay
(
5
);
retry_count
+=
5
;
}
while
(
retry_count
<
EEPROM_MAX_RETRY_SPI
);
e1000_clock_eeprom
(
hw
);
/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
* only 0-5mSec on 5V devices)
*/
if
(
retry_count
>=
EEPROM_MAX_RETRY_SPI
)
{
DEBUGOUT
(
"SPI EEPROM Status error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
...
...
@@ -2477,71 +3035,76 @@ e1000_cleanup_eeprom(struct e1000_hw *hw)
*
* hw - Struct containing variables accessed by shared code
* offset - offset of word in the EEPROM to read
* data - word read from the EEPROM
* data - word read from the EEPROM
* words - number of words to read
*****************************************************************************/
int32_t
e1000_read_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
words
,
uint16_t
*
data
)
{
uint32_t
eecd
;
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
i
=
0
;
boolean_t
large_eeprom
=
FALSE
;
DEBUGFUNC
(
"e1000_read_eeprom"
);
/* Request EEPROM Access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
if
(
eecd
&
E1000_EECD_SIZE
)
large_eeprom
=
TRUE
;
eecd
|=
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
while
((
!
(
eecd
&
E1000_EECD_GNT
))
&&
(
i
<
100
))
{
i
++
;
udelay
(
5
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
}
if
(
!
(
eecd
&
E1000_EECD_GNT
))
{
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
DEBUGOUT
(
"Could not acquire EEPROM grant
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if
((
offset
>
eeprom
->
word_size
)
||
(
words
>
eeprom
->
word_size
-
offset
)
||
(
words
==
0
))
{
DEBUGOUT
(
"
\"
words
\"
parameter out of bounds
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
/* Prepare the EEPROM for reading */
e1000_setup_eeprom
(
hw
);
/* Prepare the EEPROM for reading */
if
(
e1000_acquire_eeprom
(
hw
)
!=
E1000_SUCCESS
)
return
-
E1000_ERR_EEPROM
;
/* Send the READ command (opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
EEPROM_READ_OPCODE
,
3
);
if
(
large_eeprom
)
{
/* If we have a 256 word EEPROM, there are 8 address bits */
e1000_shift_out_ee_bits
(
hw
,
offset
,
8
);
}
else
{
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits
(
hw
,
offset
,
6
);
}
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
{
uint8_t
read_opcode
=
EEPROM_READ_OPCODE_SPI
;
/* Read the data */
*
data
=
e1000_shift_in_ee_bits
(
hw
);
if
(
e1000_spi_eeprom_ready
(
hw
))
return
-
E1000_ERR_EEPROM
;
/* End this read operation */
e1000_standby_eeprom
(
hw
);
e1000_standby_eeprom
(
hw
);
/* Stop requesting EEPROM access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Some SPI eeproms use the 8th address bit embedded in the opcode */
if
((
eeprom
->
address_bits
==
8
)
&&
(
offset
>=
128
))
read_opcode
|=
EEPROM_A8_OPCODE_SPI
;
/* Send the READ command (opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
read_opcode
,
eeprom
->
opcode_bits
);
e1000_shift_out_ee_bits
(
hw
,
(
uint16_t
)(
offset
*
2
),
eeprom
->
address_bits
);
}
else
if
(
eeprom
->
type
==
e1000_eeprom_microwire
)
{
/* Send the READ command (opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
EEPROM_READ_OPCODE_MICROWIRE
,
eeprom
->
opcode_bits
);
e1000_shift_out_ee_bits
(
hw
,
offset
,
eeprom
->
address_bits
);
}
/* Read the data. The address of the eeprom internally increments with
* each word (microwire) or byte (spi) being read, saving on the overhead
* of eeprom setup and tear-down. The address counter will roll over if
* reading beyond the size of the eeprom, thus allowing the entire memory
* to be read starting from any offset. */
for
(
i
=
0
;
i
<
words
;
i
++
)
{
uint16_t
word_in
=
e1000_shift_in_ee_bits
(
hw
,
16
);
if
(
eeprom
->
type
==
e1000_eeprom_spi
)
word_in
=
(
word_in
>>
8
)
|
(
word_in
<<
8
);
data
[
i
]
=
word_in
;
}
/* End this read operation */
e1000_release_eeprom
(
hw
);
return
0
;
}
/******************************************************************************
* Verifies that the EEPROM has a valid checksum
*
*
* hw - Struct containing variables accessed by shared code
*
* Reads the first 64 16 bit words of the EEPROM and sums the values read.
...
...
@@ -2557,7 +3120,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC
(
"e1000_validate_eeprom_checksum"
);
for
(
i
=
0
;
i
<
(
EEPROM_CHECKSUM_REG
+
1
);
i
++
)
{
if
(
e1000_read_eeprom
(
hw
,
i
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
i
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -2567,7 +3130,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
if
(
checksum
==
(
uint16_t
)
EEPROM_SUM
)
{
return
0
;
}
else
{
DEBUGOUT
(
"EEPROM Checksum Invalid
\n
"
);
DEBUGOUT
(
"EEPROM Checksum Invalid
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
}
...
...
@@ -2589,14 +3152,14 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
DEBUGFUNC
(
"e1000_update_eeprom_checksum"
);
for
(
i
=
0
;
i
<
EEPROM_CHECKSUM_REG
;
i
++
)
{
if
(
e1000_read_eeprom
(
hw
,
i
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
i
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
checksum
+=
eeprom_data
;
}
checksum
=
(
uint16_t
)
EEPROM_SUM
-
checksum
;
if
(
e1000_write_eeprom
(
hw
,
EEPROM_CHECKSUM_REG
,
checksum
)
<
0
)
{
if
(
e1000_write_eeprom
(
hw
,
EEPROM_CHECKSUM_REG
,
1
,
&
checksum
)
<
0
)
{
DEBUGOUT
(
"EEPROM Write Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -2604,118 +3167,201 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
}
/******************************************************************************
*
Writes a 16 bit word to a given offset in the EEPROM
.
*
Parent function for writing words to the different EEPROM types
.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* data - 16 bit word to be writen to the EEPROM
* words - number of words to write
* data - 16 bit word to be written to the EEPROM
*
* If e1000_update_eeprom_checksum is not called after this function, the
* If e1000_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
*****************************************************************************/
int32_t
e1000_write_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
data
)
uint16_t
words
,
uint16_t
*
data
)
{
uint32_t
eecd
;
uint32_t
i
=
0
;
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
int32_t
status
=
0
;
boolean_t
large_eeprom
=
FALSE
;
DEBUGFUNC
(
"e1000_write_eeprom"
);
/* Request EEPROM Access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
if
(
eecd
&
E1000_EECD_SIZE
)
large_eeprom
=
TRUE
;
eecd
|=
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
while
((
!
(
eecd
&
E1000_EECD_GNT
))
&&
(
i
<
100
))
{
i
++
;
udelay
(
5
);
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
}
if
(
!
(
eecd
&
E1000_EECD_GNT
))
{
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
DEBUGOUT
(
"Could not acquire EEPROM grant
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
/* A check for invalid values: offset too large, too many words, and not
* enough words.
*/
if
((
offset
>
eeprom
->
word_size
)
||
(
words
>
eeprom
->
word_size
-
offset
)
||
(
words
==
0
))
{
DEBUGOUT
(
"
\"
words
\"
parameter out of bounds
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
/* Prepare the EEPROM for writing */
e1000_setup_eeprom
(
hw
);
if
(
e1000_acquire_eeprom
(
hw
)
!=
E1000_SUCCESS
)
return
-
E1000_ERR_EEPROM
;
/* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
* into write/erase mode.
*/
e1000_shift_out_ee_bits
(
hw
,
EEPROM_EWEN_OPCODE
,
5
);
if
(
large_eeprom
)
e1000_shift_out_ee_bits
(
hw
,
0
,
6
);
if
(
eeprom
->
type
==
e1000_eeprom_microwire
)
status
=
e1000_write_eeprom_microwire
(
hw
,
offset
,
words
,
data
);
else
e1000_shift_out_ee_bits
(
hw
,
0
,
4
);
status
=
e1000_write_eeprom_spi
(
hw
,
offset
,
words
,
data
);
/*
Prepare the EEPROM
*/
e1000_
standby
_eeprom
(
hw
);
/*
Done with writing
*/
e1000_
release
_eeprom
(
hw
);
/* Send the Write command (3-bit opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
EEPROM_WRITE_OPCODE
,
3
);
if
(
large_eeprom
)
/* If we have a 256 word EEPROM, there are 8 address bits */
e1000_shift_out_ee_bits
(
hw
,
offset
,
8
);
else
/* If we have a 64 word EEPROM, there are 6 address bits */
e1000_shift_out_ee_bits
(
hw
,
offset
,
6
);
return
status
;
}
/* Send the data */
e1000_shift_out_ee_bits
(
hw
,
data
,
16
);
/******************************************************************************
* Writes a 16 bit word to a given offset in an SPI EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* words - number of words to write
* data - pointer to array of 8 bit words to be written to the EEPROM
*
*****************************************************************************/
int32_t
e1000_write_eeprom_spi
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
words
,
uint16_t
*
data
)
{
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint16_t
widx
=
0
;
/* Toggle the CS line. This in effect tells to EEPROM to actually execute
* the command in question.
*/
e1000_standby_eeprom
(
hw
);
DEBUGFUNC
(
"e1000_write_eeprom_spi"
);
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for
(
i
=
0
;
i
<
200
;
i
++
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
if
(
eecd
&
E1000_EECD_DO
)
break
;
udelay
(
50
);
}
if
(
i
==
200
)
{
DEBUGOUT
(
"EEPROM Write did not complete
\n
"
);
status
=
-
E1000_ERR_EEPROM
;
while
(
widx
<
words
)
{
uint8_t
write_opcode
=
EEPROM_WRITE_OPCODE_SPI
;
if
(
e1000_spi_eeprom_ready
(
hw
))
return
-
E1000_ERR_EEPROM
;
e1000_standby_eeprom
(
hw
);
/* Send the WRITE ENABLE command (8 bit opcode ) */
e1000_shift_out_ee_bits
(
hw
,
EEPROM_WREN_OPCODE_SPI
,
eeprom
->
opcode_bits
);
e1000_standby_eeprom
(
hw
);
/* Some SPI eeproms use the 8th address bit embedded in the opcode */
if
((
eeprom
->
address_bits
==
8
)
&&
(
offset
>=
128
))
write_opcode
|=
EEPROM_A8_OPCODE_SPI
;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
write_opcode
,
eeprom
->
opcode_bits
);
e1000_shift_out_ee_bits
(
hw
,
(
uint16_t
)((
offset
+
widx
)
*
2
),
eeprom
->
address_bits
);
/* Send the data */
/* Loop to allow for up to whole page write (32 bytes) of eeprom */
while
(
widx
<
words
)
{
uint16_t
word_out
=
data
[
widx
];
word_out
=
(
word_out
>>
8
)
|
(
word_out
<<
8
);
e1000_shift_out_ee_bits
(
hw
,
word_out
,
16
);
widx
++
;
/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
* operation, while the smaller eeproms are capable of an 8-byte
* PAGE WRITE operation. Break the inner loop to pass new address
*/
if
((((
offset
+
widx
)
*
2
)
%
eeprom
->
page_size
)
==
0
)
{
e1000_standby_eeprom
(
hw
);
break
;
}
}
}
/* Recover from write */
e1000_standby_eeprom
(
hw
);
return
E1000_SUCCESS
;
}
/* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
* to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
* out of write/erase mode.
/******************************************************************************
* Writes a 16 bit word to a given offset in a Microwire EEPROM.
*
* hw - Struct containing variables accessed by shared code
* offset - offset within the EEPROM to be written to
* words - number of words to write
* data - pointer to array of 16 bit words to be written to the EEPROM
*
*****************************************************************************/
int32_t
e1000_write_eeprom_microwire
(
struct
e1000_hw
*
hw
,
uint16_t
offset
,
uint16_t
words
,
uint16_t
*
data
)
{
struct
e1000_eeprom_info
*
eeprom
=
&
hw
->
eeprom
;
uint32_t
eecd
;
uint16_t
words_written
=
0
;
uint16_t
i
=
0
;
DEBUGFUNC
(
"e1000_write_eeprom_microwire"
);
/* Send the write enable command to the EEPROM (3-bit opcode plus
* 6/8-bit dummy address beginning with 11). It's less work to include
* the 11 of the dummy address as part of the opcode than it is to shift
* it over the correct number of bits for the address. This puts the
* EEPROM into write/erase mode.
*/
e1000_shift_out_ee_bits
(
hw
,
EEPROM_EWDS_OPCODE
,
5
);
if
(
large_eeprom
)
e1000_shift_out_ee_bits
(
hw
,
0
,
6
);
else
e1000_shift_out_ee_bits
(
hw
,
0
,
4
);
e1000_shift_out_ee_bits
(
hw
,
EEPROM_EWEN_OPCODE_MICROWIRE
,
(
uint16_t
)(
eeprom
->
opcode_bits
+
2
));
/* Done with writing */
e1000_cleanup_eeprom
(
hw
);
e1000_shift_out_ee_bits
(
hw
,
0
,
(
uint16_t
)(
eeprom
->
address_bits
-
2
));
/* Stop requesting EEPROM access */
if
(
hw
->
mac_type
>
e1000_82544
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
eecd
&=
~
E1000_EECD_REQ
;
E1000_WRITE_REG
(
hw
,
EECD
,
eecd
);
/* Prepare the EEPROM */
e1000_standby_eeprom
(
hw
);
while
(
words_written
<
words
)
{
/* Send the Write command (3-bit opcode + addr) */
e1000_shift_out_ee_bits
(
hw
,
EEPROM_WRITE_OPCODE_MICROWIRE
,
eeprom
->
opcode_bits
);
e1000_shift_out_ee_bits
(
hw
,
(
uint16_t
)(
offset
+
words_written
),
eeprom
->
address_bits
);
/* Send the data */
e1000_shift_out_ee_bits
(
hw
,
data
[
words_written
],
16
);
/* Toggle the CS line. This in effect tells the EEPROM to execute
* the previous command.
*/
e1000_standby_eeprom
(
hw
);
/* Read DO repeatedly until it is high (equal to '1'). The EEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
for
(
i
=
0
;
i
<
200
;
i
++
)
{
eecd
=
E1000_READ_REG
(
hw
,
EECD
);
if
(
eecd
&
E1000_EECD_DO
)
break
;
udelay
(
50
);
}
if
(
i
==
200
)
{
DEBUGOUT
(
"EEPROM Write did not complete
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
/* Recover from write */
e1000_standby_eeprom
(
hw
);
words_written
++
;
}
return
status
;
/* Send the write disable command to the EEPROM (3-bit opcode plus
* 6/8-bit dummy address beginning with 10). It's less work to include
* the 10 of the dummy address as part of the opcode than it is to shift
* it over the correct number of bits for the address. This takes the
* EEPROM out of write/erase mode.
*/
e1000_shift_out_ee_bits
(
hw
,
EEPROM_EWDS_OPCODE_MICROWIRE
,
(
uint16_t
)(
eeprom
->
opcode_bits
+
2
));
e1000_shift_out_ee_bits
(
hw
,
0
,
(
uint16_t
)(
eeprom
->
address_bits
-
2
));
return
0
;
}
/******************************************************************************
...
...
@@ -2734,7 +3380,7 @@ e1000_read_part_num(struct e1000_hw *hw,
DEBUGFUNC
(
"e1000_read_part_num"
);
/* Get word 0 from EEPROM */
if
(
e1000_read_eeprom
(
hw
,
offset
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
offset
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -2742,7 +3388,7 @@ e1000_read_part_num(struct e1000_hw *hw,
*
part_num
=
(
uint32_t
)
(
eeprom_data
<<
16
);
/* Get word 1 from EEPROM */
if
(
e1000_read_eeprom
(
hw
,
++
offset
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
++
offset
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -2768,7 +3414,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
for
(
i
=
0
;
i
<
NODE_ADDRESS_SIZE
;
i
+=
2
)
{
offset
=
i
>>
1
;
if
(
e1000_read_eeprom
(
hw
,
offset
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
offset
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
...
...
@@ -2790,7 +3436,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
/******************************************************************************
* Initializes receive address filters.
*
* hw - Struct containing variables accessed by shared code
* hw - Struct containing variables accessed by shared code
*
* Places the MAC address in receive address register 0 and clears the rest
* of the receive addresss registers. Clears the multicast table. Assumes
...
...
@@ -2835,7 +3481,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
*
* The given list replaces any existing list. Clears the last 15 receive
* address registers and the multicast table. Uses receive address registers
* for the first 15 multicast addresses, and hashes the rest into the
* for the first 15 multicast addresses, and hashes the rest into the
* multicast table.
*****************************************************************************/
void
...
...
@@ -2884,7 +3530,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
DEBUGOUT1
(
" Hash value = 0x%03X
\n
"
,
hash_value
);
/* Place this multicast address in the RAR if there is room, *
* else put it in the MTA
* else put it in the MTA
*/
if
(
rar_used_count
<
E1000_RAR_ENTRIES
)
{
e1000_rar_set
(
hw
,
...
...
@@ -2902,7 +3548,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
* Hashes an address to determine its location in the multicast table
*
* hw - Struct containing variables accessed by shared code
* mc_addr - the multicast address to hash
* mc_addr - the multicast address to hash
*****************************************************************************/
uint32_t
e1000_hash_mc_addr
(
struct
e1000_hw
*
hw
,
...
...
@@ -2911,7 +3557,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
uint32_t
hash_value
=
0
;
/* The portion of the address that is used for the hash table is
* determined by the mc_filter_type setting.
* determined by the mc_filter_type setting.
*/
switch
(
hw
->
mc_filter_type
)
{
/* [0] [1] [2] [3] [4] [5]
...
...
@@ -2954,12 +3600,12 @@ e1000_mta_set(struct e1000_hw *hw,
uint32_t
mta
;
uint32_t
temp
;
/* The MTA is a register array of 128 32-bit registers.
* It is treated like an array of 4096 bits. We want to set
/* The MTA is a register array of 128 32-bit registers.
* It is treated like an array of 4096 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the
* upper 7 bits of the hash value and the bit within that
* back the new value. The register is determined by the
* upper 7 bits of the hash value and the bit within that
* register are determined by the lower 5 bits of the value.
*/
hash_reg
=
(
hash_value
>>
5
)
&
0x7F
;
...
...
@@ -2997,7 +3643,7 @@ e1000_rar_set(struct e1000_hw *hw,
uint32_t
rar_low
,
rar_high
;
/* HW expects these in little endian so we reverse the byte order
* from network order (big endian) to little endian
* from network order (big endian) to little endian
*/
rar_low
=
((
uint32_t
)
addr
[
0
]
|
((
uint32_t
)
addr
[
1
]
<<
8
)
|
...
...
@@ -3055,24 +3701,24 @@ e1000_id_led_init(struct e1000_hw * hw)
const
uint32_t
ledctl_off
=
E1000_LEDCTL_MODE_LED_OFF
;
uint16_t
eeprom_data
,
i
,
temp
;
const
uint16_t
led_mask
=
0x0F
;
DEBUGFUNC
(
"e1000_id_led_init"
);
if
(
hw
->
mac_type
<
e1000_82540
)
{
/* Nothing to do */
return
0
;
}
ledctl
=
E1000_READ_REG
(
hw
,
LEDCTL
);
hw
->
ledctl_default
=
ledctl
;
hw
->
ledctl_mode1
=
hw
->
ledctl_default
;
hw
->
ledctl_mode2
=
hw
->
ledctl_default
;
if
(
e1000_read_eeprom
(
hw
,
EEPROM_ID_LED_SETTINGS
,
&
eeprom_data
)
<
0
)
{
if
(
e1000_read_eeprom
(
hw
,
EEPROM_ID_LED_SETTINGS
,
1
,
&
eeprom_data
)
<
0
)
{
DEBUGOUT
(
"EEPROM Read Error
\n
"
);
return
-
E1000_ERR_EEPROM
;
}
if
((
eeprom_data
==
ID_LED_RESERVED_0000
)
||
if
((
eeprom_data
==
ID_LED_RESERVED_0000
)
||
(
eeprom_data
==
ID_LED_RESERVED_FFFF
))
eeprom_data
=
ID_LED_DEFAULT
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
temp
=
(
eeprom_data
>>
(
i
<<
2
))
&
led_mask
;
...
...
@@ -3123,9 +3769,9 @@ int32_t
e1000_setup_led
(
struct
e1000_hw
*
hw
)
{
uint32_t
ledctl
;
DEBUGFUNC
(
"e1000_setup_led"
);
switch
(
hw
->
device_id
)
{
case
E1000_DEV_ID_82542
:
case
E1000_DEV_ID_82543GC_FIBER
:
...
...
@@ -3143,7 +3789,7 @@ e1000_setup_led(struct e1000_hw *hw)
hw
->
ledctl_default
=
ledctl
;
/* Turn off LED0 */
ledctl
&=
~
(
E1000_LEDCTL_LED0_IVRT
|
E1000_LEDCTL_LED0_BLINK
|
E1000_LEDCTL_LED0_BLINK
|
E1000_LEDCTL_LED0_MODE_MASK
);
ledctl
|=
(
E1000_LEDCTL_MODE_LED_OFF
<<
E1000_LEDCTL_LED0_MODE_SHIFT
);
E1000_WRITE_REG
(
hw
,
LEDCTL
,
ledctl
);
...
...
@@ -3155,6 +3801,9 @@ e1000_setup_led(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
E1000_WRITE_REG
(
hw
,
LEDCTL
,
hw
->
ledctl_mode1
);
break
;
default:
...
...
@@ -3193,6 +3842,9 @@ e1000_cleanup_led(struct e1000_hw *hw)
case
E1000_DEV_ID_82545EM_FIBER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82546EB_FIBER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
/* Restore LEDCTL settings */
E1000_WRITE_REG
(
hw
,
LEDCTL
,
hw
->
ledctl_default
);
break
;
...
...
@@ -3202,7 +3854,7 @@ e1000_cleanup_led(struct e1000_hw *hw)
}
return
0
;
}
/******************************************************************************
* Turns on the software controllable LED
*
...
...
@@ -3244,6 +3896,9 @@ e1000_led_on(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
E1000_WRITE_REG
(
hw
,
LEDCTL
,
hw
->
ledctl_mode2
);
break
;
default:
...
...
@@ -3294,6 +3949,9 @@ e1000_led_off(struct e1000_hw *hw)
case
E1000_DEV_ID_82540EM_LOM
:
case
E1000_DEV_ID_82545EM_COPPER
:
case
E1000_DEV_ID_82546EB_COPPER
:
case
E1000_DEV_ID_82541EI
:
case
E1000_DEV_ID_82541EP
:
case
E1000_DEV_ID_82547EI
:
E1000_WRITE_REG
(
hw
,
LEDCTL
,
hw
->
ledctl_mode1
);
break
;
default:
...
...
@@ -3304,7 +3962,7 @@ e1000_led_off(struct e1000_hw *hw)
}
/******************************************************************************
* Clears all hardware statistics counters.
* Clears all hardware statistics counters.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
...
...
@@ -3423,7 +4081,7 @@ e1000_update_adaptive(struct e1000_hw *hw)
DEBUGFUNC
(
"e1000_update_adaptive"
);
if
(
hw
->
adaptive_ifs
)
{
if
((
hw
->
collision_delta
*
hw
->
ifs_ratio
)
>
if
((
hw
->
collision_delta
*
hw
->
ifs_ratio
)
>
hw
->
tx_packet_delta
)
{
if
(
hw
->
tx_packet_delta
>
MIN_NUM_XMITS
)
{
hw
->
in_ifs_mode
=
TRUE
;
...
...
@@ -3436,7 +4094,7 @@ e1000_update_adaptive(struct e1000_hw *hw)
}
}
}
else
{
if
((
hw
->
in_ifs_mode
==
TRUE
)
&&
if
((
hw
->
in_ifs_mode
==
TRUE
)
&&
(
hw
->
tx_packet_delta
<=
MIN_NUM_XMITS
))
{
hw
->
current_ifs_val
=
0
;
hw
->
in_ifs_mode
=
FALSE
;
...
...
@@ -3450,7 +4108,7 @@ e1000_update_adaptive(struct e1000_hw *hw)
/******************************************************************************
* Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
*
*
* hw - Struct containing variables accessed by shared code
* frame_len - The length of the frame in question
* mac_addr - The Ethernet destination address of the frame in question
...
...
@@ -3478,16 +4136,16 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
carry_bit
=
0x80000000
&
stats
->
gorcl
;
stats
->
gorcl
+=
frame_len
;
/* If the high bit of Gorcl (the low 32 bits of the Good Octets
* Received Count) was one before the addition,
* AND it is zero after, then we lost the carry out,
* Received Count) was one before the addition,
* AND it is zero after, then we lost the carry out,
* need to add one to Gorch (Good Octets Received Count High).
* This could be simplified if all environments supported
* This could be simplified if all environments supported
* 64-bit integers.
*/
if
(
carry_bit
&&
((
stats
->
gorcl
&
0x80000000
)
==
0
))
stats
->
gorch
++
;
/* Is this a broadcast or multicast? Check broadcast first,
* since the test for a multicast frame will test positive on
* since the test for a multicast frame will test positive on
* a broadcast frame.
*/
if
((
mac_addr
[
0
]
==
(
uint8_t
)
0xff
)
&&
(
mac_addr
[
1
]
==
(
uint8_t
)
0xff
))
...
...
@@ -3608,3 +4266,221 @@ e1000_write_reg_io(struct e1000_hw *hw,
e1000_io_write
(
hw
,
io_data
,
value
);
}
/******************************************************************************
* Estimates the cable length.
*
* hw - Struct containing variables accessed by shared code
* min_length - The estimated minimum length
* max_length - The estimated maximum length
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* This function always returns a ranged length (minimum & maximum).
* So for M88 phy's, this function interprets the one value returned from the
* register to the minimum and maximum range.
* For IGP phy's, the function calculates the range by the AGC registers.
*****************************************************************************/
int32_t
e1000_get_cable_length
(
struct
e1000_hw
*
hw
,
uint16_t
*
min_length
,
uint16_t
*
max_length
)
{
uint16_t
agc_value
=
0
;
uint16_t
cur_agc
,
min_agc
=
IGP01E1000_AGC_LENGTH_TABLE_SIZE
;
uint16_t
i
,
phy_data
;
DEBUGFUNC
(
"e1000_get_cable_length"
);
*
min_length
=
*
max_length
=
0
;
/* Use old method for Phy older than IGP */
if
(
hw
->
phy_type
==
e1000_phy_m88
)
{
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
/* Convert the enum value to ranged values */
switch
((
phy_data
&
M88E1000_PSSR_CABLE_LENGTH
)
>>
M88E1000_PSSR_CABLE_LENGTH_SHIFT
)
{
case
e1000_cable_length_50
:
*
min_length
=
0
;
*
max_length
=
e1000_igp_cable_length_50
;
break
;
case
e1000_cable_length_50_80
:
*
min_length
=
e1000_igp_cable_length_50
;
*
max_length
=
e1000_igp_cable_length_80
;
break
;
case
e1000_cable_length_80_110
:
*
min_length
=
e1000_igp_cable_length_80
;
*
max_length
=
e1000_igp_cable_length_110
;
break
;
case
e1000_cable_length_110_140
:
*
min_length
=
e1000_igp_cable_length_110
;
*
max_length
=
e1000_igp_cable_length_140
;
break
;
case
e1000_cable_length_140
:
*
min_length
=
e1000_igp_cable_length_140
;
*
max_length
=
e1000_igp_cable_length_170
;
break
;
default:
return
-
E1000_ERR_PHY
;
break
;
}
}
else
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
/* For IGP PHY */
uint16_t
agc_reg_array
[
IGP01E1000_PHY_AGC_NUM
]
=
{
IGP01E1000_PHY_AGC_A
,
IGP01E1000_PHY_AGC_B
,
IGP01E1000_PHY_AGC_C
,
IGP01E1000_PHY_AGC_D
};
/* Read the AGC registers for all channels */
for
(
i
=
0
;
i
<
IGP01E1000_PHY_AGC_NUM
;
i
++
)
{
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
agc_reg_array
[
i
])
!=
E1000_SUCCESS
)
return
-
E1000_ERR_PHY
;
if
(
e1000_read_phy_reg
(
hw
,
agc_reg_array
[
i
]
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
)
!=
E1000_SUCCESS
)
return
-
E1000_ERR_PHY
;
cur_agc
=
phy_data
>>
IGP01E1000_AGC_LENGTH_SHIFT
;
/* Array bound check. */
if
((
cur_agc
>=
IGP01E1000_AGC_LENGTH_TABLE_SIZE
-
1
)
||
(
cur_agc
==
0
))
return
-
E1000_ERR_PHY
;
agc_value
+=
cur_agc
;
/* Update minimal AGC value. */
if
(
min_agc
>
cur_agc
)
min_agc
=
cur_agc
;
}
/* Return to page 0 */
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0
)
!=
E1000_SUCCESS
)
return
-
E1000_ERR_PHY
;
/* Remove the minimal AGC result for length < 50m */
if
(
agc_value
<
IGP01E1000_PHY_AGC_NUM
*
e1000_igp_cable_length_50
)
{
agc_value
-=
min_agc
;
/* Get the average length of the remaining 3 channels */
agc_value
/=
(
IGP01E1000_PHY_AGC_NUM
-
1
);
}
else
{
/* Get the average length of all the 4 channels. */
agc_value
/=
IGP01E1000_PHY_AGC_NUM
;
}
/* Set the range of the calculated length. */
*
min_length
=
((
e1000_igp_cable_length_table
[
agc_value
]
-
IGP01E1000_AGC_RANGE
)
>
0
)
?
(
e1000_igp_cable_length_table
[
agc_value
]
-
IGP01E1000_AGC_RANGE
)
:
0
;
*
max_length
=
e1000_igp_cable_length_table
[
agc_value
]
+
IGP01E1000_AGC_RANGE
;
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* Check the cable polarity
*
* hw - Struct containing variables accessed by shared code
* polarity - output parameter : 0 - Polarity is not reversed
* 1 - Polarity is reversed.
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* For phy's older then IGP, this function simply reads the polarity bit in the
* Phy Status register. For IGP phy's, this bit is valid only if link speed is
* 10 Mbps. If the link speed is 100 Mbps there is no polarity so this bit will
* return 0. If the link speed is 1000 Mbps the polarity status is in the
* IGP01E1000_PHY_PCS_INIT_REG.
*****************************************************************************/
int32_t
e1000_check_polarity
(
struct
e1000_hw
*
hw
,
uint16_t
*
polarity
)
{
uint16_t
phy_data
;
DEBUGFUNC
(
"e1000_check_polarity"
);
if
(
hw
->
phy_type
==
e1000_phy_m88
)
{
/* return the Polarity bit in the Status register. */
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
*
polarity
=
(
phy_data
&
M88E1000_PSSR_REV_POLARITY
)
>>
M88E1000_PSSR_REV_POLARITY_SHIFT
;
}
else
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
/* Read the Status register to check the speed */
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PORT_STATUS
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
* find the polarity status */
if
((
phy_data
&
IGP01E1000_PSSR_SPEED_MASK
)
==
IGP01E1000_PSSR_SPEED_1000MBPS
)
{
/* Read the GIG initialization PCS register (0x00B4) */
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
IGP01E1000_PHY_PCS_INIT_REG
)
<
0
)
return
-
E1000_ERR_PHY
;
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_PCS_INIT_REG
&
IGP01E1000_PHY_PAGE_SELECT
,
&
phy_data
)
<
0
)
return
-
E1000_ERR_PHY
;
/* Return to page 0 */
if
(
e1000_write_phy_reg
(
hw
,
IGP01E1000_PHY_PAGE_SELECT
,
0x0
)
!=
E1000_SUCCESS
)
return
-
E1000_ERR_PHY
;
/* Check the polarity bits */
*
polarity
=
(
phy_data
&
IGP01E1000_PHY_POLARITY_MASK
)
?
1
:
0
;
}
else
{
/* For 10 Mbps, read the polarity bit in the status register. (for
* 100 Mbps this bit is always 0) */
*
polarity
=
phy_data
&
IGP01E1000_PSSR_POLARITY_REVERSED
;
}
}
return
E1000_SUCCESS
;
}
/******************************************************************************
* Check if Downshift occured
*
* hw - Struct containing variables accessed by shared code
* downshift - output parameter : 0 - No Downshift ocured.
* 1 - Downshift ocured.
*
* returns: E1000_SUCCESS / -E1000_ERR_XXX
*
* For phy's older then IGP, this function reads the Downshift bit in the Phy
* Specific Status register. For IGP phy's, it reads the Downgrade bit in the
* Link Health register. In IGP this bit is latched high, so the driver must
* read it immediately after link is established.
*****************************************************************************/
int32_t
e1000_check_downshift
(
struct
e1000_hw
*
hw
)
{
uint16_t
phy_data
;
DEBUGFUNC
(
"e1000_check_downshift"
);
if
(
hw
->
phy_type
==
e1000_phy_igp
)
{
if
(
e1000_read_phy_reg
(
hw
,
IGP01E1000_PHY_LINK_HEALTH
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
hw
->
speed_downgraded
=
(
phy_data
&
IGP01E1000_PLHR_SS_DOWNGRADE
)
?
1
:
0
;
}
else
if
(
hw
->
phy_type
==
e1000_phy_m88
)
{
if
(
e1000_read_phy_reg
(
hw
,
M88E1000_PHY_SPEC_STATUS
,
&
phy_data
)
<
0
)
{
DEBUGOUT
(
"PHY Read Error
\n
"
);
return
-
E1000_ERR_PHY
;
}
hw
->
speed_downgraded
=
(
phy_data
&
M88E1000_PSSR_DOWNSHIFT
)
>>
M88E1000_PSSR_DOWNSHIFT_SHIFT
;
}
return
E1000_SUCCESS
;
}
drivers/net/e1000/e1000_hw.h
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -33,6 +33,7 @@
#ifndef _E1000_HW_H_
#define _E1000_HW_H_
#include "e1000_osdep.h"
/* Forward declarations of structures used by the shared code */
...
...
@@ -50,9 +51,18 @@ typedef enum {
e1000_82540
,
e1000_82545
,
e1000_82546
,
e1000_82541
,
e1000_82547
,
e1000_num_macs
}
e1000_mac_type
;
typedef
enum
{
e1000_eeprom_uninitialized
=
0
,
e1000_eeprom_spi
,
e1000_eeprom_microwire
,
e1000_num_eeprom_types
}
e1000_eeprom_type
;
/* Media Types */
typedef
enum
{
e1000_media_type_copper
=
0
,
...
...
@@ -110,6 +120,27 @@ typedef enum {
e1000_cable_length_undefined
=
0xFF
}
e1000_cable_length
;
typedef
enum
{
e1000_igp_cable_length_10
=
10
,
e1000_igp_cable_length_20
=
20
,
e1000_igp_cable_length_30
=
30
,
e1000_igp_cable_length_40
=
40
,
e1000_igp_cable_length_50
=
50
,
e1000_igp_cable_length_60
=
60
,
e1000_igp_cable_length_70
=
70
,
e1000_igp_cable_length_80
=
80
,
e1000_igp_cable_length_90
=
90
,
e1000_igp_cable_length_100
=
100
,
e1000_igp_cable_length_110
=
110
,
e1000_igp_cable_length_120
=
120
,
e1000_igp_cable_length_130
=
130
,
e1000_igp_cable_length_140
=
140
,
e1000_igp_cable_length_150
=
150
,
e1000_igp_cable_length_160
=
160
,
e1000_igp_cable_length_170
=
170
,
e1000_igp_cable_length_180
=
180
}
e1000_igp_cable_length
;
typedef
enum
{
e1000_10bt_ext_dist_enable_normal
=
0
,
e1000_10bt_ext_dist_enable_lower
,
...
...
@@ -122,6 +153,12 @@ typedef enum {
e1000_rev_polarity_undefined
=
0xFF
}
e1000_rev_polarity
;
typedef
enum
{
e1000_downshift_normal
=
0
,
e1000_downshift_activated
,
e1000_downshift_undefined
=
0xFF
}
e1000_downshift
;
typedef
enum
{
e1000_polarity_reversal_enabled
=
0
,
e1000_polarity_reversal_disabled
,
...
...
@@ -142,10 +179,17 @@ typedef enum {
e1000_1000t_rx_status_undefined
=
0xFF
}
e1000_1000t_rx_status
;
typedef
enum
{
e1000_phy_m88
=
0
,
e1000_phy_igp
,
e1000_phy_undefined
=
0xFF
}
e1000_phy_type
;
struct
e1000_phy_info
{
e1000_cable_length
cable_length
;
e1000_10bt_ext_dist_enable
extended_10bt_distance
;
e1000_rev_polarity
cable_polarity
;
e1000_downshift
downshift
;
e1000_polarity_reversal
polarity_correction
;
e1000_auto_x_mode
mdix_mode
;
e1000_1000t_rx_status
local_rx
;
...
...
@@ -157,6 +201,15 @@ struct e1000_phy_stats {
uint32_t
receive_errors
;
};
struct
e1000_eeprom_info
{
e1000_eeprom_type
type
;
uint16_t
word_size
;
uint16_t
opcode_bits
;
uint16_t
address_bits
;
uint16_t
delay_usec
;
uint16_t
page_size
;
};
/* Error Codes */
...
...
@@ -166,6 +219,7 @@ struct e1000_phy_stats {
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_TYPE 5
#define E1000_ERR_PHY_TYPE 6
/* Function prototypes */
/* Initialization */
...
...
@@ -189,13 +243,19 @@ void e1000_phy_hw_reset(struct e1000_hw *hw);
int32_t
e1000_phy_reset
(
struct
e1000_hw
*
hw
);
int32_t
e1000_detect_gig_phy
(
struct
e1000_hw
*
hw
);
int32_t
e1000_phy_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
);
int32_t
e1000_phy_m88_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
);
int32_t
e1000_phy_igp_get_info
(
struct
e1000_hw
*
hw
,
struct
e1000_phy_info
*
phy_info
);
int32_t
e1000_get_cable_length
(
struct
e1000_hw
*
hw
,
uint16_t
*
min_length
,
uint16_t
*
max_length
);
int32_t
e1000_check_polarity
(
struct
e1000_hw
*
hw
,
uint16_t
*
polarity
);
int32_t
e1000_check_downshift
(
struct
e1000_hw
*
hw
);
int32_t
e1000_validate_mdi_setting
(
struct
e1000_hw
*
hw
);
/* EEPROM Functions */
int32_t
e1000_read_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
reg
,
uint16_t
*
data
);
void
e1000_init_eeprom_params
(
struct
e1000_hw
*
hw
);
int32_t
e1000_read_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
reg
,
uint16_t
words
,
uint16_t
*
data
);
int32_t
e1000_validate_eeprom_checksum
(
struct
e1000_hw
*
hw
);
int32_t
e1000_update_eeprom_checksum
(
struct
e1000_hw
*
hw
);
int32_t
e1000_write_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
reg
,
uint16_t
data
);
int32_t
e1000_write_eeprom
(
struct
e1000_hw
*
hw
,
uint16_t
reg
,
uint16_t
words
,
uint16_t
*
data
);
int32_t
e1000_read_part_num
(
struct
e1000_hw
*
hw
,
uint32_t
*
part_num
);
int32_t
e1000_read_mac_addr
(
struct
e1000_hw
*
hw
);
...
...
@@ -231,6 +291,7 @@ uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port);
uint32_t
e1000_read_reg_io
(
struct
e1000_hw
*
hw
,
uint32_t
offset
);
void
e1000_io_write
(
struct
e1000_hw
*
hw
,
uint32_t
port
,
uint32_t
value
);
void
e1000_write_reg_io
(
struct
e1000_hw
*
hw
,
uint32_t
offset
,
uint32_t
value
);
#define E1000_READ_REG_IO(a, reg) \
e1000_read_reg_io((a), E1000_##reg)
#define E1000_WRITE_REG_IO(a, reg, val) \
...
...
@@ -253,7 +314,10 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define NUM_DEV_IDS 16
#define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EP 0x1018
#define E1000_DEV_ID_82547EI 0x1019
#define NUM_DEV_IDS 19
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
...
...
@@ -298,7 +362,7 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
/* This defines the bits that are set in the Interrupt Mask
* Set/Read Register. Each bit is documented below:
* o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
* o RXSEQ = Receive Sequence Error
* o RXSEQ = Receive Sequence Error
*/
#define POLL_IMS_ENABLE_MASK ( \
E1000_IMS_RXDMT0 | \
...
...
@@ -322,9 +386,9 @@ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
/* The number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor. We
* reserve one of these spots for our directed address, allowing us room for
* E1000_RAR_ENTRIES - 1 multicast addresses.
* E1000_RAR_ENTRIES - 1 multicast addresses.
*/
#define E1000_RAR_ENTRIES 1
6
#define E1000_RAR_ENTRIES 1
5
#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
...
...
@@ -523,7 +587,7 @@ struct e1000_ffvt_entry {
/* Register Set. (82543, 82544)
*
* Registers are defined to be 32 bits and should be accessed as 32 bit values.
* These registers are physically located on the NIC, but are mapped into the
* These registers are physically located on the NIC, but are mapped into the
* host memory address space.
*
* RW - register is both readable and writable
...
...
@@ -537,6 +601,7 @@ struct e1000_ffvt_entry {
#define E1000_EECD 0x00010
/* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014
/* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018
/* Extended Device Control - RW */
#define E1000_FLA 0x0001C
/* Flash Access Register - RW */
#define E1000_MDIC 0x00020
/* MDI Control - RW */
#define E1000_FCAL 0x00028
/* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C
/* Flow Control Address High -RW */
...
...
@@ -569,6 +634,11 @@ struct e1000_ffvt_entry {
#define E1000_RADV 0x0282C
/* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD 0x02C00
/* RX Small Packet Detect - RW */
#define E1000_TXDMAC 0x03000
/* TX DMA Control - RW */
#define E1000_TDFH 0x03410
/* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418
/* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420
/* TX Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428
/* TX Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430
/* TX Data FIFO Packet Count - RW */
#define E1000_TDBAL 0x03800
/* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH 0x03804
/* TX Descriptor Base Address High - RW */
#define E1000_TDLEN 0x03808
/* TX Descriptor Length - RW */
...
...
@@ -664,6 +734,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_EECD E1000_EECD
#define E1000_82542_EERD E1000_EERD
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA E1000_FLA
#define E1000_82542_MDIC E1000_MDIC
#define E1000_82542_FCAL E1000_FCAL
#define E1000_82542_FCAH E1000_FCAH
...
...
@@ -705,6 +776,9 @@ struct e1000_ffvt_entry {
#define E1000_82542_RADV E1000_RADV
#define E1000_82542_RSRPD E1000_RSRPD
#define E1000_82542_TXDMAC E1000_TXDMAC
#define E1000_82542_TDFHS E1000_TDFHS
#define E1000_82542_TDFTS E1000_TDFTS
#define E1000_82542_TDFPC E1000_TDFPC
#define E1000_82542_TXDCTL E1000_TXDCTL
#define E1000_82542_TADV E1000_TADV
#define E1000_82542_TSPMT E1000_TSPMT
...
...
@@ -777,6 +851,8 @@ struct e1000_ffvt_entry {
#define E1000_82542_WUPL E1000_WUPL
#define E1000_82542_WUPM E1000_WUPM
#define E1000_82542_FFLT E1000_FFLT
#define E1000_82542_TDFH 0x08010
#define E1000_82542_TDFT 0x08018
#define E1000_82542_FFMT E1000_FFMT
#define E1000_82542_FFVT E1000_FFVT
...
...
@@ -846,12 +922,15 @@ struct e1000_hw_stats {
struct
e1000_hw
{
uint8_t
*
hw_addr
;
e1000_mac_type
mac_type
;
e1000_phy_type
phy_type
;
uint32_t
phy_init_script
;
e1000_media_type
media_type
;
void
*
back
;
e1000_fc_type
fc
;
e1000_bus_speed
bus_speed
;
e1000_bus_width
bus_width
;
e1000_bus_type
bus_type
;
struct
e1000_eeprom_info
eeprom
;
uint32_t
io_base
;
uint32_t
phy_id
;
uint32_t
phy_revision
;
...
...
@@ -891,6 +970,7 @@ struct e1000_hw {
uint8_t
mac_addr
[
NODE_ADDRESS_SIZE
];
uint8_t
perm_mac_addr
[
NODE_ADDRESS_SIZE
];
boolean_t
disable_polarity_correction
;
boolean_t
speed_downgraded
;
boolean_t
get_link_status
;
boolean_t
tbi_compatibility_en
;
boolean_t
tbi_compatibility_on
;
...
...
@@ -967,14 +1047,20 @@ struct e1000_hw {
#define E1000_EECD_CS 0x00000002
/* EEPROM Chip Select */
#define E1000_EECD_DI 0x00000004
/* EEPROM Data In */
#define E1000_EECD_DO 0x00000008
/* EEPROM Data Out */
#define E1000_EECD_FWE_MASK 0x00000030
#define E1000_EECD_FWE_MASK 0x00000030
#define E1000_EECD_FWE_DIS 0x00000010
/* Disable FLASH writes */
#define E1000_EECD_FWE_EN 0x00000020
/* Enable FLASH writes */
#define E1000_EECD_FWE_SHIFT 4
#define E1000_EECD_SIZE 0x00000200
/* EEPROM Size (0=64 word 1=256 word) */
#define E1000_EECD_REQ 0x00000040
/* EEPROM Access Request */
#define E1000_EECD_GNT 0x00000080
/* EEPROM Access Grant */
#define E1000_EECD_PRES 0x00000100
/* EEPROM Present */
#define E1000_EECD_SIZE 0x00000200
/* EEPROM Size (0=64 word 1=256 word) */
#define E1000_EECD_ADDR_BITS 0x00000400
/* EEPROM Addressing bits based on type
* (0-small, 1-large) */
#define E1000_EECD_TYPE 0x00002000
/* EEPROM Type (1-SPI, 0-Microwire) */
#ifndef E1000_EEPROM_GRANT_ATTEMPTS
#define E1000_EEPROM_GRANT_ATTEMPTS 1000
/* EEPROM # attempts to gain grant */
#endif
/* EEPROM Read */
#define E1000_EERD_START 0x00000001
/* Start Read */
...
...
@@ -984,8 +1070,15 @@ struct e1000_hw {
#define E1000_EERD_DATA_SHIFT 16
#define E1000_EERD_DATA_MASK 0xFFFF0000
/* Read Data */
/* SPI EEPROM Status Register */
#define EEPROM_STATUS_RDY_SPI 0x01
#define EEPROM_STATUS_WEN_SPI 0x02
#define EEPROM_STATUS_BP0_SPI 0x04
#define EEPROM_STATUS_BP1_SPI 0x08
#define EEPROM_STATUS_WPEN_SPI 0x80
/* Extended Device Control */
#define E1000_CTRL_EXT_GPI0_EN 0x00000001
/* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI0_EN 0x00000001
/* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI1_EN 0x00000002
/* Maps SDP5 to GPI1 */
#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
#define E1000_CTRL_EXT_GPI2_EN 0x00000004
/* Maps SDP6 to GPI2 */
...
...
@@ -1239,6 +1332,7 @@ struct e1000_hw {
#define E1000_WUC_PME_EN 0x00000002
/* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004
/* PME Status */
#define E1000_WUC_APMPME 0x00000008
/* Assert PME on APM Wakeup */
#define E1000_WUC_SPM 0x80000000
/* Enable SPM */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001
/* Link Status Change Wakeup Enable */
...
...
@@ -1282,7 +1376,7 @@ struct e1000_hw {
#define E1000_MANC_IPV6_EN 0x00000800
/* Enable IPv6 */
#define E1000_MANC_SNAP_EN 0x00001000
/* Accept LLC/SNAP */
#define E1000_MANC_ARP_EN 0x00002000
/* Enable ARP Request Filtering */
#define E1000_MANC_NEIGHBOR_EN 0x00004000
/* Enable Neighbor Discovery
#define E1000_MANC_NEIGHBOR_EN 0x00004000
/* Enable Neighbor Discovery
* Filtering */
#define E1000_MANC_TCO_RESET 0x00010000
/* TCO Reset Occurred */
#define E1000_MANC_RCV_TCO_EN 0x00020000
/* Receive TCO Packets Enabled */
...
...
@@ -1302,18 +1396,40 @@ struct e1000_hw {
#define E1000_MDALIGN 4096
/* EEPROM Commands */
#define EEPROM_READ_OPCODE 0x6
/* EERPOM read opcode */
#define EEPROM_WRITE_OPCODE 0x5
/* EERPOM write opcode */
#define EEPROM_ERASE_OPCODE 0x7
/* EERPOM erase opcode */
#define EEPROM_EWEN_OPCODE 0x13
/* EERPOM erase/write enable */
#define EEPROM_EWDS_OPCODE 0x10
/* EERPOM erast/write disable */
/* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE 0x6
/* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5
/* EEPROM write opcode */
#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7
/* EEPROM erase opcode */
#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13
/* EEPROM erase/write enable */
#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10
/* EEPROM erast/write disable */
/* EEPROM Commands - SPI */
#define EEPROM_MAX_RETRY_SPI 5000
/* Max wait of 5ms, for RDY signal */
#define EEPROM_READ_OPCODE_SPI 0x3
/* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_SPI 0x2
/* EEPROM write opcode */
#define EEPROM_A8_OPCODE_SPI 0x8
/* opcode bit-3 = address bit-8 */
#define EEPROM_WREN_OPCODE_SPI 0x6
/* EEPROM set Write Enable latch */
#define EEPROM_WRDI_OPCODE_SPI 0x4
/* EEPROM reset Write Enable latch */
#define EEPROM_RDSR_OPCODE_SPI 0x5
/* EEPROM read Status register */
#define EEPROM_WRSR_OPCODE_SPI 0x1
/* EEPROM write Status register */
/* EEPROM Size definitions */
#define EEPROM_SIZE_16KB 0x1800
#define EEPROM_SIZE_8KB 0x1400
#define EEPROM_SIZE_4KB 0x1000
#define EEPROM_SIZE_2KB 0x0C00
#define EEPROM_SIZE_1KB 0x0800
#define EEPROM_SIZE_512B 0x0400
#define EEPROM_SIZE_128B 0x0000
#define EEPROM_SIZE_MASK 0x1C00
/* EEPROM Word Offsets */
#define EEPROM_COMPAT 0x0003
#define EEPROM_ID_LED_SETTINGS 0x0004
#define EEPROM_INIT_CONTROL1_REG 0x000A
#define EEPROM_INIT_CONTROL2_REG 0x000F
#define EEPROM_CFG 0x0012
#define EEPROM_FLASH_VERSION 0x0032
#define EEPROM_CHECKSUM_REG 0x003F
...
...
@@ -1334,9 +1450,10 @@ struct e1000_hw {
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
/* Mask bits for fields in Word 0x03 of the EEPROM */
#define EEPROM_COMPAT_SERVER 0x0400
#define EEPROM_COMPAT_CLIENT 0x0200
#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE 0x07000000
/* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS 0x0010
...
...
@@ -1409,7 +1526,9 @@ struct e1000_hw {
/* PBA constants */
#define E1000_PBA_16K 0x0010
/* 16KB, default TX allocation */
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030
/* 48KB, default RX allocation */
...
...
@@ -1438,26 +1557,26 @@ struct e1000_hw {
/* The number of bits that we need to shift right to move the "pause"
* bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
* in the TXCW register
* in the TXCW register
*/
#define PAUSE_SHIFT 5
/* The number of bits that we need to shift left to move the "SWDPIO"
* bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
* in the CTRL register
* in the CTRL register
*/
#define SWDPIO_SHIFT 17
/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
* bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
* Extended CTRL register.
* in the CTRL register
* in the CTRL register
*/
#define SWDPIO__EXT_SHIFT 4
/* The number of bits that we need to shift left to move the "ILOS"
* bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
* in the CTRL register
* in the CTRL register
*/
#define ILOS_SHIFT 3
...
...
@@ -1475,7 +1594,7 @@ struct e1000_hw {
/* TBI_ACCEPT macro definition:
*
* This macro requires:
* adapter = a pointer to struct e1000_hw
* adapter = a pointer to struct e1000_hw
* status = the 8 bit status field of the RX descriptor with EOP set
* error = the 8 bit error field of the RX descriptor with EOP set
* length = the sum of all the length fields of the RX descriptors that
...
...
@@ -1484,7 +1603,7 @@ struct e1000_hw {
* max_frame_length = the maximum frame length we want to accept.
* min_frame_length = the minimum frame length we want to accept.
*
* This macro is a conditional that should be used in the interrupt
* This macro is a conditional that should be used in the interrupt
* handler's Rx processing routine when RxErrors have been detected.
*
* Typical use:
...
...
@@ -1547,6 +1666,29 @@ struct e1000_hw {
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14
/* Extended PHY Specific Control */
#define M88E1000_RX_ERR_CNTR 0x15
/* Receive Error Counter */
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10
/* PHY Specific Port Config Register */
#define IGP01E1000_PHY_PORT_STATUS 0x11
/* PHY Specific Status Register */
#define IGP01E1000_PHY_PORT_CTRL 0x12
/* PHY Specific Control Register */
#define IGP01E1000_PHY_LINK_HEALTH 0x13
/* PHY Link Health Register */
#define IGP01E1000_GMII_FIFO 0x14
/* GMII FIFO Register */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15
/* PHY Channel Quality Register */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F
/* PHY Page Select Core Register */
/* IGP01E1000 AGC Registers - stores the cable length values*/
#define IGP01E1000_PHY_AGC_A 0x1172
#define IGP01E1000_PHY_AGC_B 0x1272
#define IGP01E1000_PHY_AGC_C 0x1472
#define IGP01E1000_PHY_AGC_D 0x1872
/* Number of AGC registers */
#define IGP01E1000_PHY_AGC_NUM 4
/* IGP01E1000 PCS Initialization register - stores the polarity status when
* speed = 1000 Mbps. */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define MAX_PHY_REG_ADDRESS 0x1F
/* 5 bit address bus (0-0x1F) */
/* PHY Control Register */
...
...
@@ -1608,7 +1750,7 @@ struct e1000_hw {
#define NWAY_ER_PAGE_RXD 0x0002
/* LP is 10T Half Duplex Capable */
#define NWAY_ER_NEXT_PAGE_CAPS 0x0004
/* LP is 10T Full Duplex Capable */
#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008
/* LP is 100TX Half Duplex Capable */
#define NWAY_ER_PAR_DETECT_FAULT 0x0
10
0
/* LP is 100TX Full Duplex Capable */
#define NWAY_ER_PAR_DETECT_FAULT 0x0
01
0
/* LP is 100TX Full Duplex Capable */
/* Next Page TX Register */
#define NPTX_MSG_CODE_FIELD 0x0001
/* NP msg code or unformatted data */
...
...
@@ -1619,7 +1761,7 @@ struct e1000_hw {
* 0 = cannot comply with msg
*/
#define NPTX_MSG_PAGE 0x2000
/* formatted(1)/unformatted(0) pg */
#define NPTX_NEXT_PAGE 0x8000
/* 1 = addition NP will follow
#define NPTX_NEXT_PAGE 0x8000
/* 1 = addition NP will follow
* 0 = sending last NP
*/
...
...
@@ -1628,13 +1770,13 @@ struct e1000_hw {
#define LP_RNPR_TOGGLE 0x0800
/* Toggles between exchanges
* of different NP
*/
#define LP_RNPR_ACKNOWLDGE2 0x1000
/* 1 = will comply with msg
#define LP_RNPR_ACKNOWLDGE2 0x1000
/* 1 = will comply with msg
* 0 = cannot comply with msg
*/
#define LP_RNPR_MSG_PAGE 0x2000
/* formatted(1)/unformatted(0) pg */
#define LP_RNPR_ACKNOWLDGE 0x4000
/* 1 = ACK / 0 = NO ACK */
#define LP_RNPR_NEXT_PAGE 0x8000
/* 1 = addition NP will follow
* 0 = sending last NP
* 0 = sending last NP
*/
/* 1000BASE-T Control Register */
...
...
@@ -1681,20 +1823,20 @@ struct e1000_hw {
#define M88E1000_PSCR_JABBER_DISABLE 0x0001
/* 1=Jabber Function disabled */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002
/* 1=Polarity Reversal enabled */
#define M88E1000_PSCR_SQE_TEST 0x0004
/* 1=SQE Test enabled */
#define M88E1000_PSCR_CLK125_DISABLE 0x0010
/* 1=CLK125 low,
#define M88E1000_PSCR_CLK125_DISABLE 0x0010
/* 1=CLK125 low,
* 0=CLK125 toggling
*/
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000
/* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020
/* Manual MDIX configuration */
#define M88E1000_PSCR_AUTO_X_1000T 0x0040
/* 1000BASE-T: Auto crossover,
* 100BASE-TX/10BASE-T:
* 100BASE-TX/10BASE-T:
* MDI Mode
*/
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
/* Auto crossover enabled
* all speeds.
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
/* Auto crossover enabled
* all speeds.
*/
#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
/* 1=Enable Extended 10BASE-T distance
* (Lower 10BASE-T RX Threshold)
* 0=Normal 10BASE-T RX Threshold */
...
...
@@ -1712,6 +1854,7 @@ struct e1000_hw {
/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_JABBER 0x0001
/* 1=Jabber */
#define M88E1000_PSSR_REV_POLARITY 0x0002
/* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT 0x0020
/* 1=Downshifted */
#define M88E1000_PSSR_MDIX 0x0040
/* 1=MDIX; 0=MDI */
#define M88E1000_PSSR_CABLE_LENGTH 0x0380
/* 0=<50M;1=50-80M;2=80-110M;
* 3=110-140M;4=>140M */
...
...
@@ -1725,6 +1868,7 @@ struct e1000_hw {
#define M88E1000_PSSR_1000MBS 0x8000
/* 10=1000Mbs */
#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
#define M88E1000_PSSR_MDIX_SHIFT 6
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
...
...
@@ -1733,12 +1877,12 @@ struct e1000_hw {
#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000
/* 1=Lost lock detect enabled.
* Will assert lost lock and bring
* link down if idle not seen
* within 1ms in 1000BASE-T
* within 1ms in 1000BASE-T
*/
/* Number of times we will attempt to autonegotiate before downshifting if we
* are the master */
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00
...
...
@@ -1753,10 +1897,93 @@ struct e1000_hw {
#define M88E1000_EPSCR_TX_CLK_25 0x0070
/* 25 MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_0 0x0000
/* NO TX_CLK */
/* IGP01E1000 Specific Port Config Register - R/W */
#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
#define IGP01E1000_PSCFR_PRE_EN 0x0020
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100
#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400
#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000
/* IGP01E1000 Specific Port Status Register - R/O */
#define IGP01E1000_PSSR_AUTONEG_FAILED 0x0001
/* RO LH SC */
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_CABLE_LENGTH 0x007C
#define IGP01E1000_PSSR_FULL_DUPLEX 0x0200
#define IGP01E1000_PSSR_LINK_UP 0x0400
#define IGP01E1000_PSSR_MDIX 0x0800
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
/* speed bits mask */
#define IGP01E1000_PSSR_SPEED_10MBPS 0x4000
#define IGP01E1000_PSSR_SPEED_100MBPS 0x8000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT 0x0002
/* shift right 2 */
#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B
/* shift right 11 */
/* IGP01E1000 Specific Port Control Register - R/W */
#define IGP01E1000_PSCR_TP_LOOPBACK 0x0001
#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000
/* 0-MDI, 1-MDIX */
/* IGP01E1000 Specific Port Link Health Register */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
#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 0x0010
#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0008
#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0004
#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0002
#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0001
#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0000
/* IGP01E1000 Channel Quality Register */
#define IGP01E1000_MSE_CHANNEL_D 0x000F
#define IGP01E1000_MSE_CHANNEL_C 0x00F0
#define IGP01E1000_MSE_CHANNEL_B 0x0F00
#define IGP01E1000_MSE_CHANNEL_A 0xF000
/* IGP01E1000 AGC Registers */
#define IGP01E1000_AGC_LENGTH_SHIFT 7
/* Coarse - 13:11, Fine - 10:7 */
/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
/* The precision of the length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE 10
/* IGP cable length table */
static
const
uint16_t
e1000_igp_cable_length_table
[
IGP01E1000_AGC_LENGTH_TABLE_SIZE
]
=
{
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
10
,
10
,
10
,
10
,
10
,
10
,
10
,
20
,
20
,
20
,
20
,
20
,
25
,
25
,
25
,
25
,
25
,
25
,
25
,
30
,
30
,
30
,
30
,
40
,
40
,
40
,
40
,
40
,
40
,
40
,
40
,
40
,
50
,
50
,
50
,
50
,
50
,
50
,
50
,
60
,
60
,
60
,
60
,
60
,
60
,
60
,
60
,
60
,
70
,
70
,
70
,
70
,
70
,
70
,
80
,
80
,
80
,
80
,
80
,
80
,
90
,
90
,
90
,
90
,
90
,
90
,
90
,
90
,
90
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
100
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
110
,
120
,
120
,
120
,
120
,
120
,
120
,
120
,
120
,
120
,
120
};
/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
/* IGP01E1000 GMII FIFO Register */
#define IGP01E1000_GMII_FLEX_SPD 0x10
/* Enable flexible speed
* on Link-Up */
#define IGP01E1000_GMII_SPD 0x20
/* Enable SPD */
/* Bit definitions for valid PHY IDs. */
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
#define IGP01E1000_I_PHY_ID 0x02A80380
#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
#define M88E1011_I_REV_4 0x04
...
...
drivers/net/e1000/e1000_main.c
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -30,7 +30,22 @@
/* Change Log
*
* 4.4.19 11/27/02
* 5.0.43 3/5/03
* o Feature: Added support for 82541 and 82547 hardware.
* o Feature: Added support for Intel Gigabit PHY (IGP) and a variety of
* eeproms.
* o Feature: Added support for TCP Segmentation Offload (TSO).
* o Feature: Added MII ioctl.
* o Feature: Added support for statistics reporting through ethtool.
* o Cleanup: Removed proprietary hooks for ANS.
* o Cleanup: Miscellaneous code changes to improve CPU utilization.
* - Replaced "%" with conditionals and "+-" operators.
* - Implemented dynamic Interrupt Throttle Rate (ITR).
* - Reduced expensive PCI reads of ICR in interrupt.
* o Bug fix: Request IRQ after descriptor ring setup to avoid panic in
* shared interrupt instances.
*
* 4.4.18 11/27/02
* o Feature: Added user-settable knob for interrupt throttle rate (ITR).
* o Cleanup: removed large static array allocations.
* o Cleanup: C99 struct initializer format.
...
...
@@ -42,25 +57,12 @@
* o Bug fix: Make ethtool EEPROM acceses work on older versions of ethtool.
*
* 4.4.12 10/15/02
* o Clean up: use members of pci_device rather than direct calls to
* pci_read_config_word.
* o Bug fix: changed default flow control settings.
* o Clean up: ethtool file now has an inclusive list for adapters in the
* Wake-On-LAN capabilities instead of an exclusive list.
* o Bug fix: miscellaneous WoL bug fixes.
* o Added software interrupt for clearing rx ring
* o Bug fix: easier to undo "forcing" of 1000/fd using ethtool.
* o Now setting netdev->mem_end in e1000_probe.
* o Clean up: Moved tx_timeout from interrupt context to process context
* using schedule_task.
*
* 4.3.15 8/9/02
*/
char
e1000_driver_name
[]
=
"e1000"
;
char
e1000_driver_string
[]
=
"Intel(R) PRO/1000 Network Driver"
;
char
e1000_driver_version
[]
=
"
4.4.19-k3
"
;
char
e1000_copyright
[]
=
"Copyright (c) 1999-200
2
Intel Corporation."
;
char
e1000_driver_version
[]
=
"
5.0.43-k1
"
;
char
e1000_copyright
[]
=
"Copyright (c) 1999-200
3
Intel Corporation."
;
/* e1000_pci_tbl - PCI Device ID Table
*
...
...
@@ -104,6 +106,8 @@ static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
{
0x8086
,
0x1016
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1017
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x101E
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1013
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0x8086
,
0x1019
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
/* required last entry */
{
0
,}
};
...
...
@@ -112,7 +116,7 @@ MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
static
char
*
e1000_strings
[]
=
{
"Intel(R) PRO/1000 Network Connection"
,
"
Compaq
Gigabit Ethernet Server Adapter"
,
"
HP
Gigabit Ethernet Server Adapter"
,
"IBM Mobile, Desktop & Server Adapters"
};
...
...
@@ -121,6 +125,7 @@ static char *e1000_strings[] = {
int
e1000_up
(
struct
e1000_adapter
*
adapter
);
void
e1000_down
(
struct
e1000_adapter
*
adapter
);
void
e1000_reset
(
struct
e1000_adapter
*
adapter
);
int
e1000_set_spd_dplx
(
struct
e1000_adapter
*
adapter
,
uint16_t
spddplx
);
static
int
e1000_init_module
(
void
);
static
void
e1000_exit_module
(
void
);
...
...
@@ -141,6 +146,7 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter);
static
void
e1000_set_multi
(
struct
net_device
*
netdev
);
static
void
e1000_update_phy_info
(
unsigned
long
data
);
static
void
e1000_watchdog
(
unsigned
long
data
);
static
void
e1000_82547_tx_fifo_stall
(
unsigned
long
data
);
static
int
e1000_xmit_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
);
static
struct
net_device_stats
*
e1000_get_stats
(
struct
net_device
*
netdev
);
static
int
e1000_change_mtu
(
struct
net_device
*
netdev
,
int
new_mtu
);
...
...
@@ -149,14 +155,18 @@ static void e1000_update_stats(struct e1000_adapter *adapter);
static
inline
void
e1000_irq_disable
(
struct
e1000_adapter
*
adapter
);
static
inline
void
e1000_irq_enable
(
struct
e1000_adapter
*
adapter
);
static
void
e1000_intr
(
int
irq
,
void
*
data
,
struct
pt_regs
*
regs
);
static
void
e1000_clean_tx_irq
(
struct
e1000_adapter
*
adapter
);
#ifdef CONFIG_E1000_NAPI
static
int
e1000_poll
(
struct
net_device
*
netdev
,
int
*
budget
);
static
int
e1000_clean
(
struct
net_device
*
netdev
,
int
*
budget
);
static
boolean_t
e1000_clean_rx_irq
(
struct
e1000_adapter
*
adapter
,
int
*
work_done
,
int
work_to_do
);
#else
static
void
e1000_clean_rx_irq
(
struct
e1000_adapter
*
adapter
);
static
boolean_t
e1000_clean_rx_irq
(
struct
e1000_adapter
*
adapter
);
#endif
static
boolean_t
e1000_clean_tx_irq
(
struct
e1000_adapter
*
adapter
);
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
);
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
,
...
...
@@ -164,6 +174,9 @@ static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
struct
sk_buff
*
skb
);
static
void
e1000_tx_timeout
(
struct
net_device
*
dev
);
static
void
e1000_tx_timeout_task
(
struct
net_device
*
dev
);
static
void
e1000_smartspeed
(
struct
e1000_adapter
*
adapter
);
static
inline
int
e1000_82547_fifo_workaround
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
);
static
void
e1000_vlan_rx_register
(
struct
net_device
*
netdev
,
struct
vlan_group
*
grp
);
static
void
e1000_vlan_rx_add_vid
(
struct
net_device
*
netdev
,
uint16_t
vid
);
...
...
@@ -182,6 +195,7 @@ struct notifier_block e1000_notifier_reboot = {
.
priority
=
0
};
/* Exported from other modules */
extern
void
e1000_check_options
(
struct
e1000_adapter
*
adapter
);
...
...
@@ -249,13 +263,10 @@ e1000_up(struct e1000_adapter *adapter)
{
struct
net_device
*
netdev
=
adapter
->
netdev
;
if
(
request_irq
(
netdev
->
irq
,
&
e1000_intr
,
SA_SHIRQ
|
SA_SAMPLE_RANDOM
,
netdev
->
name
,
netdev
))
return
-
1
;
/* hardware has been reset, we need to reload some things */
e1000_set_multi
(
netdev
);
e1000_restore_vlan
(
adapter
);
e1000_configure_tx
(
adapter
);
...
...
@@ -263,6 +274,14 @@ e1000_up(struct e1000_adapter *adapter)
e1000_configure_rx
(
adapter
);
e1000_alloc_rx_buffers
(
adapter
);
if
(
request_irq
(
netdev
->
irq
,
&
e1000_intr
,
SA_SHIRQ
|
SA_SAMPLE_RANDOM
,
netdev
->
name
,
netdev
))
{
e1000_reset_hw
(
&
adapter
->
hw
);
e1000_free_tx_resources
(
adapter
);
e1000_free_rx_resources
(
adapter
);
return
-
1
;
}
mod_timer
(
&
adapter
->
watchdog_timer
,
jiffies
);
e1000_irq_enable
(
adapter
);
...
...
@@ -276,6 +295,7 @@ e1000_down(struct e1000_adapter *adapter)
e1000_irq_disable
(
adapter
);
free_irq
(
netdev
->
irq
,
netdev
);
del_timer_sync
(
&
adapter
->
tx_fifo_stall_timer
);
del_timer_sync
(
&
adapter
->
watchdog_timer
);
del_timer_sync
(
&
adapter
->
phy_info_timer
);
adapter
->
link_speed
=
0
;
...
...
@@ -291,14 +311,28 @@ e1000_down(struct e1000_adapter *adapter)
void
e1000_reset
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
pba
;
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
if
(
adapter
->
rx_buffer_len
>
E1000_RXBUFFER_8192
)
E1000_WRITE_REG
(
&
adapter
->
hw
,
PBA
,
E1000_JUMBO_PBA
);
else
E1000_WRITE_REG
(
&
adapter
->
hw
,
PBA
,
E1000_DEFAULT_PBA
);
if
(
adapter
->
hw
.
mac_type
<
e1000_82547
)
{
if
(
adapter
->
rx_buffer_len
>
E1000_RXBUFFER_8192
)
pba
=
E1000_PBA_40K
;
else
pba
=
E1000_PBA_48K
;
}
else
{
if
(
adapter
->
rx_buffer_len
>
E1000_RXBUFFER_8192
)
pba
=
E1000_PBA_22K
;
else
pba
=
E1000_PBA_30K
;
adapter
->
tx_fifo_head
=
0
;
adapter
->
tx_head_addr
=
pba
<<
E1000_TX_HEAD_ADDR_SHIFT
;
adapter
->
tx_fifo_size
=
(
E1000_PBA_40K
-
pba
)
<<
E1000_TX_FIFO_SIZE_SHIFT
;
atomic_set
(
&
adapter
->
tx_fifo_stall
,
0
);
}
E1000_WRITE_REG
(
&
adapter
->
hw
,
PBA
,
pba
);
adapter
->
hw
.
fc
=
adapter
->
hw
.
original_fc
;
e1000_reset_hw
(
&
adapter
->
hw
);
...
...
@@ -389,9 +423,9 @@ e1000_probe(struct pci_dev *pdev,
netdev
->
change_mtu
=
&
e1000_change_mtu
;
netdev
->
do_ioctl
=
&
e1000_ioctl
;
netdev
->
tx_timeout
=
&
e1000_tx_timeout
;
netdev
->
watchdog_timeo
=
HZ
;
netdev
->
watchdog_timeo
=
5
*
HZ
;
#ifdef CONFIG_E1000_NAPI
netdev
->
poll
=
&
e1000_
poll
;
netdev
->
poll
=
&
e1000_
clean
;
netdev
->
weight
=
64
;
#endif
netdev
->
vlan_rx_register
=
e1000_vlan_rx_register
;
...
...
@@ -413,17 +447,18 @@ e1000_probe(struct pci_dev *pdev,
if
(
adapter
->
hw
.
mac_type
>=
e1000_82543
)
{
netdev
->
features
=
NETIF_F_SG
|
NETIF_F_HW_CSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
|
NETIF_F_HW_CSUM
|
NETIF_F_HW_VLAN_TX
|
NETIF_F_HW_VLAN_RX
|
NETIF_F_HW_VLAN_FILTER
;
}
else
{
netdev
->
features
=
NETIF_F_SG
;
}
if
(
adapter
->
hw
.
mac_type
>=
e1000_82544
)
if
((
adapter
->
hw
.
mac_type
>=
e1000_82544
)
&&
(
adapter
->
hw
.
mac_type
!=
e1000_82547
))
netdev
->
features
|=
NETIF_F_TSO
;
if
(
pci_using_dac
)
netdev
->
features
|=
NETIF_F_HIGHDMA
;
...
...
@@ -446,13 +481,9 @@ e1000_probe(struct pci_dev *pdev,
e1000_get_bus_info
(
&
adapter
->
hw
);
if
((
adapter
->
hw
.
mac_type
==
e1000_82544
)
&&
(
adapter
->
hw
.
bus_type
==
e1000_bus_type_pcix
))
adapter
->
max_data_per_txd
=
4096
;
else
adapter
->
max_data_per_txd
=
MAX_JUMBO_FRAME_SIZE
;
init_timer
(
&
adapter
->
tx_fifo_stall_timer
);
adapter
->
tx_fifo_stall_timer
.
function
=
&
e1000_82547_tx_fifo_stall
;
adapter
->
tx_fifo_stall_timer
.
data
=
(
unsigned
long
)
adapter
;
init_timer
(
&
adapter
->
watchdog_timer
);
adapter
->
watchdog_timer
.
function
=
&
e1000_watchdog
;
...
...
@@ -482,11 +513,12 @@ e1000_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter
*/
e1000_read_eeprom
(
&
adapter
->
hw
,
EEPROM_INIT_CONTROL2_REG
,
&
eeprom_data
);
e1000_read_eeprom
(
&
adapter
->
hw
,
EEPROM_INIT_CONTROL2_REG
,
1
,
&
eeprom_data
);
if
((
adapter
->
hw
.
mac_type
>=
e1000_82544
)
&&
(
eeprom_data
&
E1000_EEPROM_APME
))
adapter
->
wol
|=
E1000_WUFC_MAG
;
/* reset the hardware with the new settings */
e1000_reset
(
adapter
);
...
...
@@ -533,6 +565,7 @@ e1000_remove(struct pci_dev *pdev)
e1000_phy_hw_reset
(
&
adapter
->
hw
);
iounmap
(
adapter
->
hw
.
hw_addr
);
pci_release_regions
(
pdev
);
...
...
@@ -568,7 +601,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
adapter
->
rx_buffer_len
=
E1000_RXBUFFER_2048
;
hw
->
max_frame_size
=
netdev
->
mtu
+
ENET_HEADER_SIZE
+
ETHERNET_FCS_SIZE
;
ENET_HEADER_SIZE
+
ETHERNET_FCS_SIZE
;
hw
->
min_frame_size
=
MINIMUM_ETHERNET_FRAME_SIZE
;
/* identify the MAC */
...
...
@@ -578,6 +611,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
return
-
1
;
}
/* initialize eeprom parameters */
e1000_init_eeprom_params
(
hw
);
/* flow control settings */
hw
->
fc_high_water
=
E1000_FC_HIGH_THRESH
;
...
...
@@ -585,6 +622,9 @@ e1000_sw_init(struct e1000_adapter *adapter)
hw
->
fc_pause_time
=
E1000_FC_PAUSE_TIME
;
hw
->
fc_send_xon
=
1
;
if
((
hw
->
mac_type
==
e1000_82541
)
||
(
hw
->
mac_type
==
e1000_82547
))
hw
->
phy_init_script
=
1
;
/* Media type - copper or fiber */
if
(
hw
->
mac_type
>=
e1000_82543
)
{
...
...
@@ -782,7 +822,7 @@ e1000_configure_tx(struct e1000_adapter *adapter)
tctl
&=
~
E1000_TCTL_CT
;
tctl
|=
E1000_TCTL_EN
|
E1000_TCTL_PSP
|
(
E1000_COLLISION_THRESHOLD
<<
E1000_CT_SHIFT
);
(
E1000_COLLISION_THRESHOLD
<<
E1000_CT_SHIFT
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
tctl
);
...
...
@@ -852,8 +892,8 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
rctl
&=
~
(
3
<<
E1000_RCTL_MO_SHIFT
);
rctl
|=
E1000_RCTL_EN
|
E1000_RCTL_BAM
|
E1000_RCTL_LBM_NO
|
E1000_RCTL_RDMTS_HALF
|
(
adapter
->
hw
.
mc_filter_type
<<
E1000_RCTL_MO_SHIFT
);
E1000_RCTL_LBM_NO
|
E1000_RCTL_RDMTS_HALF
|
(
adapter
->
hw
.
mc_filter_type
<<
E1000_RCTL_MO_SHIFT
);
if
(
adapter
->
hw
.
tbi_compatibility_on
==
1
)
rctl
|=
E1000_RCTL_SBP
;
...
...
@@ -907,12 +947,9 @@ e1000_configure_rx(struct e1000_adapter *adapter)
if
(
adapter
->
hw
.
mac_type
>=
e1000_82540
)
{
E1000_WRITE_REG
(
&
adapter
->
hw
,
RADV
,
adapter
->
rx_abs_int_delay
);
/* Set the interrupt throttling rate. Value is calculated
* as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
#define MAX_INTS_PER_SEC 8000
#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256)
E1000_WRITE_REG
(
&
adapter
->
hw
,
ITR
,
DEFAULT_ITR
);
if
(
adapter
->
itr
>
1
)
E1000_WRITE_REG
(
&
adapter
->
hw
,
ITR
,
1000000000
/
(
adapter
->
itr
*
256
));
}
/* Setup the Base and Length of the Rx Descriptor Ring */
...
...
@@ -1184,9 +1221,9 @@ e1000_set_multi(struct net_device *netdev)
if
(
hw
->
mac_type
==
e1000_82542_rev2_0
)
e1000_enter_82542_rst
(
adapter
);
/* load the first 1
5 multicast address into the exact filters 1-15
/* load the first 1
4 multicast address into the exact filters 1-14
* RAR 0 is used for the station MAC adddress
* if there are not 1
5
addresses, go ahead and clear the filters
* if there are not 1
4
addresses, go ahead and clear the filters
*/
mc_ptr
=
netdev
->
mc_list
;
...
...
@@ -1216,6 +1253,40 @@ e1000_set_multi(struct net_device *netdev)
e1000_leave_82542_rst
(
adapter
);
}
static
void
e1000_tx_flush
(
struct
e1000_adapter
*
adapter
)
{
uint32_t
ctrl
,
tctl
,
txcw
,
icr
;
e1000_irq_disable
(
adapter
);
if
(
adapter
->
hw
.
mac_type
<
e1000_82543
)
{
/* Transmit Unit Reset */
tctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
TCTL
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
tctl
|
E1000_TCTL_RST
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
tctl
);
e1000_clean_tx_ring
(
adapter
);
e1000_configure_tx
(
adapter
);
}
else
{
txcw
=
E1000_READ_REG
(
&
adapter
->
hw
,
TXCW
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TXCW
,
txcw
&
~
E1000_TXCW_ANE
);
ctrl
=
E1000_READ_REG
(
&
adapter
->
hw
,
CTRL
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
CTRL
,
ctrl
|
E1000_CTRL_SLU
|
E1000_CTRL_ILOS
);
mdelay
(
10
);
e1000_clean_tx_irq
(
adapter
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
CTRL
,
ctrl
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TXCW
,
txcw
);
/* clear the link status change interrupts this caused */
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
);
}
e1000_irq_enable
(
adapter
);
}
/* need to wait a few seconds after link up to get diagnostic information from the phy */
...
...
@@ -1226,6 +1297,48 @@ e1000_update_phy_info(unsigned long data)
e1000_phy_get_info
(
&
adapter
->
hw
,
&
adapter
->
phy_info
);
}
/**
* e1000_82547_tx_fifo_stall - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
static
void
e1000_82547_tx_fifo_stall
(
unsigned
long
data
)
{
struct
e1000_adapter
*
adapter
=
(
struct
e1000_adapter
*
)
data
;
struct
net_device
*
netdev
=
adapter
->
netdev
;
uint32_t
tctl
;
if
(
atomic_read
(
&
adapter
->
tx_fifo_stall
))
{
if
((
E1000_READ_REG
(
&
adapter
->
hw
,
TDT
)
==
E1000_READ_REG
(
&
adapter
->
hw
,
TDH
))
&&
(
E1000_READ_REG
(
&
adapter
->
hw
,
TDFT
)
==
E1000_READ_REG
(
&
adapter
->
hw
,
TDFH
))
&&
(
E1000_READ_REG
(
&
adapter
->
hw
,
TDFTS
)
==
E1000_READ_REG
(
&
adapter
->
hw
,
TDFHS
)))
{
tctl
=
E1000_READ_REG
(
&
adapter
->
hw
,
TCTL
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
tctl
&
~
E1000_TCTL_EN
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDFT
,
adapter
->
tx_head_addr
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDFH
,
adapter
->
tx_head_addr
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDFTS
,
adapter
->
tx_head_addr
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDFHS
,
adapter
->
tx_head_addr
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
TCTL
,
tctl
);
E1000_WRITE_FLUSH
(
&
adapter
->
hw
);
adapter
->
tx_fifo_head
=
0
;
atomic_set
(
&
adapter
->
tx_fifo_stall
,
0
);
netif_wake_queue
(
netdev
);
}
else
{
mod_timer
(
&
adapter
->
tx_fifo_stall_timer
,
jiffies
+
1
);
}
}
}
/**
* e1000_watchdog - Timer Call-back
* @data: pointer to netdev cast into an unsigned long
...
...
@@ -1256,6 +1369,7 @@ e1000_watchdog(unsigned long data)
netif_carrier_on
(
netdev
);
netif_wake_queue
(
netdev
);
mod_timer
(
&
adapter
->
phy_info_timer
,
jiffies
+
2
*
HZ
);
adapter
->
smartspeed
=
0
;
}
}
else
{
if
(
netif_carrier_ok
(
netdev
))
{
...
...
@@ -1268,11 +1382,34 @@ e1000_watchdog(unsigned long data)
netif_stop_queue
(
netdev
);
mod_timer
(
&
adapter
->
phy_info_timer
,
jiffies
+
2
*
HZ
);
}
e1000_smartspeed
(
adapter
);
}
e1000_update_stats
(
adapter
);
e1000_update_adaptive
(
&
adapter
->
hw
);
if
(
!
netif_carrier_ok
(
netdev
))
{
if
(
E1000_DESC_UNUSED
(
txdr
)
+
1
<
txdr
->
count
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
netdev
->
xmit_lock
,
flags
);
e1000_tx_flush
(
adapter
);
spin_unlock_irqrestore
(
&
netdev
->
xmit_lock
,
flags
);
}
}
/* Dynamic mode for Interrupt Throttle Rate (ITR) */
if
(
adapter
->
hw
.
mac_type
>=
e1000_82540
&&
adapter
->
itr
==
1
)
{
/* Symmetric Tx/Rx gets a reduced ITR=2000; Total
* asymmetrical Tx or Rx gets ITR=8000; everyone
* else is between 2000-8000. */
uint32_t
goc
=
(
adapter
->
gotcl
+
adapter
->
gorcl
)
/
10000
;
uint32_t
dif
=
(
adapter
->
gotcl
>
adapter
->
gorcl
?
adapter
->
gotcl
-
adapter
->
gorcl
:
adapter
->
gorcl
-
adapter
->
gotcl
)
/
10000
;
uint32_t
itr
=
goc
>
0
?
(
dif
*
6000
/
goc
+
2000
)
:
8000
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
ITR
,
1000000000
/
(
itr
*
256
));
}
/* Cause software interrupt to ensure rx ring is cleaned */
E1000_WRITE_REG
(
&
adapter
->
hw
,
ICS
,
E1000_ICS_RXDMT0
);
...
...
@@ -1301,7 +1438,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
int
i
;
uint8_t
ipcss
,
ipcso
,
tucss
,
tucso
,
hdr_len
;
uint16_t
ipcse
,
tucse
,
mss
;
if
(
skb_shinfo
(
skb
)
->
tso_size
)
{
hdr_len
=
((
skb
->
h
.
raw
-
skb
->
data
)
+
(
skb
->
h
.
th
->
doff
<<
2
));
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
...
...
@@ -1321,7 +1458,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
i
=
adapter
->
tx_ring
.
next_to_use
;
context_desc
=
E1000_CONTEXT_DESC
(
adapter
->
tx_ring
,
i
);
context_desc
->
lower_setup
.
ip_fields
.
ipcss
=
ipcss
;
context_desc
->
lower_setup
.
ip_fields
.
ipcso
=
ipcso
;
context_desc
->
lower_setup
.
ip_fields
.
ipcse
=
cpu_to_le16
(
ipcse
);
...
...
@@ -1335,12 +1472,12 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
E1000_TXD_CMD_IP
|
E1000_TXD_CMD_TCP
|
(
skb
->
len
-
(
hdr_len
)));
i
=
(
i
+
1
)
%
adapter
->
tx_ring
.
count
;
i
f
(
++
i
==
adapter
->
tx_ring
.
count
)
i
=
0
;
adapter
->
tx_ring
.
next_to_use
=
i
;
return
TRUE
;
}
return
FALSE
;
}
...
...
@@ -1365,7 +1502,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
context_desc
->
cmd_and_length
=
cpu_to_le32
(
adapter
->
txd_cmd
|
E1000_TXD_CMD_DEXT
);
i
=
(
i
+
1
)
%
adapter
->
tx_ring
.
count
;
i
f
(
++
i
==
adapter
->
tx_ring
.
count
)
i
=
0
;
adapter
->
tx_ring
.
next_to_use
=
i
;
return
TRUE
;
...
...
@@ -1374,24 +1511,24 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
return
FALSE
;
}
#define E1000_MAX_TXD_PWR 12
#define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
static
inline
int
e1000_tx_map
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
int
len
,
offset
,
size
,
count
,
i
;
int
len
=
skb
->
len
,
offset
=
0
,
size
,
count
=
0
,
i
;
int
tso
=
skb_shinfo
(
skb
)
->
tso_size
;
int
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
int
f
;
len
=
skb
->
len
-
skb
->
data_len
;
i
=
(
tx_ring
->
next_to_use
+
tx_ring
->
count
-
1
)
%
tx_ring
->
count
;
count
=
0
;
len
-=
skb
->
data_len
;
offset
=
0
;
i
=
tx_ring
->
next_to_use
;
while
(
len
)
{
i
=
(
i
+
1
)
%
tx_ring
->
count
;
size
=
min
(
len
,
adapter
->
max_data_per_txd
);
size
=
min
(
len
,
E1000_MAX_DATA_PER_TXD
);
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if
(
tso
&&
!
nr_frags
&&
size
==
len
&&
size
>
4
)
...
...
@@ -1407,6 +1544,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
len
-=
size
;
offset
+=
size
;
count
++
;
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
for
(
f
=
0
;
f
<
nr_frags
;
f
++
)
{
...
...
@@ -1417,8 +1555,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
offset
=
0
;
while
(
len
)
{
i
=
(
i
+
1
)
%
tx_ring
->
count
;
size
=
min
(
len
,
adapter
->
max_data_per_txd
);
size
=
min
(
len
,
E1000_MAX_DATA_PER_TXD
);
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
if
(
tso
&&
f
==
(
nr_frags
-
1
)
&&
size
==
len
&&
size
>
4
)
...
...
@@ -1435,8 +1572,10 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
len
-=
size
;
offset
+=
size
;
count
++
;
if
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
}
if
(
--
i
<
0
)
i
=
tx_ring
->
count
-
1
;
tx_ring
->
buffer_info
[
i
].
skb
=
skb
;
return
count
;
...
...
@@ -1477,7 +1616,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
tx_desc
->
lower
.
data
=
cpu_to_le32
(
txd_lower
|
tx_ring
->
buffer_info
[
i
].
length
);
tx_desc
->
upper
.
data
=
cpu_to_le32
(
txd_upper
);
i
=
(
i
+
1
)
%
tx_ring
->
count
;
i
f
(
++
i
==
tx_ring
->
count
)
i
=
0
;
}
tx_desc
->
lower
.
data
|=
cpu_to_le32
(
E1000_TXD_CMD_EOP
);
...
...
@@ -1492,34 +1631,74 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
E1000_WRITE_REG
(
&
adapter
->
hw
,
TDT
,
i
);
}
#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
/**
* 82547 workaround to avoid controller hang in half-duplex environment.
* The workaround is to avoid queuing a large packet that would span
* the internal Tx FIFO ring boundary by notifying the stack to resend
* the packet at a later time. This gives the Tx FIFO an opportunity to
* flush all packets. When that occurs, we reset the Tx FIFO pointers
* to the beginning of the Tx FIFO.
**/
#define E1000_FIFO_HDR 0x10
#define E1000_82547_PAD_LEN 0x3E0
static
inline
int
e1000_82547_fifo_workaround
(
struct
e1000_adapter
*
adapter
,
struct
sk_buff
*
skb
)
{
uint32_t
fifo_space
=
adapter
->
tx_fifo_size
-
adapter
->
tx_fifo_head
;
uint32_t
skb_fifo_len
=
skb
->
len
+
E1000_FIFO_HDR
;
E1000_ROUNDUP
(
skb_fifo_len
,
E1000_FIFO_HDR
);
if
(
adapter
->
link_duplex
!=
HALF_DUPLEX
)
goto
no_fifo_stall_required
;
if
(
atomic_read
(
&
adapter
->
tx_fifo_stall
))
return
1
;
if
(
skb_fifo_len
>=
(
E1000_82547_PAD_LEN
+
fifo_space
))
{
atomic_set
(
&
adapter
->
tx_fifo_stall
,
1
);
return
1
;
}
no_fifo_stall_required:
adapter
->
tx_fifo_head
+=
skb_fifo_len
;
if
(
adapter
->
tx_fifo_head
>=
adapter
->
tx_fifo_size
)
adapter
->
tx_fifo_head
-=
adapter
->
tx_fifo_size
;
return
0
;
}
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
(((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
static
int
e1000_xmit_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
netdev
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
int
tx_flags
=
0
,
count
;
int
f
;
count
=
TXD_USE_COUNT
(
skb
->
len
-
skb
->
data_len
,
adapter
->
max_data_per_txd
);
int
tx_flags
=
0
;
if
(
count
=
=
0
)
{
if
(
skb
->
len
<
=
0
)
{
dev_kfree_skb_any
(
skb
);
return
0
;
}
for
(
f
=
0
;
f
<
skb_shinfo
(
skb
)
->
nr_frags
;
f
++
)
count
+=
TXD_USE_COUNT
(
skb_shinfo
(
skb
)
->
frags
[
f
].
size
,
adapter
->
max_data_per_txd
);
if
((
skb_shinfo
(
skb
)
->
tso_size
)
||
(
skb
->
ip_summed
==
CHECKSUM_HW
))
count
++
;
if
(
E1000_DESC_UNUSED
(
&
adapter
->
tx_ring
)
<
count
)
{
if
(
E1000_DESC_UNUSED
(
&
adapter
->
tx_ring
)
<
DESC_NEEDED
)
{
netif_stop_queue
(
netdev
);
return
1
;
}
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
);
return
1
;
}
}
if
(
adapter
->
vlgrp
&&
vlan_tx_tag_present
(
skb
))
{
tx_flags
|=
E1000_TX_FLAGS_VLAN
;
tx_flags
|=
(
vlan_tx_tag_get
(
skb
)
<<
E1000_TX_FLAGS_VLAN_SHIFT
);
...
...
@@ -1530,9 +1709,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else
if
(
e1000_tx_csum
(
adapter
,
skb
))
tx_flags
|=
E1000_TX_FLAGS_CSUM
;
count
=
e1000_tx_map
(
adapter
,
skb
);
e1000_tx_queue
(
adapter
,
count
,
tx_flags
);
e1000_tx_queue
(
adapter
,
e1000_tx_map
(
adapter
,
skb
),
tx_flags
);
netdev
->
trans_start
=
jiffies
;
...
...
@@ -1653,7 +1830,8 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter
->
stats
.
crcerrs
+=
E1000_READ_REG
(
hw
,
CRCERRS
);
adapter
->
stats
.
gprc
+=
E1000_READ_REG
(
hw
,
GPRC
);
adapter
->
stats
.
gorcl
+=
E1000_READ_REG
(
hw
,
GORCL
);
adapter
->
gorcl
=
E1000_READ_REG
(
hw
,
GORCL
);
adapter
->
stats
.
gorcl
+=
adapter
->
gorcl
;
adapter
->
stats
.
gorch
+=
E1000_READ_REG
(
hw
,
GORCH
);
adapter
->
stats
.
bprc
+=
E1000_READ_REG
(
hw
,
BPRC
);
adapter
->
stats
.
mprc
+=
E1000_READ_REG
(
hw
,
MPRC
);
...
...
@@ -1684,7 +1862,8 @@ e1000_update_stats(struct e1000_adapter *adapter)
adapter
->
stats
.
xofftxc
+=
E1000_READ_REG
(
hw
,
XOFFTXC
);
adapter
->
stats
.
fcruc
+=
E1000_READ_REG
(
hw
,
FCRUC
);
adapter
->
stats
.
gptc
+=
E1000_READ_REG
(
hw
,
GPTC
);
adapter
->
stats
.
gotcl
+=
E1000_READ_REG
(
hw
,
GOTCL
);
adapter
->
gotcl
=
E1000_READ_REG
(
hw
,
GOTCL
);
adapter
->
stats
.
gotcl
+=
adapter
->
gotcl
;
adapter
->
stats
.
gotch
+=
E1000_READ_REG
(
hw
,
GOTCH
);
adapter
->
stats
.
rnbc
+=
E1000_READ_REG
(
hw
,
RNBC
);
adapter
->
stats
.
ruc
+=
E1000_READ_REG
(
hw
,
RUC
);
...
...
@@ -1807,60 +1986,57 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
{
struct
net_device
*
netdev
=
data
;
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
#ifdef CONFIG_E1000_NAPI
if
(
netif_rx_schedule_prep
(
netdev
))
{
/* Disable interrupts and enable polling */
atomic_inc
(
&
adapter
->
irq_sem
);
E1000_WRITE_REG
(
&
adapter
->
hw
,
IMC
,
~
0
);
E1000_WRITE_FLUSH
(
&
adapter
->
hw
);
__netif_rx_schedule
(
netdev
);
}
#else
uint32_t
icr
;
int
i
=
E1000_MAX_INTR
;
uint32_t
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
);
#ifndef CONFIG_E1000_NAPI
int
i
;
#endif
while
(
i
&&
(
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
)))
{
if
(
icr
&
(
E1000_ICR_RXSEQ
|
E1000_ICR_LSC
))
{
adapter
->
hw
.
get_link_status
=
1
;
mod_timer
(
&
adapter
->
watchdog_timer
,
jiffies
);
}
e1000_clean_rx_irq
(
adapter
);
e1000_clean_tx_irq
(
adapter
);
i
--
;
if
(
!
icr
)
return
;
/* Not our interrupt */
if
(
icr
&
(
E1000_ICR_RXSEQ
|
E1000_ICR_LSC
))
{
adapter
->
hw
.
get_link_status
=
1
;
mod_timer
(
&
adapter
->
watchdog_timer
,
jiffies
);
}
#ifdef CONFIG_E1000_NAPI
/* Don't disable interrupts - rely on h/w interrupt
* moderation to keep interrupts low. netif_rx_schedule
* is NOP if already polling. */
netif_rx_schedule
(
netdev
);
#else
for
(
i
=
0
;
i
<
E1000_MAX_INTR
;
i
++
)
if
(
!
e1000_clean_rx_irq
(
adapter
)
&&
!
e1000_clean_tx_irq
(
adapter
))
break
;
#endif
}
#ifdef CONFIG_E1000_NAPI
/**
* e1000_clean - NAPI Rx polling callback
* @adapter: board private structure
**/
static
int
e1000_
process_intr
(
struct
net_device
*
netdev
)
e1000_
clean
(
struct
net_device
*
netdev
,
int
*
budget
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
uint32_t
icr
;
int
i
=
E1000_MAX_INTR
;
int
hasReceived
=
0
;
while
(
i
&&
(
icr
=
E1000_READ_REG
(
&
adapter
->
hw
,
ICR
)))
{
if
(
icr
&
E1000_ICR_RXT0
)
hasReceived
=
1
;
if
(
!
(
icr
&
~
(
E1000_ICR_RXT0
)))
int
work_to_do
=
min
(
*
budget
,
netdev
->
quota
);
int
work_done
=
0
;
while
(
work_done
<
work_to_do
)
if
(
!
e1000_clean_rx_irq
(
adapter
,
&
work_done
,
work_to_do
)
&&
!
e1000_clean_tx_irq
(
adapter
))
break
;
if
(
icr
&
(
E1000_ICR_RXSEQ
|
E1000_ICR_LSC
))
{
adapter
->
hw
.
get_link_status
=
1
;
mod_timer
(
&
adapter
->
watchdog_timer
,
jiffies
);
}
e1000_clean_tx_irq
(
adapter
);
i
--
;
}
return
hasReceived
;
*
budget
-=
work_done
;
netdev
->
quota
-=
work_done
;
if
(
work_done
<
work_to_do
)
netif_rx_complete
(
netdev
);
return
(
work_done
>=
work_to_do
);
}
#endif
...
...
@@ -1869,20 +2045,22 @@ e1000_process_intr(struct net_device *netdev)
* @adapter: board private structure
**/
static
void
static
boolean_t
e1000_clean_tx_irq
(
struct
e1000_adapter
*
adapter
)
{
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
struct
net_device
*
netdev
=
adapter
->
netdev
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
struct
e1000_tx_desc
*
tx_desc
;
int
i
;
int
i
,
cleaned
=
FALSE
;
i
=
tx_ring
->
next_to_clean
;
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
while
(
tx_desc
->
upper
.
data
&
cpu_to_le32
(
E1000_TXD_STAT_DD
))
{
cleaned
=
TRUE
;
if
(
tx_ring
->
buffer_info
[
i
].
dma
)
{
pci_unmap_page
(
pdev
,
...
...
@@ -1900,158 +2078,34 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
tx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
}
tx_desc
->
buffer_addr
=
0
;
tx_desc
->
lower
.
data
=
0
;
tx_desc
->
upper
.
data
=
0
;
i
=
(
i
+
1
)
%
tx_ring
->
count
;
i
f
(
++
i
==
tx_ring
->
count
)
i
=
0
;
tx_desc
=
E1000_TX_DESC
(
*
tx_ring
,
i
);
}
tx_ring
->
next_to_clean
=
i
;
if
(
netif_queue_stopped
(
netdev
)
&&
netif_carrier_ok
(
netdev
)
&&
(
E1000_DESC_UNUSED
(
tx_ring
)
>
E1000_TX_QUEUE_WAKE
))
{
if
(
cleaned
&&
netif_queue_stopped
(
netdev
)
&&
netif_carrier_ok
(
netdev
))
netif_wake_queue
(
netdev
);
}
}
#ifdef CONFIG_E1000_NAPI
static
int
e1000_poll
(
struct
net_device
*
netdev
,
int
*
budget
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
e1000_desc_ring
*
rx_ring
=
&
adapter
->
rx_ring
;
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
struct
e1000_rx_desc
*
rx_desc
;
struct
sk_buff
*
skb
;
unsigned
long
flags
;
uint32_t
length
;
uint8_t
last_byte
;
int
i
;
int
received
=
0
;
int
rx_work_limit
=
*
budget
;
if
(
rx_work_limit
>
netdev
->
quota
)
rx_work_limit
=
netdev
->
quota
;
e1000_process_intr
(
netdev
);
i
=
rx_ring
->
next_to_clean
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
while
(
rx_desc
->
status
&
E1000_RXD_STAT_DD
)
{
if
(
--
rx_work_limit
<
0
)
goto
not_done
;
pci_unmap_single
(
pdev
,
rx_ring
->
buffer_info
[
i
].
dma
,
rx_ring
->
buffer_info
[
i
].
length
,
PCI_DMA_FROMDEVICE
);
skb
=
rx_ring
->
buffer_info
[
i
].
skb
;
length
=
le16_to_cpu
(
rx_desc
->
length
);
if
(
!
(
rx_desc
->
status
&
E1000_RXD_STAT_EOP
))
{
/* All receives must fit into a single buffer */
E1000_DBG
(
"Receive packet consumed multiple buffers
\n
"
);
dev_kfree_skb_irq
(
skb
);
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
continue
;
}
if
(
rx_desc
->
errors
&
E1000_RXD_ERR_FRAME_ERR_MASK
)
{
last_byte
=
*
(
skb
->
data
+
length
-
1
);
if
(
TBI_ACCEPT
(
&
adapter
->
hw
,
rx_desc
->
status
,
rx_desc
->
errors
,
length
,
last_byte
))
{
spin_lock_irqsave
(
&
adapter
->
stats_lock
,
flags
);
e1000_tbi_adjust_stats
(
&
adapter
->
hw
,
&
adapter
->
stats
,
length
,
skb
->
data
);
spin_unlock_irqrestore
(
&
adapter
->
stats_lock
,
flags
);
length
--
;
}
else
{
dev_kfree_skb_irq
(
skb
);
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
continue
;
}
}
/* Good Receive */
skb_put
(
skb
,
length
-
ETHERNET_FCS_SIZE
);
/* Receive Checksum Offload */
e1000_rx_checksum
(
adapter
,
rx_desc
,
skb
);
skb
->
protocol
=
eth_type_trans
(
skb
,
netdev
);
if
(
adapter
->
vlgrp
&&
(
rx_desc
->
status
&
E1000_RXD_STAT_VP
))
{
vlan_hwaccel_rx
(
skb
,
adapter
->
vlgrp
,
(
rx_desc
->
special
&
E1000_RXD_SPC_VLAN_MASK
));
}
else
{
netif_receive_skb
(
skb
);
}
netdev
->
last_rx
=
jiffies
;
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
received
++
;
}
if
(
!
received
)
received
=
1
;
e1000_alloc_rx_buffers
(
adapter
);
rx_ring
->
next_to_clean
=
i
;
netdev
->
quota
-=
received
;
*
budget
-=
received
;
netif_rx_complete
(
netdev
);
e1000_irq_enable
(
adapter
);
return
0
;
not_done:
e1000_alloc_rx_buffers
(
adapter
);
rx_ring
->
next_to_clean
=
i
;
netdev
->
quota
-=
received
;
*
budget
-=
received
;
return
1
;
return
cleaned
;
}
#else
/**
* e1000_clean_rx_irq - Send received data up the network stack,
* @adapter: board private structure
**/
static
void
static
boolean_t
#ifdef CONFIG_E1000_NAPI
e1000_clean_rx_irq
(
struct
e1000_adapter
*
adapter
,
int
*
work_done
,
int
work_to_do
)
#else
e1000_clean_rx_irq
(
struct
e1000_adapter
*
adapter
)
#endif
{
struct
e1000_desc_ring
*
rx_ring
=
&
adapter
->
rx_ring
;
struct
net_device
*
netdev
=
adapter
->
netdev
;
...
...
@@ -2061,13 +2115,22 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
unsigned
long
flags
;
uint32_t
length
;
uint8_t
last_byte
;
int
i
;
int
i
,
cleaned
=
FALSE
;
i
=
rx_ring
->
next_to_clean
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
while
(
rx_desc
->
status
&
E1000_RXD_STAT_DD
)
{
#ifdef CONFIG_E1000_NAPI
if
(
*
work_done
>=
work_to_do
)
break
;
(
*
work_done
)
++
;
#endif
cleaned
=
TRUE
;
pci_unmap_single
(
pdev
,
rx_ring
->
buffer_info
[
i
].
dma
,
rx_ring
->
buffer_info
[
i
].
length
,
...
...
@@ -2086,7 +2149,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
i
f
(
++
i
==
rx_ring
->
count
)
i
=
0
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
continue
;
...
...
@@ -2114,7 +2177,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
i
f
(
++
i
==
rx_ring
->
count
)
i
=
0
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
continue
;
...
...
@@ -2128,18 +2191,28 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
e1000_rx_checksum
(
adapter
,
rx_desc
,
skb
);
skb
->
protocol
=
eth_type_trans
(
skb
,
netdev
);
#ifdef CONFIG_E1000_NAPI
if
(
adapter
->
vlgrp
&&
(
rx_desc
->
status
&
E1000_RXD_STAT_VP
))
{
vlan_hwaccel_receive_skb
(
skb
,
adapter
->
vlgrp
,
(
rx_desc
->
special
&
E1000_RXD_SPC_VLAN_MASK
));
}
else
{
netif_receive_skb
(
skb
);
}
#else
/* CONFIG_E1000_NAPI */
if
(
adapter
->
vlgrp
&&
(
rx_desc
->
status
&
E1000_RXD_STAT_VP
))
{
vlan_hwaccel_rx
(
skb
,
adapter
->
vlgrp
,
(
rx_desc
->
special
&
E1000_RXD_SPC_VLAN_MASK
));
}
else
{
netif_rx
(
skb
);
}
#endif
/* CONFIG_E1000_NAPI */
netdev
->
last_rx
=
jiffies
;
rx_desc
->
status
=
0
;
rx_ring
->
buffer_info
[
i
].
skb
=
NULL
;
i
=
(
i
+
1
)
%
rx_ring
->
count
;
i
f
(
++
i
==
rx_ring
->
count
)
i
=
0
;
rx_desc
=
E1000_RX_DESC
(
*
rx_ring
,
i
);
}
...
...
@@ -2147,8 +2220,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter)
rx_ring
->
next_to_clean
=
i
;
e1000_alloc_rx_buffers
(
adapter
);
return
cleaned
;
}
#endif
/**
* e1000_alloc_rx_buffers - Replace used receive buffers
...
...
@@ -2163,11 +2237,9 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
struct
pci_dev
*
pdev
=
adapter
->
pdev
;
struct
e1000_rx_desc
*
rx_desc
;
struct
sk_buff
*
skb
;
int
reserve_len
;
int
reserve_len
=
2
;
int
i
;
reserve_len
=
2
;
i
=
rx_ring
->
next_to_use
;
while
(
!
rx_ring
->
buffer_info
[
i
].
skb
)
{
...
...
@@ -2198,7 +2270,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
rx_desc
->
buffer_addr
=
cpu_to_le64
(
rx_ring
->
buffer_info
[
i
].
dma
);
if
(
!
(
i
%
E1000_RX_BUFFER_WRITE
)
)
{
if
(
(
i
&
~
(
E1000_RX_BUFFER_WRITE
-
1
))
==
i
)
{
/* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs,
...
...
@@ -2208,12 +2280,67 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
E1000_WRITE_REG
(
&
adapter
->
hw
,
RDT
,
i
);
}
i
=
(
i
+
1
)
%
rx_ring
->
count
;
i
f
(
++
i
==
rx_ring
->
count
)
i
=
0
;
}
rx_ring
->
next_to_use
=
i
;
}
/**
* e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
* @adapter:
**/
static
void
e1000_smartspeed
(
struct
e1000_adapter
*
adapter
)
{
uint16_t
phy_status
;
uint16_t
phy_ctrl
;
if
((
adapter
->
hw
.
phy_type
!=
e1000_phy_igp
)
||
!
adapter
->
hw
.
autoneg
||
!
(
adapter
->
hw
.
autoneg_advertised
&
ADVERTISE_1000_FULL
))
return
;
if
(
adapter
->
smartspeed
==
0
)
{
/* If Master/Slave config fault is asserted twice,
* we assume back-to-back */
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_STATUS
,
&
phy_status
);
if
(
!
(
phy_status
&
SR_1000T_MS_CONFIG_FAULT
))
return
;
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_STATUS
,
&
phy_status
);
if
(
!
(
phy_status
&
SR_1000T_MS_CONFIG_FAULT
))
return
;
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_CTRL
,
&
phy_ctrl
);
if
(
phy_ctrl
&
CR_1000T_MS_ENABLE
)
{
phy_ctrl
&=
~
CR_1000T_MS_ENABLE
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_CTRL
,
phy_ctrl
);
adapter
->
smartspeed
++
;
if
(
!
e1000_phy_setup_autoneg
(
&
adapter
->
hw
)
&&
!
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_ctrl
))
{
phy_ctrl
|=
(
MII_CR_AUTO_NEG_EN
|
MII_CR_RESTART_AUTO_NEG
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
phy_ctrl
);
}
}
return
;
}
else
if
(
adapter
->
smartspeed
==
E1000_SMARTSPEED_DOWNSHIFT
)
{
/* If still no link, perhaps using 2/3 pair cable */
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_CTRL
,
&
phy_ctrl
);
phy_ctrl
|=
CR_1000T_MS_ENABLE
;
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_1000T_CTRL
,
phy_ctrl
);
if
(
!
e1000_phy_setup_autoneg
(
&
adapter
->
hw
)
&&
!
e1000_read_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
&
phy_ctrl
))
{
phy_ctrl
|=
(
MII_CR_AUTO_NEG_EN
|
MII_CR_RESTART_AUTO_NEG
);
e1000_write_phy_reg
(
&
adapter
->
hw
,
PHY_CTRL
,
phy_ctrl
);
}
}
/* Restart process after E1000_SMARTSPEED_MAX iterations */
if
(
adapter
->
smartspeed
++
==
E1000_SMARTSPEED_MAX
)
adapter
->
smartspeed
=
0
;
}
/**
* e1000_ioctl -
* @netdev:
...
...
@@ -2225,6 +2352,10 @@ static int
e1000_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
,
int
cmd
)
{
switch
(
cmd
)
{
case
SIOCGMIIPHY
:
case
SIOCGMIIREG
:
case
SIOCSMIIREG
:
return
e1000_mii_ioctl
(
netdev
,
ifr
,
cmd
);
case
SIOCETHTOOL
:
return
e1000_ethtool_ioctl
(
netdev
,
ifr
);
default:
...
...
@@ -2232,6 +2363,86 @@ e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
/**
* e1000_mii_ioctl -
* @netdev:
* @ifreq:
* @cmd:
**/
static
int
e1000_mii_ioctl
(
struct
net_device
*
netdev
,
struct
ifreq
*
ifr
,
int
cmd
)
{
struct
e1000_adapter
*
adapter
=
netdev
->
priv
;
struct
mii_ioctl_data
*
data
=
(
struct
mii_ioctl_data
*
)
&
ifr
->
ifr_data
;
int
retval
;
uint16_t
mii_reg
;
uint16_t
spddplx
;
if
(
adapter
->
hw
.
media_type
==
e1000_media_type_fiber
)
return
-
EOPNOTSUPP
;
switch
(
cmd
)
{
case
SIOCGMIIPHY
:
data
->
phy_id
=
adapter
->
hw
.
phy_addr
;
break
;
case
SIOCGMIIREG
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
e1000_read_phy_reg
(
&
adapter
->
hw
,
data
->
reg_num
&
0x1F
,
&
data
->
val_out
))
return
-
EIO
;
break
;
case
SIOCSMIIREG
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
data
->
reg_num
&
~
(
0x1F
))
return
-
EFAULT
;
mii_reg
=
data
->
val_in
;
if
(
e1000_write_phy_reg
(
&
adapter
->
hw
,
data
->
reg_num
,
data
->
val_in
))
return
-
EIO
;
if
(
adapter
->
hw
.
phy_type
==
e1000_phy_m88
)
{
switch
(
data
->
reg_num
)
{
case
PHY_CTRL
:
if
(
data
->
val_in
&
MII_CR_AUTO_NEG_EN
)
{
adapter
->
hw
.
autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
0x2F
;
}
else
{
if
(
data
->
val_in
&
0x40
)
spddplx
=
SPEED_1000
;
else
if
(
data
->
val_in
&
0x2000
)
spddplx
=
SPEED_100
;
else
spddplx
=
SPEED_10
;
spddplx
+=
(
data
->
val_in
&
0x100
)
?
FULL_DUPLEX
:
HALF_DUPLEX
;
retval
=
e1000_set_spd_dplx
(
adapter
,
spddplx
);
if
(
retval
)
return
retval
;
}
if
(
netif_running
(
adapter
->
netdev
))
{
e1000_down
(
adapter
);
e1000_up
(
adapter
);
}
else
e1000_reset
(
adapter
);
break
;
case
M88E1000_PHY_SPEC_CTRL
:
case
M88E1000_EXT_PHY_SPEC_CTRL
:
if
(
e1000_phy_reset
(
&
adapter
->
hw
))
return
-
EIO
;
break
;
}
}
break
;
default:
return
-
EOPNOTSUPP
;
}
return
E1000_SUCCESS
;
}
/**
* e1000_rx_checksum - Receive Checksum Offload for 82543
* @adapter: board private structure
...
...
@@ -2402,6 +2613,35 @@ e1000_restore_vlan(struct e1000_adapter *adapter)
}
}
int
e1000_set_spd_dplx
(
struct
e1000_adapter
*
adapter
,
uint16_t
spddplx
)
{
adapter
->
hw
.
autoneg
=
0
;
switch
(
spddplx
)
{
case
SPEED_10
+
DUPLEX_HALF
:
adapter
->
hw
.
forced_speed_duplex
=
e1000_10_half
;
break
;
case
SPEED_10
+
DUPLEX_FULL
:
adapter
->
hw
.
forced_speed_duplex
=
e1000_10_full
;
break
;
case
SPEED_100
+
DUPLEX_HALF
:
adapter
->
hw
.
forced_speed_duplex
=
e1000_100_half
;
break
;
case
SPEED_100
+
DUPLEX_FULL
:
adapter
->
hw
.
forced_speed_duplex
=
e1000_100_full
;
break
;
case
SPEED_1000
+
DUPLEX_FULL
:
adapter
->
hw
.
autoneg
=
1
;
adapter
->
hw
.
autoneg_advertised
=
ADVERTISE_1000_FULL
;
break
;
case
SPEED_1000
+
DUPLEX_HALF
:
/* not supported */
default:
return
-
EINVAL
;
}
return
0
;
}
static
int
e1000_notify_reboot
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
p
)
{
...
...
@@ -2419,6 +2659,7 @@ e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
return
NOTIFY_DONE
;
}
static
int
e1000_suspend
(
struct
pci_dev
*
pdev
,
uint32_t
state
)
{
...
...
@@ -2483,7 +2724,8 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state)
if
(
manc
&
E1000_MANC_SMBUS_EN
)
{
manc
|=
E1000_MANC_ARP_EN
;
E1000_WRITE_REG
(
&
adapter
->
hw
,
MANC
,
manc
);
state
=
0
;
pci_enable_wake
(
pdev
,
3
,
1
);
pci_enable_wake
(
pdev
,
4
,
1
);
/* 4 == D3 cold */
}
}
...
...
drivers/net/e1000/e1000_osdep.h
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -77,24 +77,22 @@ typedef enum {
#define E1000_WRITE_REG(a, reg, value) ( \
((a)->mac_type >= e1000_82543) ? \
(writel((value), ((a)->hw_addr + E1000_##reg))) : \
(writel((value), ((a)->hw_addr + E1000_82542_##reg))))
writel((value), ((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))
#define E1000_READ_REG(a, reg) ( \
((a)->mac_type >= e1000_82543) ? \
readl((a)->hw_addr + E1000_##reg) : \
readl((a)->hw_addr + E1000_82542_##reg))
readl((a)->hw_addr + \
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
((a)->mac_type >= e1000_82543) ?
\
writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) :
\
writel((value), ((a)->hw_addr + E1000_82542_##reg +
((offset) << 2))))
writel((value), ((a)->hw_addr +
\
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) +
\
((offset) << 2))))
#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
((a)->mac_type >= e1000_82543) ?
\
readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) :
\
readl((a)->hw_addr + E1000_82542_##reg +
((offset) << 2)))
readl((a)->hw_addr +
\
(((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) +
\
((offset) << 2)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
...
...
drivers/net/e1000/e1000_param.c
View file @
e5c136c0
/*******************************************************************************
Copyright(c) 1999 - 200
2
Intel Corporation. All rights reserved.
Copyright(c) 1999 - 200
3
Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
...
...
@@ -169,7 +169,7 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
*
* Valid Range: 0-65535
*
* Default Value: 0
/128
* Default Value: 0
*/
E1000_PARAM
(
RxIntDelay
,
"Receive Interrupt Delay"
);
...
...
@@ -183,6 +183,15 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
E1000_PARAM
(
RxAbsIntDelay
,
"Receive Absolute Interrupt Delay"
);
/* Interrupt Throttle Rate (interrupts/sec)
*
* Valid Range: 100-100000 (0=off, 1=dynamic)
*
* Default Value: 1
*/
E1000_PARAM
(
InterruptThrottleRate
,
"Interrupt Throttling Rate"
);
#define AUTONEG_ADV_DEFAULT 0x2F
#define AUTONEG_ADV_MASK 0x2F
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
...
...
@@ -213,6 +222,10 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
#define MAX_TXABSDELAY 0xFFFF
#define MIN_TXABSDELAY 0
#define DEFAULT_ITR 1
#define MAX_ITR 100000
#define MIN_ITR 100
struct
e1000_option
{
enum
{
enable_option
,
range_option
,
list_option
}
type
;
char
*
name
;
...
...
@@ -309,7 +322,7 @@ e1000_check_options(struct e1000_adapter *adapter)
.
name
=
"Transmit Descriptors"
,
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_TXD
),
.
def
=
DEFAULT_TXD
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_TXD
}}
.
arg
=
{
.
r
{
.
min
=
MIN_TXD
}}
};
struct
e1000_desc_ring
*
tx_ring
=
&
adapter
->
tx_ring
;
e1000_mac_type
mac_type
=
adapter
->
hw
.
mac_type
;
...
...
@@ -362,7 +375,8 @@ e1000_check_options(struct e1000_adapter *adapter)
.
name
=
"Flow Control"
,
.
err
=
"reading default settings from EEPROM"
,
.
def
=
e1000_fc_default
,
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
fc_list
),
.
p
=
fc_list
}}
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
fc_list
),
.
p
=
fc_list
}}
};
int
fc
=
FlowControl
[
bd
];
...
...
@@ -370,58 +384,78 @@ e1000_check_options(struct e1000_adapter *adapter)
adapter
->
hw
.
fc
=
adapter
->
hw
.
original_fc
=
fc
;
}
{
/* Transmit Interrupt Delay */
char
*
tidv
=
"using default of "
__MODULE_STRING
(
DEFAULT_TIDV
);
struct
e1000_option
opt
=
{
.
type
=
range_option
,
.
name
=
"Transmit Interrupt Delay"
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_TXDELAY
,
.
max
=
MAX_TXDELAY
}}
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_TIDV
),
.
def
=
DEFAULT_TIDV
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_TXDELAY
,
.
max
=
MAX_TXDELAY
}}
};
opt
.
def
=
DEFAULT_TIDV
;
opt
.
err
=
tidv
;
adapter
->
tx_int_delay
=
TxIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
tx_int_delay
,
&
opt
);
}
{
/* Transmit Absolute Interrupt Delay */
char
*
tadv
=
"using default of "
__MODULE_STRING
(
DEFAULT_TADV
);
struct
e1000_option
opt
=
{
.
type
=
range_option
,
.
name
=
"Transmit Absolute Interrupt Delay"
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_TXABSDELAY
,
.
max
=
MAX_TXABSDELAY
}}
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_TADV
),
.
def
=
DEFAULT_TADV
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_TXABSDELAY
,
.
max
=
MAX_TXABSDELAY
}}
};
opt
.
def
=
DEFAULT_TADV
;
opt
.
err
=
tadv
;
adapter
->
tx_abs_int_delay
=
TxAbsIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
tx_abs_int_delay
,
&
opt
);
}
{
/* Receive Interrupt Delay */
char
*
rdtr
=
"using default of "
__MODULE_STRING
(
DEFAULT_RDTR
);
struct
e1000_option
opt
=
{
.
type
=
range_option
,
.
name
=
"Receive Interrupt Delay"
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_RXDELAY
,
.
max
=
MAX_RXDELAY
}}
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_RDTR
),
.
def
=
DEFAULT_RDTR
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_RXDELAY
,
.
max
=
MAX_RXDELAY
}}
};
opt
.
def
=
DEFAULT_RDTR
;
opt
.
err
=
rdtr
;
adapter
->
rx_int_delay
=
RxIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
rx_int_delay
,
&
opt
);
}
{
/* Receive Absolute Interrupt Delay */
char
*
radv
=
"using default of "
__MODULE_STRING
(
DEFAULT_RADV
);
struct
e1000_option
opt
=
{
.
type
=
range_option
,
.
name
=
"Receive Absolute Interrupt Delay"
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_RXABSDELAY
,
.
max
=
MAX_RXABSDELAY
}}
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_RADV
),
.
def
=
DEFAULT_RADV
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_RXABSDELAY
,
.
max
=
MAX_RXABSDELAY
}}
};
opt
.
def
=
DEFAULT_RADV
;
opt
.
err
=
radv
;
adapter
->
rx_abs_int_delay
=
RxAbsIntDelay
[
bd
];
e1000_validate_option
(
&
adapter
->
rx_abs_int_delay
,
&
opt
);
}
{
/* Interrupt Throttling Rate */
struct
e1000_option
opt
=
{
.
type
=
range_option
,
.
name
=
"Interrupt Throttling Rate (ints/sec)"
,
.
err
=
"using default of "
__MODULE_STRING
(
DEFAULT_ITR
),
.
def
=
DEFAULT_ITR
,
.
arg
=
{
.
r
=
{
.
min
=
MIN_ITR
,
.
max
=
MAX_ITR
}}
};
adapter
->
itr
=
InterruptThrottleRate
[
bd
];
if
(
adapter
->
itr
==
0
)
{
printk
(
KERN_INFO
"%s turned off
\n
"
,
opt
.
name
);
}
else
if
(
adapter
->
itr
==
1
||
adapter
->
itr
==
-
1
)
{
/* Dynamic mode */
adapter
->
itr
=
1
;
}
else
{
e1000_validate_option
(
&
adapter
->
itr
,
&
opt
);
}
}
switch
(
adapter
->
hw
.
media_type
)
{
case
e1000_media_type_fiber
:
e1000_check_fiber_options
(
adapter
);
...
...
@@ -486,7 +520,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.
name
=
"Speed"
,
.
err
=
"parameter ignored"
,
.
def
=
0
,
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
speed_list
),
.
p
=
speed_list
}}
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
speed_list
),
.
p
=
speed_list
}}
};
speed
=
Speed
[
bd
];
...
...
@@ -502,7 +537,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.
name
=
"Duplex"
,
.
err
=
"parameter ignored"
,
.
def
=
0
,
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
dplx_list
),
.
p
=
dplx_list
}}
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
dplx_list
),
.
p
=
dplx_list
}}
};
dplx
=
Duplex
[
bd
];
...
...
@@ -554,7 +590,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter)
.
name
=
"AutoNeg"
,
.
err
=
"parameter ignored"
,
.
def
=
AUTONEG_ADV_DEFAULT
,
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
an_list
),
.
p
=
an_list
}}
.
arg
=
{
.
l
=
{
.
nr
=
ARRAY_SIZE
(
an_list
),
.
p
=
an_list
}}
};
int
an
=
AutoNeg
[
bd
];
...
...
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