pipeline: add check against loops
[dpdk.git] / drivers / net / ixgbe / ixgbe_82599_bypass.c
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 ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
24 {
25         s32 status;
26         u8 rs, eeprom_data;
27
28         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         default:
37                 PMD_DRV_LOG(ERR, "Invalid fixed module speed");
38                 return;
39         }
40
41         /* Set RS0 */
42         status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
43                                            IXGBE_I2C_EEPROM_DEV_ADDR2,
44                                            &eeprom_data);
45         if (status) {
46                 PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS0");
47                 goto out;
48         }
49
50         eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
51
52         status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
53                                             IXGBE_I2C_EEPROM_DEV_ADDR2,
54                                             eeprom_data);
55         if (status) {
56                 PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS0");
57                 goto out;
58         }
59
60         /* Set RS1 */
61         status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
62                                            IXGBE_I2C_EEPROM_DEV_ADDR2,
63                                            &eeprom_data);
64         if (status) {
65                 PMD_DRV_LOG(ERR, "Failed to read Rx Rate Select RS1");
66                 goto out;
67         }
68
69         eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
70
71         status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
72                                             IXGBE_I2C_EEPROM_DEV_ADDR2,
73                                             eeprom_data);
74         if (status) {
75                 PMD_DRV_LOG(ERR, "Failed to write Rx Rate Select RS1");
76                 goto out;
77         }
78 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 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         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         u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
100         u32 i = 0;
101         bool link_up = false;
102         bool negotiation;
103
104         PMD_INIT_FUNC_TRACE();
105
106         /* Mask off requested but non-supported speeds */
107         status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
108         if (status != IXGBE_SUCCESS)
109                 return status;
110
111         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         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                 status = ixgbe_check_link(hw, &link_speed, &link_up, false);
123                 if (status != IXGBE_SUCCESS)
124                         return status;
125
126                 if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
127                         goto out;
128                 /* Set the module link speed */
129                 ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_10GB_FULL);
130
131                 /* Set the module link speed */
132                 esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
133                 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
134                 IXGBE_WRITE_FLUSH(hw);
135
136                 /* Allow module to change analog characteristics (1G->10G) */
137                 msec_delay(40);
138
139                 status = ixgbe_setup_mac_link_82599(hw,
140                                                     IXGBE_LINK_SPEED_10GB_FULL,
141                                                     autoneg_wait_to_complete);
142                 if (status != IXGBE_SUCCESS)
143                         return status;
144
145                 /* Flap the tx laser if it has not already been done */
146                 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                 for (i = 0; i < 5; i++) {
154                         /* Wait for the link partner to also set speed */
155                         msec_delay(100);
156
157                         /* If we have link, just jump out */
158                         status = ixgbe_check_link(hw, &link_speed,
159                                                   &link_up, false);
160                         if (status != IXGBE_SUCCESS)
161                                 return status;
162
163                         if (link_up)
164                                 goto out;
165                 }
166         }
167
168         if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
169                 speedcnt++;
170                 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                 status = ixgbe_check_link(hw, &link_speed, &link_up, false);
175                 if (status != IXGBE_SUCCESS)
176                         return status;
177
178                 if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
179                         goto out;
180
181                 /* Set the module link speed */
182                 ixgbe_set_fiber_fixed_speed(hw, IXGBE_LINK_SPEED_1GB_FULL);
183
184                 /* Allow module to change analog characteristics (10G->1G) */
185                 msec_delay(40);
186
187                 status = ixgbe_setup_mac_link_82599(hw,
188                                                     IXGBE_LINK_SPEED_1GB_FULL,
189                                                     autoneg_wait_to_complete);
190                 if (status != IXGBE_SUCCESS)
191                         return status;
192
193                 /* Flap the tx laser if it has not already been done */
194                 ixgbe_flap_tx_laser(hw);
195
196                 /* Wait for the link partner to also set speed */
197                 msec_delay(100);
198
199                 /* If we have link, just jump out */
200                 status = ixgbe_check_link(hw, &link_speed, &link_up, false);
201                 if (status != IXGBE_SUCCESS)
202                         return status;
203
204                 if (link_up)
205                         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         if (speedcnt > 1)
214                 status = ixgbe_setup_mac_link_multispeed_fixed_fiber(hw,
215                         highest_link_speed, autoneg_wait_to_complete);
216
217 out:
218         /* Set autoneg_advertised value based on input link speed */
219         hw->phy.autoneg_advertised = 0;
220
221         if (speed & IXGBE_LINK_SPEED_10GB_FULL)
222                 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
223
224         if (speed & IXGBE_LINK_SPEED_1GB_FULL)
225                 hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
226
227         return status;
228 }
229
230 static enum ixgbe_media_type
231 ixgbe_bypass_get_media_type(struct ixgbe_hw *hw)
232 {
233         enum ixgbe_media_type media_type;
234
235         PMD_INIT_FUNC_TRACE();
236
237         if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
238                 media_type = ixgbe_media_type_fiber;
239         } else {
240                 media_type = ixgbe_get_media_type_82599(hw);
241         }
242         return media_type;
243 }
244
245 /*
246  * Wrapper around shared code (base driver) to support BYPASS nic.
247  */
248 s32
249 ixgbe_bypass_init_shared_code(struct ixgbe_hw *hw)
250 {
251         s32 ret_val;
252
253         if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
254                 hw->mac.type = ixgbe_mac_82599EB;
255         }
256
257         ret_val = ixgbe_init_shared_code(hw);
258         if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
259                 hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
260                 ixgbe_init_mac_link_ops_82599(hw);
261         }
262
263         return ret_val;
264 }
265
266 s32
267 ixgbe_bypass_init_hw(struct ixgbe_hw *hw)
268 {
269         int rc;
270
271         rc  = ixgbe_init_hw(hw);
272         if (rc == 0 && hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
273
274                 hw->mac.ops.setup_link =
275                         &ixgbe_setup_mac_link_multispeed_fixed_fiber;
276
277                 hw->mac.ops.get_media_type = &ixgbe_bypass_get_media_type;
278
279                 hw->mac.ops.disable_tx_laser = NULL;
280                 hw->mac.ops.enable_tx_laser = NULL;
281                 hw->mac.ops.flap_tx_laser = NULL;
282         }
283
284         return rc;
285 }