76d75fb922f406100f436d1061eb220beebdf463
[dpdk.git] / 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         if ((rc  = ixgbe_init_hw(hw)) == 0 &&
301                         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 }