Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2015 Intel Corporation
3 : : */
4 : :
5 : : #include "base/ixgbe_type.h"
6 : : #include "base/ixgbe_82599.h"
7 : : #include "base/ixgbe_api.h"
8 : : #include "base/ixgbe_common.h"
9 : : #include "base/ixgbe_phy.h"
10 : : #include "ixgbe_bypass_defines.h"
11 : : #include "ixgbe_bypass.h"
12 : :
13 : : /**
14 : : * ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
15 : : * @hw: pointer to hardware structure
16 : : * @speed: link speed to set
17 : : *
18 : : * We set the module speed differently for fixed fiber. For other
19 : : * multi-speed devices we don't have an error value so here if we
20 : : * detect an error we just log it and exit.
21 : : */
22 : : static void
23 : 0 : ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
24 : : {
25 : : s32 status;
26 : : u8 rs, eeprom_data;
27 : :
28 [ # # ]: 0 : switch (speed) {
29 : : case IXGBE_LINK_SPEED_10GB_FULL:
30 : : /* one bit mask same as setting on */
31 : : rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
32 : : break;
33 : : case IXGBE_LINK_SPEED_1GB_FULL:
34 : : rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
35 : : break;
36 : 0 : default:
37 : 0 : PMD_DRV_LOG(ERR, "Invalid fixed module speed");
38 : 0 : return;
39 : : }
40 : :
41 : : /* Set RS0 */
42 : 0 : status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
43 : : IXGBE_I2C_EEPROM_DEV_ADDR2,
44 : : &eeprom_data);
45 [ # # ]: 0 : if (status) {
46 : 0 : PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS0");
47 : 0 : goto out;
48 : : }
49 : :
50 : 0 : eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
51 : :
52 : 0 : status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
53 : : IXGBE_I2C_EEPROM_DEV_ADDR2,
54 : : eeprom_data);
55 [ # # ]: 0 : if (status) {
56 : 0 : PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS0");
57 : 0 : goto out;
58 : : }
59 : :
60 : : /* Set RS1 */
61 : 0 : status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
62 : : IXGBE_I2C_EEPROM_DEV_ADDR2,
63 : : &eeprom_data);
64 [ # # ]: 0 : if (status) {
65 : 0 : PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS1");
66 : 0 : goto out;
67 : : }
68 : :
69 : 0 : eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
70 : :
71 : 0 : status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
72 : : IXGBE_I2C_EEPROM_DEV_ADDR2,
73 : : eeprom_data);
74 [ # # ]: 0 : if (status) {
75 : 0 : PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS1");
76 : 0 : goto out;
77 : : }
78 : 0 : out:
79 : : return;
80 : : }
81 : :
82 : : /**
83 : : * ixgbe_setup_mac_link_multispeed_fixed_fiber - Set MAC link speed
84 : : * @hw: pointer to hardware structure
85 : : * @speed: new link speed
86 : : * @autoneg_wait_to_complete: true when waiting for completion is needed
87 : : *
88 : : * Set the link speed in the AUTOC register and restarts link.
89 : : **/
90 : : static s32
91 : 0 : ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw,
92 : : ixgbe_link_speed speed,
93 : : bool autoneg_wait_to_complete)
94 : : {
95 : : s32 status = IXGBE_SUCCESS;
96 : 0 : ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
97 : : ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
98 : : u32 speedcnt = 0;
99 : 0 : u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
100 : : u32 i = 0;
101 : 0 : bool link_up = false;
102 : : bool negotiation;
103 : :
104 : 0 : PMD_INIT_FUNC_TRACE();
105 : :
106 : : /* Mask off requested but non-supported speeds */
107 : 0 : status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
108 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
109 : : return status;
110 : :
111 : 0 : speed &= link_speed;
112 : :
113 : : /*
114 : : * Try each speed one by one, highest priority first. We do this in
115 : : * software because 10gb fiber doesn't support speed autonegotiation.
116 : : */
117 [ # # ]: 0 : if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
118 : : speedcnt++;
119 : : highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
120 : :
121 : : /* If we already have link at this speed, just jump out */
122 : 0 : status = ixgbe_check_link(hw, &link_speed, &link_up, false);
123 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
124 : : return status;
125 : :
126 [ # # # # ]: 0 : if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
127 : 0 : goto out;
128 : : /* Set the module link speed */
129 : 0 : ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_10GB_FULL);
130 : :
131 : : /* Set the module link speed */
132 : 0 : esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
133 : 0 : IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
134 : 0 : IXGBE_WRITE_FLUSH(hw);
135 : :
136 : : /* Allow module to change analog characteristics (1G->10G) */
137 : 0 : msec_delay(40);
138 : :
139 : 0 : status = ixgbe_setup_mac_link_82599(hw,
140 : : IXGBE_LINK_SPEED_10GB_FULL,
141 : : autoneg_wait_to_complete);
142 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
143 : : return status;
144 : :
145 : : /* Flap the tx laser if it has not already been done */
146 : 0 : ixgbe_flap_tx_laser(hw);
147 : :
148 : : /*
149 : : * Wait for the controller to acquire link. Per IEEE 802.3ap,
150 : : * Section 73.10.2, we may have to wait up to 500ms if KR is
151 : : * attempted. 82599 uses the same timing for 10g SFI.
152 : : */
153 [ # # ]: 0 : for (i = 0; i < 5; i++) {
154 : : /* Wait for the link partner to also set speed */
155 : 0 : msec_delay(100);
156 : :
157 : : /* If we have link, just jump out */
158 : 0 : status = ixgbe_check_link(hw, &link_speed,
159 : : &link_up, false);
160 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
161 : 0 : return status;
162 : :
163 [ # # ]: 0 : if (link_up)
164 : 0 : goto out;
165 : : }
166 : : }
167 : :
168 [ # # ]: 0 : if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
169 : 0 : speedcnt++;
170 [ # # ]: 0 : if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
171 : : highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
172 : :
173 : : /* If we already have link at this speed, just jump out */
174 : 0 : status = ixgbe_check_link(hw, &link_speed, &link_up, false);
175 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
176 : : return status;
177 : :
178 [ # # # # ]: 0 : if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
179 : 0 : goto out;
180 : :
181 : : /* Set the module link speed */
182 : 0 : ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_1GB_FULL);
183 : :
184 : : /* Allow module to change analog characteristics (10G->1G) */
185 : 0 : msec_delay(40);
186 : :
187 : 0 : status = ixgbe_setup_mac_link_82599(hw,
188 : : IXGBE_LINK_SPEED_1GB_FULL,
189 : : autoneg_wait_to_complete);
190 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
191 : : return status;
192 : :
193 : : /* Flap the tx laser if it has not already been done */
194 : 0 : ixgbe_flap_tx_laser(hw);
195 : :
196 : : /* Wait for the link partner to also set speed */
197 : 0 : msec_delay(100);
198 : :
199 : : /* If we have link, just jump out */
200 : 0 : status = ixgbe_check_link(hw, &link_speed, &link_up, false);
201 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
202 : : return status;
203 : :
204 [ # # ]: 0 : if (link_up)
205 : 0 : goto out;
206 : : }
207 : :
208 : : /*
209 : : * We didn't get link. Configure back to the highest speed we tried,
210 : : * (if there was more than one). We call ourselves back with just the
211 : : * single highest speed that the user requested.
212 : : */
213 [ # # ]: 0 : if (speedcnt > 1)
214 : 0 : status = ixgbe_setup_mac_link_multispeed_fixed_fiber(hw,
215 : : highest_link_speed, autoneg_wait_to_complete);
216 : :
217 : 0 : out:
218 : : /* Set autoneg_advertised value based on input link speed */
219 : 0 : hw->phy.autoneg_advertised = 0;
220 : :
221 [ # # ]: 0 : if (speed & IXGBE_LINK_SPEED_10GB_FULL)
222 : 0 : hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
223 : :
224 [ # # ]: 0 : if (speed & IXGBE_LINK_SPEED_1GB_FULL)
225 : 0 : hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
226 : :
227 : : return status;
228 : : }
229 : :
230 : : static enum ixgbe_media_type
231 : 0 : ixgbe_bypass_get_media_type(struct ixgbe_hw *hw)
232 : : {
233 : : enum ixgbe_media_type media_type;
234 : :
235 : 0 : PMD_INIT_FUNC_TRACE();
236 : :
237 [ # # ]: 0 : if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
238 : : media_type = ixgbe_media_type_fiber;
239 : : } else {
240 : 0 : media_type = ixgbe_get_media_type_82599(hw);
241 : : }
242 : 0 : return media_type;
243 : : }
244 : :
245 : : /*
246 : : * Wrapper around shared code (base driver) to support BYPASS nic.
247 : : */
248 : : s32
249 : 0 : ixgbe_bypass_init_shared_code(struct ixgbe_hw *hw)
250 : : {
251 : : s32 ret_val;
252 : :
253 [ # # ]: 0 : if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
254 : 0 : hw->mac.type = ixgbe_mac_82599EB;
255 : : }
256 : :
257 : 0 : ret_val = ixgbe_init_shared_code(hw);
258 [ # # ]: 0 : if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
259 : 0 : hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
260 : 0 : ixgbe_init_mac_link_ops_82599(hw);
261 : : }
262 : :
263 : 0 : return ret_val;
264 : : }
265 : :
266 : : s32
267 : 0 : ixgbe_bypass_init_hw(struct ixgbe_hw *hw)
268 : : {
269 : : int rc;
270 : :
271 : 0 : rc = ixgbe_init_hw(hw);
272 [ # # # # ]: 0 : if (rc == 0 && hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
273 : :
274 : 0 : hw->mac.ops.setup_link =
275 : : &ixgbe_setup_mac_link_multispeed_fixed_fiber;
276 : :
277 : 0 : hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
278 : :
279 : 0 : hw->mac.ops.disable_tx_laser = NULL;
280 : 0 : hw->mac.ops.enable_tx_laser = NULL;
281 : 0 : hw->mac.ops.flap_tx_laser = NULL;
282 : : }
283 : :
284 : 0 : return rc;
285 : : }
|