4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "base/ixgbe_type.h"
35 #include "base/ixgbe_82599.h"
36 #include "base/ixgbe_api.h"
37 #include "base/ixgbe_common.h"
38 #include "base/ixgbe_phy.h"
39 #include "ixgbe_bypass_defines.h"
40 #include "ixgbe_bypass.h"
43 * ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
44 * @hw: pointer to hardware structure
45 * @speed: link speed to set
47 * We set the module speed differently for fixed fiber. For other
48 * multi-speed devices we don't have an error value so here if we
49 * detect an error we just log it and exit.
52 ixgbe_set_fiber_fixed_speed(struct ixgbe_hw
*hw
, ixgbe_link_speed speed
)
58 case IXGBE_LINK_SPEED_10GB_FULL
:
59 /* one bit mask same as setting on */
60 rs
= IXGBE_SFF_SOFT_RS_SELECT_10G
;
62 case IXGBE_LINK_SPEED_1GB_FULL
:
63 rs
= IXGBE_SFF_SOFT_RS_SELECT_1G
;
66 PMD_DRV_LOG(ERR
, "Invalid fixed module speed");
71 status
= hw
->phy
.ops
.read_i2c_byte(hw
, IXGBE_SFF_SFF_8472_OSCB
,
72 IXGBE_I2C_EEPROM_DEV_ADDR2
,
75 PMD_DRV_LOG(ERR
, "Failed to read Rx Rate Select RS0");
79 eeprom_data
= (eeprom_data
& ~IXGBE_SFF_SOFT_RS_SELECT_MASK
) & rs
;
81 status
= hw
->phy
.ops
.write_i2c_byte(hw
, IXGBE_SFF_SFF_8472_OSCB
,
82 IXGBE_I2C_EEPROM_DEV_ADDR2
,
85 PMD_DRV_LOG(ERR
, "Failed to write Rx Rate Select RS0");
90 status
= hw
->phy
.ops
.read_i2c_byte(hw
, IXGBE_SFF_SFF_8472_ESCB
,
91 IXGBE_I2C_EEPROM_DEV_ADDR2
,
94 PMD_DRV_LOG(ERR
, "Failed to read Rx Rate Select RS1");
98 eeprom_data
= (eeprom_data
& ~IXGBE_SFF_SOFT_RS_SELECT_MASK
) & rs
;
100 status
= hw
->phy
.ops
.write_i2c_byte(hw
, IXGBE_SFF_SFF_8472_ESCB
,
101 IXGBE_I2C_EEPROM_DEV_ADDR2
,
104 PMD_DRV_LOG(ERR
, "Failed to write Rx Rate Select RS1");
112 * ixgbe_setup_mac_link_multispeed_fixed_fiber - Set MAC link speed
113 * @hw: pointer to hardware structure
114 * @speed: new link speed
115 * @autoneg_wait_to_complete: true when waiting for completion is needed
117 * Set the link speed in the AUTOC register and restarts link.
120 ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw
*hw
,
121 ixgbe_link_speed speed
,
122 bool autoneg_wait_to_complete
)
124 s32 status
= IXGBE_SUCCESS
;
125 ixgbe_link_speed link_speed
= IXGBE_LINK_SPEED_UNKNOWN
;
126 ixgbe_link_speed highest_link_speed
= IXGBE_LINK_SPEED_UNKNOWN
;
128 u32 esdp_reg
= IXGBE_READ_REG(hw
, IXGBE_ESDP
);
130 bool link_up
= false;
133 PMD_INIT_FUNC_TRACE();
135 /* Mask off requested but non-supported speeds */
136 status
= ixgbe_get_link_capabilities(hw
, &link_speed
, &negotiation
);
137 if (status
!= IXGBE_SUCCESS
)
143 * Try each speed one by one, highest priority first. We do this in
144 * software because 10gb fiber doesn't support speed autonegotiation.
146 if (speed
& IXGBE_LINK_SPEED_10GB_FULL
) {
148 highest_link_speed
= IXGBE_LINK_SPEED_10GB_FULL
;
150 /* If we already have link at this speed, just jump out */
151 status
= ixgbe_check_link(hw
, &link_speed
, &link_up
, false);
152 if (status
!= IXGBE_SUCCESS
)
155 if ((link_speed
== IXGBE_LINK_SPEED_10GB_FULL
) && link_up
)
157 /* Set the module link speed */
158 ixgbe_set_fiber_fixed_speed(hw
, IXGBE_LINK_SPEED_10GB_FULL
);
160 /* Set the module link speed */
161 esdp_reg
|= (IXGBE_ESDP_SDP5_DIR
| IXGBE_ESDP_SDP5
);
162 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp_reg
);
163 IXGBE_WRITE_FLUSH(hw
);
165 /* Allow module to change analog characteristics (1G->10G) */
168 status
= ixgbe_setup_mac_link_82599(hw
,
169 IXGBE_LINK_SPEED_10GB_FULL
,
170 autoneg_wait_to_complete
);
171 if (status
!= IXGBE_SUCCESS
)
174 /* Flap the tx laser if it has not already been done */
175 ixgbe_flap_tx_laser(hw
);
178 * Wait for the controller to acquire link. Per IEEE 802.3ap,
179 * Section 73.10.2, we may have to wait up to 500ms if KR is
180 * attempted. 82599 uses the same timing for 10g SFI.
182 for (i
= 0; i
< 5; i
++) {
183 /* Wait for the link partner to also set speed */
186 /* If we have link, just jump out */
187 status
= ixgbe_check_link(hw
, &link_speed
,
189 if (status
!= IXGBE_SUCCESS
)
197 if (speed
& IXGBE_LINK_SPEED_1GB_FULL
) {
199 if (highest_link_speed
== IXGBE_LINK_SPEED_UNKNOWN
)
200 highest_link_speed
= IXGBE_LINK_SPEED_1GB_FULL
;
202 /* If we already have link at this speed, just jump out */
203 status
= ixgbe_check_link(hw
, &link_speed
, &link_up
, false);
204 if (status
!= IXGBE_SUCCESS
)
207 if ((link_speed
== IXGBE_LINK_SPEED_1GB_FULL
) && link_up
)
210 /* Set the module link speed */
211 ixgbe_set_fiber_fixed_speed(hw
, IXGBE_LINK_SPEED_1GB_FULL
);
213 /* Allow module to change analog characteristics (10G->1G) */
216 status
= ixgbe_setup_mac_link_82599(hw
,
217 IXGBE_LINK_SPEED_1GB_FULL
,
218 autoneg_wait_to_complete
);
219 if (status
!= IXGBE_SUCCESS
)
222 /* Flap the tx laser if it has not already been done */
223 ixgbe_flap_tx_laser(hw
);
225 /* Wait for the link partner to also set speed */
228 /* If we have link, just jump out */
229 status
= ixgbe_check_link(hw
, &link_speed
, &link_up
, false);
230 if (status
!= IXGBE_SUCCESS
)
238 * We didn't get link. Configure back to the highest speed we tried,
239 * (if there was more than one). We call ourselves back with just the
240 * single highest speed that the user requested.
243 status
= ixgbe_setup_mac_link_multispeed_fixed_fiber(hw
,
244 highest_link_speed
, autoneg_wait_to_complete
);
247 /* Set autoneg_advertised value based on input link speed */
248 hw
->phy
.autoneg_advertised
= 0;
250 if (speed
& IXGBE_LINK_SPEED_10GB_FULL
)
251 hw
->phy
.autoneg_advertised
|= IXGBE_LINK_SPEED_10GB_FULL
;
253 if (speed
& IXGBE_LINK_SPEED_1GB_FULL
)
254 hw
->phy
.autoneg_advertised
|= IXGBE_LINK_SPEED_1GB_FULL
;
259 static enum ixgbe_media_type
260 ixgbe_bypass_get_media_type(struct ixgbe_hw
*hw
)
262 enum ixgbe_media_type media_type
;
264 PMD_INIT_FUNC_TRACE();
266 if (hw
->device_id
== IXGBE_DEV_ID_82599_BYPASS
) {
267 media_type
= ixgbe_media_type_fiber
;
269 media_type
= ixgbe_get_media_type_82599(hw
);
275 * Wrapper around shared code (base driver) to support BYPASS nic.
278 ixgbe_bypass_init_shared_code(struct ixgbe_hw
*hw
)
282 if (hw
->device_id
== IXGBE_DEV_ID_82599_BYPASS
) {
283 hw
->mac
.type
= ixgbe_mac_82599EB
;
286 ret_val
= ixgbe_init_shared_code(hw
);
287 if (hw
->device_id
== IXGBE_DEV_ID_82599_BYPASS
) {
288 hw
->mac
.ops
.get_media_type
= &ixgbe_bypass_get_media_type
;
289 ixgbe_init_mac_link_ops_82599(hw
);
296 ixgbe_bypass_init_hw(struct ixgbe_hw
*hw
)
300 rc
= ixgbe_init_hw(hw
);
301 if (rc
== 0 && hw
->device_id
== IXGBE_DEV_ID_82599_BYPASS
) {
303 hw
->mac
.ops
.setup_link
=
304 &ixgbe_setup_mac_link_multispeed_fixed_fiber
;
306 hw
->mac
.ops
.get_media_type
= &ixgbe_bypass_get_media_type
;
308 hw
->mac
.ops
.disable_tx_laser
= NULL
;
309 hw
->mac
.ops
.enable_tx_laser
= NULL
;
310 hw
->mac
.ops
.flap_tx_laser
= NULL
;