]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/drivers/net/ixgbe/ixgbe_82599_bypass.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / dpdk / drivers / net / ixgbe / ixgbe_82599_bypass.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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
16 * distribution.
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.
20 *
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.
32 */
33
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"
41
42 /**
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
46 *
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.
50 */
51 static void
52 ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
53 {
54 s32 status;
55 u8 rs, eeprom_data;
56
57 switch (speed) {
58 case IXGBE_LINK_SPEED_10GB_FULL:
59 /* one bit mask same as setting on */
60 rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
61 break;
62 case IXGBE_LINK_SPEED_1GB_FULL:
63 rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
64 break;
65 default:
66 PMD_DRV_LOG(ERR, "Invalid fixed module speed");
67 return;
68 }
69
70 /* Set RS0 */
71 status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
72 IXGBE_I2C_EEPROM_DEV_ADDR2,
73 &eeprom_data);
74 if (status) {
75 PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS0");
76 goto out;
77 }
78
79 eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
80
81 status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
82 IXGBE_I2C_EEPROM_DEV_ADDR2,
83 eeprom_data);
84 if (status) {
85 PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS0");
86 goto out;
87 }
88
89 /* Set RS1 */
90 status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
91 IXGBE_I2C_EEPROM_DEV_ADDR2,
92 &eeprom_data);
93 if (status) {
94 PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS1");
95 goto out;
96 }
97
98 eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
99
100 status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
101 IXGBE_I2C_EEPROM_DEV_ADDR2,
102 eeprom_data);
103 if (status) {
104 PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS1");
105 goto out;
106 }
107 out:
108 return;
109 }
110
111 /**
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
116 *
117 * Set the link speed in the AUTOC register and restarts link.
118 **/
119 static s32
120 ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw,
121 ixgbe_link_speed speed,
122 bool autoneg_wait_to_complete)
123 {
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;
127 u32 speedcnt = 0;
128 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
129 u32 i = 0;
130 bool link_up = false;
131 bool negotiation;
132
133 PMD_INIT_FUNC_TRACE();
134
135 /* Mask off requested but non-supported speeds */
136 status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
137 if (status != IXGBE_SUCCESS)
138 return status;
139
140 speed &= link_speed;
141
142 /*
143 * Try each speed one by one, highest priority first. We do this in
144 * software because 10gb fiber doesn't support speed autonegotiation.
145 */
146 if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
147 speedcnt++;
148 highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
149
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)
153 return status;
154
155 if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
156 goto out;
157 /* Set the module link speed */
158 ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_10GB_FULL);
159
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);
164
165 /* Allow module to change analog characteristics (1G->10G) */
166 msec_delay(40);
167
168 status = ixgbe_setup_mac_link_82599(hw,
169 IXGBE_LINK_SPEED_10GB_FULL,
170 autoneg_wait_to_complete);
171 if (status != IXGBE_SUCCESS)
172 return status;
173
174 /* Flap the tx laser if it has not already been done */
175 ixgbe_flap_tx_laser(hw);
176
177 /*
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.
181 */
182 for (i = 0; i < 5; i++) {
183 /* Wait for the link partner to also set speed */
184 msec_delay(100);
185
186 /* If we have link, just jump out */
187 status = ixgbe_check_link(hw, &link_speed,
188 &link_up, false);
189 if (status != IXGBE_SUCCESS)
190 return status;
191
192 if (link_up)
193 goto out;
194 }
195 }
196
197 if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
198 speedcnt++;
199 if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
200 highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
201
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)
205 return status;
206
207 if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
208 goto out;
209
210 /* Set the module link speed */
211 ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_1GB_FULL);
212
213 /* Allow module to change analog characteristics (10G->1G) */
214 msec_delay(40);
215
216 status = ixgbe_setup_mac_link_82599(hw,
217 IXGBE_LINK_SPEED_1GB_FULL,
218 autoneg_wait_to_complete);
219 if (status != IXGBE_SUCCESS)
220 return status;
221
222 /* Flap the tx laser if it has not already been done */
223 ixgbe_flap_tx_laser(hw);
224
225 /* Wait for the link partner to also set speed */
226 msec_delay(100);
227
228 /* If we have link, just jump out */
229 status = ixgbe_check_link(hw, &link_speed, &link_up, false);
230 if (status != IXGBE_SUCCESS)
231 return status;
232
233 if (link_up)
234 goto out;
235 }
236
237 /*
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.
241 */
242 if (speedcnt > 1)
243 status = ixgbe_setup_mac_link_multispeed_fixed_fiber(hw,
244 highest_link_speed, autoneg_wait_to_complete);
245
246 out:
247 /* Set autoneg_advertised value based on input link speed */
248 hw->phy.autoneg_advertised = 0;
249
250 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
251 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
252
253 if (speed & IXGBE_LINK_SPEED_1GB_FULL)
254 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
255
256 return status;
257 }
258
259 static enum ixgbe_media_type
260 ixgbe_bypass_get_media_type(struct ixgbe_hw *hw)
261 {
262 enum ixgbe_media_type media_type;
263
264 PMD_INIT_FUNC_TRACE();
265
266 if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
267 media_type = ixgbe_media_type_fiber;
268 } else {
269 media_type = ixgbe_get_media_type_82599(hw);
270 }
271 return media_type;
272 }
273
274 /*
275 * Wrapper around shared code (base driver) to support BYPASS nic.
276 */
277 s32
278 ixgbe_bypass_init_shared_code(struct ixgbe_hw *hw)
279 {
280 s32 ret_val;
281
282 if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
283 hw->mac.type = ixgbe_mac_82599EB;
284 }
285
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);
290 }
291
292 return ret_val;
293 }
294
295 s32
296 ixgbe_bypass_init_hw(struct ixgbe_hw *hw)
297 {
298 int rc;
299
300 rc = ixgbe_init_hw(hw);
301 if (rc == 0 && hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
302
303 hw->mac.ops.setup_link =
304 &ixgbe_setup_mac_link_multispeed_fixed_fiber;
305
306 hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
307
308 hw->mac.ops.disable_tx_laser = NULL;
309 hw->mac.ops.enable_tx_laser = NULL;
310 hw->mac.ops.flap_tx_laser = NULL;
311 }
312
313 return rc;
314 }