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
ixgbe_set_fiber_fixed_speed(struct ixgbe_hw * hw,ixgbe_link_speed speed)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
ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)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
ixgbe_bypass_get_media_type(struct ixgbe_hw * hw)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
ixgbe_bypass_init_shared_code(struct ixgbe_hw * hw)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
ixgbe_bypass_init_hw(struct ixgbe_hw * hw)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 }
286