xref: /openbsd/sys/dev/pci/ixgbe_x550.c (revision 0f9e9ec2)
1 /*	$OpenBSD: ixgbe_x550.c,v 1.9 2024/05/13 01:15:51 jsg Exp $	*/
2 
3 /******************************************************************************
4 
5   Copyright (c) 2001-2017, Intel Corporation
6   All rights reserved.
7 
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions are met:
10 
11    1. Redistributions of source code must retain the above copyright notice,
12       this list of conditions and the following disclaimer.
13 
14    2. Redistributions in binary form must reproduce the above copyright
15       notice, this list of conditions and the following disclaimer in the
16       documentation and/or other materials provided with the distribution.
17 
18    3. Neither the name of the Intel Corporation nor the names of its
19       contributors may be used to endorse or promote products derived from
20       this software without specific prior written permission.
21 
22   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32   POSSIBILITY OF SUCH DAMAGE.
33 
34 ******************************************************************************/
35 /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x550.c 333870 2018-05-19 05:57:26Z mmacy $*/
36 
37 #include <dev/pci/ixgbe.h>
38 #include <dev/pci/ixgbe_type.h>
39 
40 extern int32_t ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
41 extern int32_t ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask);
42 extern void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, uint32_t mask);
43 
44 int32_t ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, uint32_t mask);
45 void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, uint32_t mask);
46 int32_t ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
47 
48 int32_t ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
49                                     ixgbe_link_speed speed,
50                                     bool autoneg_wait_to_complete);
51 
52 int32_t ixgbe_dmac_config_X550(struct ixgbe_hw *hw);
53 int32_t ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw);
54 int32_t ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw);
55 
56 int32_t ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw);
57 int32_t ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw);
58 int32_t ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw);
59 int32_t ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw);
60 int32_t ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, uint16_t *buffer,
61 				 uint32_t buffer_size);
62 int32_t ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
63 					    uint16_t *checksum_val);
64 int32_t ixgbe_update_flash_X550(struct ixgbe_hw *hw);
65 int32_t ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset,
66 			       uint16_t data);
67 int32_t ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
68 					 uint16_t offset, uint16_t words,
69 					 uint16_t *data);
70 int32_t ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset,
71 				  uint16_t *data);
72 int32_t ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, uint16_t offset,
73 					uint16_t data);
74 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
75 					   unsigned int pool);
76 int32_t ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr,
77 				     uint32_t device_type, uint32_t data);
78 int32_t ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr,
79 				    uint32_t device_type, uint32_t *data);
80 int32_t ixgbe_get_phy_token(struct ixgbe_hw *);
81 int32_t ixgbe_put_phy_token(struct ixgbe_hw *);
82 int32_t ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
83 	uint32_t device_type, uint32_t data);
84 int32_t ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
85 	uint32_t device_type, uint32_t *data);
86 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw);
87 int32_t ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw);
88 int32_t ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
89 					   ixgbe_link_speed *speed,
90 					   bool *autoneg);
91 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw);
92 int32_t ixgbe_reset_hw_X550em(struct ixgbe_hw *hw);
93 int32_t ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw);
94 int32_t ixgbe_setup_kr_x550em(struct ixgbe_hw *hw);
95 int32_t ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw);
96 int32_t ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw);
97 int32_t ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw);
98 uint64_t ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw);
99 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw);
100 int32_t ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed);
101 int32_t ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw);
102 int32_t ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask);
103 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask);
104 int32_t ixgbe_setup_fc_X550em(struct ixgbe_hw *hw);
105 int32_t ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
106 					ixgbe_link_speed speed,
107 					bool autoneg_wait_to_complete);
108 int32_t ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
109 			       uint32_t device_type, uint16_t *phy_data);
110 int32_t ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
111 				uint32_t device_type, uint16_t phy_data);
112 int32_t ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw);
113 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw);
114 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw);
115 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw);
116 int32_t ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw);
117 int32_t ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
118 				      ixgbe_link_speed speed,
119 				      bool autoneg_wait_to_complete);
120 int32_t ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
121 				  bool *link_up, bool link_up_wait_to_complete);
122 int32_t ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw);
123 int32_t ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw);
124 int32_t ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx);
125 int32_t ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx);
126 
127 int32_t ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
128 
129 
130 /**
131  *  ixgbe_init_ops_X550 - Inits func ptrs and MAC type
132  *  @hw: pointer to hardware structure
133  *
134  *  Initialize the function pointers and assign the MAC type for X550.
135  *  Does not touch the hardware.
136  **/
ixgbe_init_ops_X550(struct ixgbe_hw * hw)137 int32_t ixgbe_init_ops_X550(struct ixgbe_hw *hw)
138 {
139 	struct ixgbe_mac_info *mac = &hw->mac;
140 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
141 	int32_t ret_val;
142 
143 	DEBUGFUNC("ixgbe_init_ops_X550");
144 
145 	ret_val = ixgbe_init_ops_X540(hw);
146 	mac->ops.dmac_config = ixgbe_dmac_config_X550;
147 	mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
148 	mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
149 	mac->ops.setup_eee = NULL;
150 	mac->ops.set_source_address_pruning =
151 			ixgbe_set_source_address_pruning_X550;
152 
153 	eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
154 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
155 	eeprom->ops.read = ixgbe_read_ee_hostif_X550;
156 	eeprom->ops.write = ixgbe_write_ee_hostif_X550;
157 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
158 	eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
159 
160 	mac->ops.disable_rx = ixgbe_disable_rx_x550;
161 	switch (hw->device_id) {
162 	case IXGBE_DEV_ID_X550EM_X_1G_T:
163 		hw->mac.ops.led_on = NULL;
164 		hw->mac.ops.led_off = NULL;
165 		break;
166 	case IXGBE_DEV_ID_X550EM_X_10G_T:
167 	case IXGBE_DEV_ID_X550EM_A_10G_T:
168 		hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
169 		hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
170 		break;
171 	default:
172 		break;
173 	}
174 	return ret_val;
175 }
176 
177 /**
178  * ixgbe_read_cs4227 - Read CS4227 register
179  * @hw: pointer to hardware structure
180  * @reg: register number to write
181  * @value: pointer to receive value read
182  *
183  * Returns status code
184  **/
ixgbe_read_cs4227(struct ixgbe_hw * hw,uint16_t reg,uint16_t * value)185 int32_t ixgbe_read_cs4227(struct ixgbe_hw *hw, uint16_t reg, uint16_t *value)
186 {
187 	return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
188 }
189 
190 /**
191  * ixgbe_write_cs4227 - Write CS4227 register
192  * @hw: pointer to hardware structure
193  * @reg: register number to write
194  * @value: value to write to register
195  *
196  * Returns status code
197  **/
ixgbe_write_cs4227(struct ixgbe_hw * hw,uint16_t reg,uint16_t value)198 int32_t ixgbe_write_cs4227(struct ixgbe_hw *hw, uint16_t reg, uint16_t value)
199 {
200 	return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
201 }
202 
203 /**
204  * ixgbe_read_pe - Read register from port expander
205  * @hw: pointer to hardware structure
206  * @reg: register number to read
207  * @value: pointer to receive read value
208  *
209  * Returns status code
210  **/
ixgbe_read_pe(struct ixgbe_hw * hw,uint8_t reg,uint8_t * value)211 int32_t ixgbe_read_pe(struct ixgbe_hw *hw, uint8_t reg, uint8_t *value)
212 {
213 	int32_t status = IXGBE_NOT_IMPLEMENTED;
214 
215 	if (hw->phy.ops.read_i2c_byte_unlocked)
216 		status = hw->phy.ops.read_i2c_byte_unlocked(hw, reg, IXGBE_PE,
217 		    value);
218 	if (status != IXGBE_SUCCESS)
219 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
220 			      "port expander access failed with %d\n", status);
221 	return status;
222 }
223 
224 /**
225  * ixgbe_write_pe - Write register to port expander
226  * @hw: pointer to hardware structure
227  * @reg: register number to write
228  * @value: value to write
229  *
230  * Returns status code
231  **/
ixgbe_write_pe(struct ixgbe_hw * hw,uint8_t reg,uint8_t value)232 int32_t ixgbe_write_pe(struct ixgbe_hw *hw, uint8_t reg, uint8_t value)
233 {
234 	int32_t status = IXGBE_NOT_IMPLEMENTED;
235 
236 	if (hw->phy.ops.write_i2c_byte_unlocked)
237 		status = hw->phy.ops.write_i2c_byte_unlocked(hw, reg, IXGBE_PE,
238 		    value);
239 	if (status != IXGBE_SUCCESS)
240 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
241 			      "port expander access failed with %d\n", status);
242 	return status;
243 }
244 
245 /**
246  * ixgbe_reset_cs4227 - Reset CS4227 using port expander
247  * @hw: pointer to hardware structure
248  *
249  * This function assumes that the caller has acquired the proper semaphore.
250  * Returns error code
251  **/
ixgbe_reset_cs4227(struct ixgbe_hw * hw)252 int32_t ixgbe_reset_cs4227(struct ixgbe_hw *hw)
253 {
254 	int32_t status;
255 	uint32_t retry;
256 	uint16_t value;
257 	uint8_t reg;
258 
259 	/* Trigger hard reset. */
260 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
261 	if (status != IXGBE_SUCCESS)
262 		return status;
263 	reg |= IXGBE_PE_BIT1;
264 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
265 	if (status != IXGBE_SUCCESS)
266 		return status;
267 
268 	status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
269 	if (status != IXGBE_SUCCESS)
270 		return status;
271 	reg &= ~IXGBE_PE_BIT1;
272 	status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
273 	if (status != IXGBE_SUCCESS)
274 		return status;
275 
276 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
277 	if (status != IXGBE_SUCCESS)
278 		return status;
279 	reg &= ~IXGBE_PE_BIT1;
280 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
281 	if (status != IXGBE_SUCCESS)
282 		return status;
283 
284 	usec_delay(IXGBE_CS4227_RESET_HOLD);
285 
286 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
287 	if (status != IXGBE_SUCCESS)
288 		return status;
289 	reg |= IXGBE_PE_BIT1;
290 	status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
291 	if (status != IXGBE_SUCCESS)
292 		return status;
293 
294 	/* Wait for the reset to complete. */
295 	msec_delay(IXGBE_CS4227_RESET_DELAY);
296 	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
297 		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
298 					   &value);
299 		if (status == IXGBE_SUCCESS &&
300 		    value == IXGBE_CS4227_EEPROM_LOAD_OK)
301 			break;
302 		msec_delay(IXGBE_CS4227_CHECK_DELAY);
303 	}
304 	if (retry == IXGBE_CS4227_RETRIES) {
305 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
306 			"CS4227 reset did not complete.");
307 		return IXGBE_ERR_PHY;
308 	}
309 
310 	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
311 	if (status != IXGBE_SUCCESS ||
312 	    !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
313 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
314 			"CS4227 EEPROM did not load successfully.");
315 		return IXGBE_ERR_PHY;
316 	}
317 
318 	return IXGBE_SUCCESS;
319 }
320 
321 /**
322  * ixgbe_check_cs4227 - Check CS4227 and reset as needed
323  * @hw: pointer to hardware structure
324  **/
ixgbe_check_cs4227(struct ixgbe_hw * hw)325 void ixgbe_check_cs4227(struct ixgbe_hw *hw)
326 {
327 	int32_t status = IXGBE_SUCCESS;
328 	uint32_t swfw_mask = hw->phy.phy_semaphore_mask;
329 	uint16_t value = 0;
330 	uint8_t retry;
331 
332 	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
333 		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
334 		if (status != IXGBE_SUCCESS) {
335 			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
336 				"semaphore failed with %d", status);
337 			msec_delay(IXGBE_CS4227_CHECK_DELAY);
338 			continue;
339 		}
340 
341 		/* Get status of reset flow. */
342 		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
343 
344 		if (status == IXGBE_SUCCESS &&
345 		    value == IXGBE_CS4227_RESET_COMPLETE)
346 			goto out;
347 
348 		if (status != IXGBE_SUCCESS ||
349 		    value != IXGBE_CS4227_RESET_PENDING)
350 			break;
351 
352 		/* Reset is pending. Wait and check again. */
353 		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
354 		msec_delay(IXGBE_CS4227_CHECK_DELAY);
355 	}
356 
357 	/* If still pending, assume other instance failed. */
358 	if (retry == IXGBE_CS4227_RETRIES) {
359 		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
360 		if (status != IXGBE_SUCCESS) {
361 			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
362 				      "semaphore failed with %d", status);
363 			return;
364 		}
365 	}
366 
367 	/* Reset the CS4227. */
368 	status = ixgbe_reset_cs4227(hw);
369 	if (status != IXGBE_SUCCESS) {
370 		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
371 			"CS4227 reset failed: %d", status);
372 		goto out;
373 	}
374 
375 	/* Reset takes so long, temporarily release semaphore in case the
376 	 * other driver instance is waiting for the reset indication.
377 	 */
378 	ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
379 			   IXGBE_CS4227_RESET_PENDING);
380 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
381 	msec_delay(10);
382 	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
383 	if (status != IXGBE_SUCCESS) {
384 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
385 			"semaphore failed with %d", status);
386 		return;
387 	}
388 
389 	/* Record completion for next time. */
390 	status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
391 		IXGBE_CS4227_RESET_COMPLETE);
392 
393 out:
394 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
395 	msec_delay(hw->eeprom.semaphore_delay);
396 }
397 
398 /**
399  * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
400  * @hw: pointer to hardware structure
401  **/
ixgbe_setup_mux_ctl(struct ixgbe_hw * hw)402 void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
403 {
404 	uint32_t esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
405 
406 	if (hw->bus.lan_id) {
407 		esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
408 		esdp |= IXGBE_ESDP_SDP1_DIR;
409 	}
410 	esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
411 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
412 	IXGBE_WRITE_FLUSH(hw);
413 }
414 
415 /**
416  * ixgbe_identify_phy_x550em - Get PHY type based on device id
417  * @hw: pointer to hardware structure
418  *
419  * Returns error code
420  */
ixgbe_identify_phy_x550em(struct ixgbe_hw * hw)421 int32_t ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
422 {
423 	hw->mac.ops.set_lan_id(hw);
424 
425 	ixgbe_read_mng_if_sel_x550em(hw);
426 
427 	switch (hw->device_id) {
428 	case IXGBE_DEV_ID_X550EM_A_SFP:
429 		return ixgbe_identify_module_generic(hw);
430 	case IXGBE_DEV_ID_X550EM_X_SFP:
431 		/* set up for CS4227 usage */
432 		ixgbe_setup_mux_ctl(hw);
433 		ixgbe_check_cs4227(hw);
434 		/* Fallthrough */
435 
436 	case IXGBE_DEV_ID_X550EM_A_SFP_N:
437 		return ixgbe_identify_module_generic(hw);
438 		break;
439 	case IXGBE_DEV_ID_X550EM_X_KX4:
440 		hw->phy.type = ixgbe_phy_x550em_kx4;
441 		break;
442 	case IXGBE_DEV_ID_X550EM_X_XFI:
443 		hw->phy.type = ixgbe_phy_x550em_xfi;
444 		break;
445 	case IXGBE_DEV_ID_X550EM_X_KR:
446 	case IXGBE_DEV_ID_X550EM_A_KR:
447 	case IXGBE_DEV_ID_X550EM_A_KR_L:
448 		hw->phy.type = ixgbe_phy_x550em_kr;
449 		break;
450 	case IXGBE_DEV_ID_X550EM_A_10G_T:
451 	case IXGBE_DEV_ID_X550EM_X_10G_T:
452 		return ixgbe_identify_phy_generic(hw);
453 	case IXGBE_DEV_ID_X550EM_X_1G_T:
454 		hw->phy.type = ixgbe_phy_ext_1g_t;
455 		break;
456 	case IXGBE_DEV_ID_X550EM_A_1G_T:
457 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
458 		hw->phy.type = ixgbe_phy_fw;
459 		if (hw->bus.lan_id)
460 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
461 		else
462 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
463 		break;
464 	default:
465 		break;
466 	}
467 	return IXGBE_SUCCESS;
468 }
469 
470 /**
471  * ixgbe_fw_phy_activity - Perform an activity on a PHY
472  * @hw: pointer to hardware structure
473  * @activity: activity to perform
474  * @data: Pointer to 4 32-bit words of data
475  */
ixgbe_fw_phy_activity(struct ixgbe_hw * hw,uint16_t activity,uint32_t (* data)[FW_PHY_ACT_DATA_COUNT])476 int32_t ixgbe_fw_phy_activity(struct ixgbe_hw *hw, uint16_t activity,
477 			  uint32_t (*data)[FW_PHY_ACT_DATA_COUNT])
478 {
479 	union {
480 		struct ixgbe_hic_phy_activity_req cmd;
481 		struct ixgbe_hic_phy_activity_resp rsp;
482 	} hic;
483 	uint16_t retries = FW_PHY_ACT_RETRIES;
484 	int32_t rc;
485 	uint16_t i;
486 
487 	do {
488 		memset(&hic, 0, sizeof(hic));
489 		hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
490 		hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
491 		hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
492 		hic.cmd.port_number = hw->bus.lan_id;
493 		hic.cmd.activity_id = htole16(activity);
494 		for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
495 			hic.cmd.data[i] = htobe32((*data)[i]);
496 
497 		rc = ixgbe_host_interface_command(hw, (uint32_t *)&hic.cmd,
498 						  sizeof(hic.cmd),
499 						  IXGBE_HI_COMMAND_TIMEOUT,
500 						  TRUE);
501 		if (rc != IXGBE_SUCCESS)
502 			return rc;
503 		if (hic.rsp.hdr.cmd_or_resp.ret_status ==
504 		    FW_CEM_RESP_STATUS_SUCCESS) {
505 			for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
506 				(*data)[i] = betoh32(hic.rsp.data[i]);
507 			return IXGBE_SUCCESS;
508 		}
509 		usec_delay(20);
510 		--retries;
511 	} while (retries > 0);
512 
513 	return IXGBE_ERR_HOST_INTERFACE_COMMAND;
514 }
515 
516 static const struct {
517 	uint16_t fw_speed;
518 	ixgbe_link_speed phy_speed;
519 } ixgbe_fw_map[] = {
520 	{ FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
521 	{ FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
522 	{ FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
523 	{ FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
524 	{ FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
525 	{ FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
526 };
527 
528 /**
529  * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
530  * @hw: pointer to hardware structure
531  *
532  * Returns error code
533  */
ixgbe_get_phy_id_fw(struct ixgbe_hw * hw)534 int32_t ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
535 {
536 	uint32_t info[FW_PHY_ACT_DATA_COUNT] = { 0 };
537 	uint16_t phy_speeds;
538 	uint16_t phy_id_lo;
539 	int32_t rc;
540 	uint16_t i;
541 
542 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
543 	if (rc)
544 		return rc;
545 
546 	hw->phy.speeds_supported = 0;
547 	phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
548 	for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
549 		if (phy_speeds & ixgbe_fw_map[i].fw_speed)
550 			hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
551 	}
552 	if (!hw->phy.autoneg_advertised)
553 		hw->phy.autoneg_advertised = hw->phy.speeds_supported;
554 
555 	hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
556 	phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
557 	hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
558 	hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
559 	if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
560 		return IXGBE_ERR_PHY_ADDR_INVALID;
561 	return IXGBE_SUCCESS;
562 }
563 
564 /**
565  * ixgbe_identify_phy_fw - Get PHY type based on firmware command
566  * @hw: pointer to hardware structure
567  *
568  * Returns error code
569  */
ixgbe_identify_phy_fw(struct ixgbe_hw * hw)570 int32_t ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
571 {
572 	if (hw->bus.lan_id)
573 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
574 	else
575 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
576 
577 	hw->phy.type = ixgbe_phy_fw;
578 	hw->phy.ops.read_reg = NULL;
579 	hw->phy.ops.write_reg = NULL;
580 	return ixgbe_get_phy_id_fw(hw);
581 }
582 
583 /**
584  * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
585  * @hw: pointer to hardware structure
586  *
587  * Returns error code
588  */
ixgbe_shutdown_fw_phy(struct ixgbe_hw * hw)589 int32_t ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
590 {
591 	uint32_t setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
592 
593 	setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
594 	return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
595 }
596 
ixgbe_read_phy_reg_x550em(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint16_t * phy_data)597 int32_t ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, uint32_t reg_addr,
598 				  uint32_t device_type, uint16_t *phy_data)
599 {
600 	return IXGBE_NOT_IMPLEMENTED;
601 }
602 
ixgbe_write_phy_reg_x550em(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint16_t phy_data)603 int32_t ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, uint32_t reg_addr,
604 				   uint32_t device_type, uint16_t phy_data)
605 {
606 	return IXGBE_NOT_IMPLEMENTED;
607 }
608 
609 /**
610 *  ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
611 *  @hw: pointer to hardware structure
612 *
613 *  Initialize the function pointers and for MAC type X550EM.
614 *  Does not touch the hardware.
615 **/
ixgbe_init_ops_X550EM(struct ixgbe_hw * hw)616 int32_t ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
617 {
618 	struct ixgbe_mac_info *mac = &hw->mac;
619 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
620 	struct ixgbe_phy_info *phy = &hw->phy;
621 	int32_t ret_val;
622 
623 	DEBUGFUNC("ixgbe_init_ops_X550EM");
624 
625 	/* Similar to X550 so start there. */
626 	ret_val = ixgbe_init_ops_X550(hw);
627 
628 	/* Since this function eventually calls
629 	 * ixgbe_init_ops_540 by design, we are setting
630 	 * the pointers to NULL explicitly here to overwrite
631 	 * the values being set in the x540 function.
632 	 */
633 
634 	/* IPsec not supported in x550EM */
635 	mac->ops.disable_sec_rx_path = NULL;
636 	mac->ops.enable_sec_rx_path = NULL;
637 
638 	/* AUTOC register is not present in x550EM. */
639 	mac->ops.prot_autoc_read = NULL;
640 	mac->ops.prot_autoc_write = NULL;
641 
642 	/* X550EM bus type is internal*/
643 	hw->bus.type = ixgbe_bus_type_internal;
644 	mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
645 
646 
647 	mac->ops.get_media_type = ixgbe_get_media_type_X550em;
648 	mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
649 	mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
650 	mac->ops.reset_hw = ixgbe_reset_hw_X550em;
651 	mac->ops.get_supported_physical_layer =
652 				    ixgbe_get_supported_physical_layer_X550em;
653 
654 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
655 		mac->ops.setup_fc = ixgbe_setup_fc_generic;
656 	else
657 		mac->ops.setup_fc = ixgbe_setup_fc_X550em;
658 
659 	/* PHY */
660 	phy->ops.init = ixgbe_init_phy_ops_X550em;
661 	switch (hw->device_id) {
662 	case IXGBE_DEV_ID_X550EM_A_1G_T:
663 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
664 		mac->ops.setup_fc = NULL;
665 		phy->ops.identify = ixgbe_identify_phy_fw;
666 		phy->ops.set_phy_power = NULL;
667 		phy->ops.get_firmware_version = NULL;
668 		break;
669 	case IXGBE_DEV_ID_X550EM_X_1G_T:
670 		mac->ops.setup_fc = NULL;
671 		phy->ops.identify = ixgbe_identify_phy_x550em;
672 		phy->ops.set_phy_power = NULL;
673 		break;
674 	default:
675 		phy->ops.identify = ixgbe_identify_phy_x550em;
676 	}
677 
678 	if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
679 		phy->ops.set_phy_power = NULL;
680 
681 
682 	/* EEPROM */
683 	eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
684 	eeprom->ops.read = ixgbe_read_ee_hostif_X550;
685 	eeprom->ops.write = ixgbe_write_ee_hostif_X550;
686 	eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
687 	eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
688 	eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
689 
690 	return ret_val;
691 }
692 
693 /**
694  * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
695  * @hw: pointer to hardware structure
696  */
ixgbe_setup_fw_link(struct ixgbe_hw * hw)697 int32_t ixgbe_setup_fw_link(struct ixgbe_hw *hw)
698 {
699 	uint32_t setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
700 	int32_t rc;
701 	uint16_t i;
702 
703 	if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
704 		return 0;
705 
706 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
707 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
708 			      "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
709 		return IXGBE_ERR_INVALID_LINK_SETTINGS;
710 	}
711 
712 	switch (hw->fc.requested_mode) {
713 	case ixgbe_fc_full:
714 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
715 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
716 		break;
717 	case ixgbe_fc_rx_pause:
718 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
719 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
720 		break;
721 	case ixgbe_fc_tx_pause:
722 		setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
723 			    FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
724 		break;
725 	default:
726 		break;
727 	}
728 
729 	for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
730 		if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
731 			setup[0] |= ixgbe_fw_map[i].fw_speed;
732 	}
733 	setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
734 
735 	if (hw->phy.eee_speeds_advertised)
736 		setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
737 
738 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
739 	if (rc)
740 		return rc;
741 	if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
742 		return IXGBE_ERR_OVERTEMP;
743 	return IXGBE_SUCCESS;
744 }
745 
746 /**
747  * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
748  * @hw: pointer to hardware structure
749  *
750  *  Called at init time to set up flow control.
751  */
ixgbe_fc_autoneg_fw(struct ixgbe_hw * hw)752 int32_t ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
753 {
754 	if (hw->fc.requested_mode == ixgbe_fc_default)
755 		hw->fc.requested_mode = ixgbe_fc_full;
756 
757 	return ixgbe_setup_fw_link(hw);
758 }
759 
760 /**
761  * ixgbe_setup_eee_fw - Enable/disable EEE support
762  * @hw: pointer to the HW structure
763  * @enable_eee: boolean flag to enable EEE
764  *
765  * Enable/disable EEE based on enable_eee flag.
766  * This function controls EEE for firmware-based PHY implementations.
767  */
ixgbe_setup_eee_fw(struct ixgbe_hw * hw,bool enable_eee)768 int32_t ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
769 {
770 	if (!!hw->phy.eee_speeds_advertised == enable_eee)
771 		return IXGBE_SUCCESS;
772 	if (enable_eee)
773 		hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
774 	else
775 		hw->phy.eee_speeds_advertised = 0;
776 	return hw->phy.ops.setup_link(hw);
777 }
778 
779 /**
780 *  ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
781 *  @hw: pointer to hardware structure
782 *
783 *  Initialize the function pointers and for MAC type X550EM_a.
784 *  Does not touch the hardware.
785 **/
ixgbe_init_ops_X550EM_a(struct ixgbe_hw * hw)786 int32_t ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
787 {
788 	struct ixgbe_mac_info *mac = &hw->mac;
789 	int32_t ret_val;
790 
791 	DEBUGFUNC("ixgbe_init_ops_X550EM_a");
792 
793 	/* Start with generic X550EM init */
794 	ret_val = ixgbe_init_ops_X550EM(hw);
795 
796 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
797 	    hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
798 		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
799 		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
800 	} else {
801 		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
802 		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
803 	}
804 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
805 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
806 
807 	switch (mac->ops.get_media_type(hw)) {
808 	case ixgbe_media_type_fiber:
809 		mac->ops.setup_fc = NULL;
810 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
811 		break;
812 	case ixgbe_media_type_backplane:
813 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
814 		mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
815 		break;
816 	default:
817 		break;
818 	}
819 
820 	switch (hw->device_id) {
821 	case IXGBE_DEV_ID_X550EM_A_1G_T:
822 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
823 		mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
824 		mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
825 		mac->ops.setup_eee = ixgbe_setup_eee_fw;
826 		hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
827 					       IXGBE_LINK_SPEED_1GB_FULL;
828 		hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
829 		break;
830 	default:
831 		break;
832 	}
833 
834 	return ret_val;
835 }
836 
837 /**
838 *  ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
839 *  @hw: pointer to hardware structure
840 *
841 *  Initialize the function pointers and for MAC type X550EM_x.
842 *  Does not touch the hardware.
843 **/
ixgbe_init_ops_X550EM_x(struct ixgbe_hw * hw)844 int32_t ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
845 {
846 	struct ixgbe_mac_info *mac = &hw->mac;
847 	struct ixgbe_link_info *link = &hw->link;
848 	int32_t ret_val;
849 
850 	DEBUGFUNC("ixgbe_init_ops_X550EM_x");
851 
852 	/* Start with generic X550EM init */
853 	ret_val = ixgbe_init_ops_X550EM(hw);
854 
855 	mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
856 	mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
857 	mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
858 	mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
859 	link->ops.read_link = ixgbe_read_i2c_combined_generic;
860 	link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
861 	link->ops.write_link = ixgbe_write_i2c_combined_generic;
862 	link->ops.write_link_unlocked =
863 				      ixgbe_write_i2c_combined_generic_unlocked;
864 	link->addr = IXGBE_CS4227;
865 
866 	if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) {
867 		mac->ops.setup_fc = NULL;
868 		mac->ops.setup_eee = NULL;
869 	}
870 
871 	return ret_val;
872 }
873 
874 /**
875  *  ixgbe_dmac_config_X550
876  *  @hw: pointer to hardware structure
877  *
878  *  Configure DMA coalescing. If enabling dmac, dmac is activated.
879  *  When disabling dmac, dmac enable dmac bit is cleared.
880  **/
ixgbe_dmac_config_X550(struct ixgbe_hw * hw)881 int32_t ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
882 {
883 	uint32_t reg;
884 
885 	DEBUGFUNC("ixgbe_dmac_config_X550");
886 
887 	/* Disable DMA coalescing before configuring */
888 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
889 	reg &= ~IXGBE_DMACR_DMAC_EN;
890 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
891 
892 	/* Disable DMA Coalescing if the watchdog timer is 0 */
893 	if (!hw->mac.dmac_config.watchdog_timer)
894 		goto out;
895 
896 	ixgbe_dmac_config_tcs_X550(hw);
897 
898 	/* Configure DMA Coalescing Control Register */
899 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
900 
901 	/* Set the watchdog timer in units of 40.96 usec */
902 	reg &= ~IXGBE_DMACR_DMACWT_MASK;
903 	reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
904 
905 	reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
906 	reg |= IXGBE_DMACR_EN_MNG_IND;
907 
908 	/* Enable DMA coalescing after configuration */
909 	reg |= IXGBE_DMACR_DMAC_EN;
910 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
911 
912 out:
913 	return IXGBE_SUCCESS;
914 }
915 
916 /**
917  *  ixgbe_dmac_config_tcs_X550
918  *  @hw: pointer to hardware structure
919  *
920  *  Configure DMA coalescing threshold per TC. The dmac enable bit must
921  *  be cleared before configuring.
922  **/
ixgbe_dmac_config_tcs_X550(struct ixgbe_hw * hw)923 int32_t ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
924 {
925 	uint32_t tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
926 
927 	DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
928 
929 	/* Configure DMA coalescing enabled */
930 	switch (hw->mac.dmac_config.link_speed) {
931 	case IXGBE_LINK_SPEED_10_FULL:
932 	case IXGBE_LINK_SPEED_100_FULL:
933 		pb_headroom = IXGBE_DMACRXT_100M;
934 		break;
935 	case IXGBE_LINK_SPEED_1GB_FULL:
936 		pb_headroom = IXGBE_DMACRXT_1G;
937 		break;
938 	default:
939 		pb_headroom = IXGBE_DMACRXT_10G;
940 		break;
941 	}
942 
943 	maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
944 			     IXGBE_MHADD_MFS_SHIFT) / 1024);
945 
946 	/* Set the per Rx packet buffer receive threshold */
947 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
948 		reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
949 		reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
950 
951 		if (tc < hw->mac.dmac_config.num_tcs) {
952 			/* Get Rx PB size */
953 			rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
954 			rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
955 				IXGBE_RXPBSIZE_SHIFT;
956 
957 			/* Calculate receive buffer threshold in kilobytes */
958 			if (rx_pb_size > pb_headroom)
959 				rx_pb_size = rx_pb_size - pb_headroom;
960 			else
961 				rx_pb_size = 0;
962 
963 			/* Minimum of MFS shall be set for DMCTH */
964 			reg |= (rx_pb_size > maxframe_size_kb) ?
965 				rx_pb_size : maxframe_size_kb;
966 		}
967 		IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
968 	}
969 	return IXGBE_SUCCESS;
970 }
971 
972 /**
973  *  ixgbe_dmac_update_tcs_X550
974  *  @hw: pointer to hardware structure
975  *
976  *  Disables dmac, updates per TC settings, and then enables dmac.
977  **/
ixgbe_dmac_update_tcs_X550(struct ixgbe_hw * hw)978 int32_t ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
979 {
980 	uint32_t reg;
981 
982 	DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
983 
984 	/* Disable DMA coalescing before configuring */
985 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
986 	reg &= ~IXGBE_DMACR_DMAC_EN;
987 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
988 
989 	ixgbe_dmac_config_tcs_X550(hw);
990 
991 	/* Enable DMA coalescing after configuration */
992 	reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
993 	reg |= IXGBE_DMACR_DMAC_EN;
994 	IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
995 
996 	return IXGBE_SUCCESS;
997 }
998 
999 /**
1000  *  ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
1001  *  @hw: pointer to hardware structure
1002  *
1003  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
1004  *  ixgbe_hw struct in order to set up EEPROM access.
1005  **/
ixgbe_init_eeprom_params_X550(struct ixgbe_hw * hw)1006 int32_t ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
1007 {
1008 	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
1009 	uint32_t eec;
1010 	uint16_t eeprom_size;
1011 
1012 	DEBUGFUNC("ixgbe_init_eeprom_params_X550");
1013 
1014 	if (eeprom->type == ixgbe_eeprom_uninitialized) {
1015 		eeprom->semaphore_delay = 10;
1016 		eeprom->type = ixgbe_flash;
1017 
1018 		eec = IXGBE_READ_REG(hw, IXGBE_EEC);
1019 		eeprom_size = (uint16_t)((eec & IXGBE_EEC_SIZE) >>
1020 				    IXGBE_EEC_SIZE_SHIFT);
1021 		eeprom->word_size = 1 << (eeprom_size +
1022 					  IXGBE_EEPROM_WORD_SIZE_SHIFT);
1023 
1024 		DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
1025 			  eeprom->type, eeprom->word_size);
1026 	}
1027 
1028 	return IXGBE_SUCCESS;
1029 }
1030 
1031 /**
1032  * ixgbe_set_source_address_pruning_X550 - Enable/Disable source address pruning
1033  * @hw: pointer to hardware structure
1034  * @enable: enable or disable source address pruning
1035  * @pool: Rx pool to set source address pruning for
1036  **/
ixgbe_set_source_address_pruning_X550(struct ixgbe_hw * hw,bool enable,unsigned int pool)1037 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
1038 					   unsigned int pool)
1039 {
1040 	uint64_t pfflp;
1041 
1042 	/* max rx pool is 63 */
1043 	if (pool > 63)
1044 		return;
1045 
1046 	pfflp = (uint64_t)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
1047 	pfflp |= (uint64_t)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
1048 
1049 	if (enable)
1050 		pfflp |= (1ULL << pool);
1051 	else
1052 		pfflp &= ~(1ULL << pool);
1053 
1054 	IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (uint32_t)pfflp);
1055 	IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (uint32_t)(pfflp >> 32));
1056 }
1057 
1058 /**
1059  * ixgbe_iosf_wait - Wait for IOSF command completion
1060  * @hw: pointer to hardware structure
1061  * @ctrl: pointer to location to receive final IOSF control value
1062  *
1063  * Returns failing status on timeout
1064  *
1065  * Note: ctrl can be NULL if the IOSF control register value is not needed
1066  **/
ixgbe_iosf_wait(struct ixgbe_hw * hw,uint32_t * ctrl)1067 int32_t ixgbe_iosf_wait(struct ixgbe_hw *hw, uint32_t *ctrl)
1068 {
1069 	uint32_t i, command = 0;
1070 
1071 	/* Check every 10 usec to see if the address cycle completed.
1072 	 * The SB IOSF BUSY bit will clear when the operation is
1073 	 * complete
1074 	 */
1075 	for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
1076 		command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
1077 		if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
1078 			break;
1079 		usec_delay(10);
1080 	}
1081 	if (ctrl)
1082 		*ctrl = command;
1083 	if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
1084 		ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
1085 		return IXGBE_ERR_PHY;
1086 	}
1087 
1088 	return IXGBE_SUCCESS;
1089 }
1090 
1091 /**
1092  *  ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
1093  *  of the IOSF device
1094  *  @hw: pointer to hardware structure
1095  *  @reg_addr: 32 bit PHY register to write
1096  *  @device_type: 3 bit device type
1097  *  @data: Data to write to the register
1098  **/
ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint32_t data)1099 int32_t ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr,
1100 			    uint32_t device_type, uint32_t data)
1101 {
1102 	uint32_t gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1103 	uint32_t command, error __unused;
1104 	int32_t ret;
1105 
1106 	ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
1107 	if (ret != IXGBE_SUCCESS)
1108 		return ret;
1109 
1110 	ret = ixgbe_iosf_wait(hw, NULL);
1111 	if (ret != IXGBE_SUCCESS)
1112 		goto out;
1113 
1114 	command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1115 		   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1116 
1117 	/* Write IOSF control register */
1118 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1119 
1120 	/* Write IOSF data register */
1121 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
1122 
1123 	ret = ixgbe_iosf_wait(hw, &command);
1124 
1125 	if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1126 		error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1127 			 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1128 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
1129 			      "Failed to write, error %x\n", error);
1130 		ret = IXGBE_ERR_PHY;
1131 	}
1132 
1133 out:
1134 	hw->mac.ops.release_swfw_sync(hw, gssr);
1135 	return ret;
1136 }
1137 
1138 /**
1139  *  ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
1140  *  @hw: pointer to hardware structure
1141  *  @reg_addr: 32 bit PHY register to write
1142  *  @device_type: 3 bit device type
1143  *  @data: Pointer to read data from the register
1144  **/
ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint32_t * data)1145 int32_t ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, uint32_t reg_addr,
1146 			   uint32_t device_type, uint32_t *data)
1147 {
1148 	uint32_t gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1149 	uint32_t command, error __unused;
1150 	int32_t ret;
1151 
1152 	ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
1153 	if (ret != IXGBE_SUCCESS)
1154 		return ret;
1155 
1156 	ret = ixgbe_iosf_wait(hw, NULL);
1157 	if (ret != IXGBE_SUCCESS)
1158 		goto out;
1159 
1160 	command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1161 		   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1162 
1163 	/* Write IOSF control register */
1164 	IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1165 
1166 	ret = ixgbe_iosf_wait(hw, &command);
1167 
1168 	if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1169 		error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1170 			 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1171 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
1172 				"Failed to read, error %x\n", error);
1173 		ret = IXGBE_ERR_PHY;
1174 	}
1175 
1176 	if (ret == IXGBE_SUCCESS)
1177 		*data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
1178 
1179 out:
1180 	hw->mac.ops.release_swfw_sync(hw, gssr);
1181 	return ret;
1182 }
1183 
1184 /**
1185  * ixgbe_get_phy_token - Get the token for shared phy access
1186  * @hw: Pointer to hardware structure
1187  */
1188 
ixgbe_get_phy_token(struct ixgbe_hw * hw)1189 int32_t ixgbe_get_phy_token(struct ixgbe_hw *hw)
1190 {
1191 	struct ixgbe_hic_phy_token_req token_cmd;
1192 	int32_t status;
1193 
1194 	token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1195 	token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1196 	token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1197 	token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1198 	token_cmd.port_number = hw->bus.lan_id;
1199 	token_cmd.command_type = FW_PHY_TOKEN_REQ;
1200 	token_cmd.pad = 0;
1201 	status = ixgbe_host_interface_command(hw, (uint32_t *)&token_cmd,
1202 					      sizeof(token_cmd),
1203 					      IXGBE_HI_COMMAND_TIMEOUT,
1204 					      TRUE);
1205 	if (status) {
1206 		DEBUGOUT1("Issuing host interface command failed with Status = %d\n",
1207 			  status);
1208 		return status;
1209 	}
1210 	if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1211 		return IXGBE_SUCCESS;
1212 	if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) {
1213 		DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n",
1214 			  token_cmd.hdr.cmd_or_resp.ret_status);
1215 		return IXGBE_ERR_FW_RESP_INVALID;
1216 	}
1217 
1218 	DEBUGOUT("Returning  IXGBE_ERR_TOKEN_RETRY\n");
1219 	return IXGBE_ERR_TOKEN_RETRY;
1220 }
1221 
1222 /**
1223  * ixgbe_put_phy_token - Put the token for shared phy access
1224  * @hw: Pointer to hardware structure
1225  */
1226 
ixgbe_put_phy_token(struct ixgbe_hw * hw)1227 int32_t ixgbe_put_phy_token(struct ixgbe_hw *hw)
1228 {
1229 	struct ixgbe_hic_phy_token_req token_cmd;
1230 	int32_t status;
1231 
1232 	token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1233 	token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1234 	token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1235 	token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1236 	token_cmd.port_number = hw->bus.lan_id;
1237 	token_cmd.command_type = FW_PHY_TOKEN_REL;
1238 	token_cmd.pad = 0;
1239 	status = ixgbe_host_interface_command(hw, (uint32_t *)&token_cmd,
1240 					      sizeof(token_cmd),
1241 					      IXGBE_HI_COMMAND_TIMEOUT,
1242 					      TRUE);
1243 	if (status)
1244 		return status;
1245 	if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1246 		return IXGBE_SUCCESS;
1247 
1248 	DEBUGOUT("Put PHY Token host interface command failed");
1249 	return IXGBE_ERR_FW_RESP_INVALID;
1250 }
1251 
1252 /**
1253  *  ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
1254  *  of the IOSF device
1255  *  @hw: pointer to hardware structure
1256  *  @reg_addr: 32 bit PHY register to write
1257  *  @device_type: 3 bit device type
1258  *  @data: Data to write to the register
1259  **/
ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint32_t data)1260 int32_t ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
1261 				      uint32_t device_type, uint32_t data)
1262 {
1263 	struct ixgbe_hic_internal_phy_req write_cmd;
1264 	int32_t status;
1265 
1266 	memset(&write_cmd, 0, sizeof(write_cmd));
1267 	write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1268 	write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1269 	write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1270 	write_cmd.port_number = hw->bus.lan_id;
1271 	write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
1272 	write_cmd.address = htobe16(reg_addr);
1273 	write_cmd.write_data = htobe32(data);
1274 
1275 	status = ixgbe_host_interface_command(hw, (uint32_t *)&write_cmd,
1276 					      sizeof(write_cmd),
1277 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
1278 
1279 	return status;
1280 }
1281 
1282 /**
1283  *  ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
1284  *  @hw: pointer to hardware structure
1285  *  @reg_addr: 32 bit PHY register to write
1286  *  @device_type: 3 bit device type
1287  *  @data: Pointer to read data from the register
1288  **/
ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint32_t * data)1289 int32_t ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
1290 				     uint32_t device_type, uint32_t *data)
1291 {
1292 	union {
1293 		struct ixgbe_hic_internal_phy_req cmd;
1294 		struct ixgbe_hic_internal_phy_resp rsp;
1295 	} hic;
1296 	int32_t status;
1297 
1298 	memset(&hic, 0, sizeof(hic));
1299 	hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1300 	hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1301 	hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1302 	hic.cmd.port_number = hw->bus.lan_id;
1303 	hic.cmd.command_type = FW_INT_PHY_REQ_READ;
1304 	hic.cmd.address = htobe16(reg_addr);
1305 
1306 	status = ixgbe_host_interface_command(hw, (uint32_t *)&hic.cmd,
1307 					      sizeof(hic.cmd),
1308 					      IXGBE_HI_COMMAND_TIMEOUT, TRUE);
1309 
1310 	/* Extract the register value from the response. */
1311 	*data = betoh32(hic.rsp.read_data);
1312 
1313 	return status;
1314 }
1315 
1316 /**
1317  *  ixgbe_get_media_type_X550em - Get media type
1318  *  @hw: pointer to hardware structure
1319  *
1320  *  Returns the media type (fiber, copper, backplane)
1321  */
ixgbe_get_media_type_X550em(struct ixgbe_hw * hw)1322 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
1323 {
1324 	enum ixgbe_media_type media_type;
1325 
1326 	DEBUGFUNC("ixgbe_get_media_type_X550em");
1327 
1328 	/* Detect if there is a copper PHY attached. */
1329 	switch (hw->device_id) {
1330 	case IXGBE_DEV_ID_X550EM_X_KR:
1331 	case IXGBE_DEV_ID_X550EM_X_KX4:
1332 	case IXGBE_DEV_ID_X550EM_X_XFI:
1333 	case IXGBE_DEV_ID_X550EM_A_KR:
1334 	case IXGBE_DEV_ID_X550EM_A_KR_L:
1335 		media_type = ixgbe_media_type_backplane;
1336 		break;
1337 	case IXGBE_DEV_ID_X550EM_X_SFP:
1338 	case IXGBE_DEV_ID_X550EM_A_SFP:
1339 	case IXGBE_DEV_ID_X550EM_A_SFP_N:
1340 	case IXGBE_DEV_ID_X550EM_A_QSFP:
1341 	case IXGBE_DEV_ID_X550EM_A_QSFP_N:
1342 		media_type = ixgbe_media_type_fiber;
1343 		break;
1344 	case IXGBE_DEV_ID_X550EM_X_1G_T:
1345 	case IXGBE_DEV_ID_X550EM_X_10G_T:
1346 	case IXGBE_DEV_ID_X550EM_A_10G_T:
1347 		media_type = ixgbe_media_type_copper;
1348 		break;
1349 	case IXGBE_DEV_ID_X550EM_A_SGMII:
1350 	case IXGBE_DEV_ID_X550EM_A_SGMII_L:
1351 		media_type = ixgbe_media_type_backplane;
1352 		hw->phy.type = ixgbe_phy_sgmii;
1353 		break;
1354 	case IXGBE_DEV_ID_X550EM_A_1G_T:
1355 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
1356 		media_type = ixgbe_media_type_copper;
1357 		break;
1358 	default:
1359 		media_type = ixgbe_media_type_unknown;
1360 		break;
1361 	}
1362 	return media_type;
1363 }
1364 
1365 /**
1366  *  ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1367  *  @hw: pointer to hardware structure
1368  *  @linear: TRUE if SFP module is linear
1369  */
ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw * hw,bool * linear)1370 int32_t ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1371 {
1372 	DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
1373 
1374 	switch (hw->phy.sfp_type) {
1375 	case ixgbe_sfp_type_not_present:
1376 		return IXGBE_ERR_SFP_NOT_PRESENT;
1377 	case ixgbe_sfp_type_da_cu_core0:
1378 	case ixgbe_sfp_type_da_cu_core1:
1379 		*linear = TRUE;
1380 		break;
1381 	case ixgbe_sfp_type_srlr_core0:
1382 	case ixgbe_sfp_type_srlr_core1:
1383 	case ixgbe_sfp_type_da_act_lmt_core0:
1384 	case ixgbe_sfp_type_da_act_lmt_core1:
1385 	case ixgbe_sfp_type_1g_sx_core0:
1386 	case ixgbe_sfp_type_1g_sx_core1:
1387 	case ixgbe_sfp_type_1g_lx_core0:
1388 	case ixgbe_sfp_type_1g_lx_core1:
1389 		*linear = FALSE;
1390 		break;
1391 	case ixgbe_sfp_type_unknown:
1392 	case ixgbe_sfp_type_1g_cu_core0:
1393 	case ixgbe_sfp_type_1g_cu_core1:
1394 	default:
1395 		return IXGBE_ERR_SFP_NOT_SUPPORTED;
1396 	}
1397 
1398 	return IXGBE_SUCCESS;
1399 }
1400 
1401 /**
1402  *  ixgbe_identify_sfp_module_X550em - Identifies SFP modules
1403  *  @hw: pointer to hardware structure
1404  *
1405  *  Searches for and identifies the SFP module and assigns appropriate PHY type.
1406  **/
ixgbe_identify_sfp_module_X550em(struct ixgbe_hw * hw)1407 int32_t ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
1408 {
1409 	int32_t status;
1410 	bool linear;
1411 
1412 	DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
1413 
1414 	status = ixgbe_identify_module_generic(hw);
1415 
1416 	if (status != IXGBE_SUCCESS)
1417 		return status;
1418 
1419 	/* Check if SFP module is supported */
1420 	status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1421 
1422 	return status;
1423 }
1424 
1425 /**
1426  *  ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
1427  *  @hw: pointer to hardware structure
1428  */
ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw * hw)1429 int32_t ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1430 {
1431 	int32_t status;
1432 	bool linear;
1433 
1434 	DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
1435 
1436 	/* Check if SFP module is supported */
1437 	status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1438 
1439 	if (status != IXGBE_SUCCESS)
1440 		return status;
1441 
1442 	ixgbe_init_mac_link_ops_X550em(hw);
1443 	hw->phy.ops.reset = NULL;
1444 
1445 	return IXGBE_SUCCESS;
1446 }
1447 
1448 /**
1449 *  ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
1450 *  internal PHY
1451 *  @hw: pointer to hardware structure
1452 **/
ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw * hw)1453 int32_t ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
1454 {
1455 	int32_t status;
1456 	uint32_t link_ctrl;
1457 
1458 	/* Restart auto-negotiation. */
1459 	status = hw->mac.ops.read_iosf_sb_reg(hw,
1460 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1461 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
1462 
1463 	if (status) {
1464 		DEBUGOUT("Auto-negotiation did not complete\n");
1465 		return status;
1466 	}
1467 
1468 	link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1469 	status = hw->mac.ops.write_iosf_sb_reg(hw,
1470 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1471 					IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
1472 
1473 	if (hw->mac.type == ixgbe_mac_X550EM_a) {
1474 		uint32_t flx_mask_st20;
1475 
1476 		/* Indicate to FW that AN restart has been asserted */
1477 		status = hw->mac.ops.read_iosf_sb_reg(hw,
1478 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1479 				IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
1480 
1481 		if (status) {
1482 			DEBUGOUT("Auto-negotiation did not complete\n");
1483 			return status;
1484 		}
1485 
1486 		flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
1487 		status = hw->mac.ops.write_iosf_sb_reg(hw,
1488 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1489 				IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
1490 	}
1491 
1492 	return status;
1493 }
1494 
1495 /**
1496  * ixgbe_setup_sgmii - Set up link for sgmii
1497  * @hw: pointer to hardware structure
1498  * @speed: new link speed
1499  * @autoneg_wait: TRUE when waiting for completion is needed
1500  */
ixgbe_setup_sgmii(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait)1501 int32_t ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1502 			     bool autoneg_wait)
1503 {
1504 	struct ixgbe_mac_info *mac = &hw->mac;
1505 	uint32_t lval, sval, flx_val;
1506 	int32_t rc;
1507 
1508 	rc = mac->ops.read_iosf_sb_reg(hw,
1509 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1510 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1511 	if (rc)
1512 		return rc;
1513 
1514 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1515 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1516 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1517 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1518 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1519 	rc = mac->ops.write_iosf_sb_reg(hw,
1520 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1521 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1522 	if (rc)
1523 		return rc;
1524 
1525 	rc = mac->ops.read_iosf_sb_reg(hw,
1526 				       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1527 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1528 	if (rc)
1529 		return rc;
1530 
1531 	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1532 	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1533 	rc = mac->ops.write_iosf_sb_reg(hw,
1534 					IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1535 					IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1536 	if (rc)
1537 		return rc;
1538 
1539 	rc = mac->ops.read_iosf_sb_reg(hw,
1540 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1541 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1542 	if (rc)
1543 		return rc;
1544 
1545 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1546 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1547 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1548 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1549 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1550 
1551 	rc = mac->ops.write_iosf_sb_reg(hw,
1552 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1553 				    IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1554 	if (rc)
1555 		return rc;
1556 
1557 	rc = ixgbe_restart_an_internal_phy_x550em(hw);
1558 	if (rc)
1559 		return rc;
1560 
1561 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1562 }
1563 
1564 /**
1565  * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation
1566  * @hw: pointer to hardware structure
1567  * @speed: new link speed
1568  * @autoneg_wait: TRUE when waiting for completion is needed
1569  */
ixgbe_setup_sgmii_fw(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait)1570 int32_t ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1571 				bool autoneg_wait)
1572 {
1573 	struct ixgbe_mac_info *mac = &hw->mac;
1574 	uint32_t lval, sval, flx_val;
1575 	int32_t rc;
1576 
1577 	rc = mac->ops.read_iosf_sb_reg(hw,
1578 				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1579 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1580 	if (rc)
1581 		return rc;
1582 
1583 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1584 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1585 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1586 	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1587 	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1588 	rc = mac->ops.write_iosf_sb_reg(hw,
1589 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1590 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1591 	if (rc)
1592 		return rc;
1593 
1594 	rc = mac->ops.read_iosf_sb_reg(hw,
1595 				       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1596 				       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1597 	if (rc)
1598 		return rc;
1599 
1600 	sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1601 	sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1602 	rc = mac->ops.write_iosf_sb_reg(hw,
1603 					IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1604 					IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1605 	if (rc)
1606 		return rc;
1607 
1608 	rc = mac->ops.write_iosf_sb_reg(hw,
1609 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1610 					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1611 	if (rc)
1612 		return rc;
1613 
1614 	rc = mac->ops.read_iosf_sb_reg(hw,
1615 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1616 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1617 	if (rc)
1618 		return rc;
1619 
1620 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1621 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
1622 	flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1623 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1624 	flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1625 
1626 	rc = mac->ops.write_iosf_sb_reg(hw,
1627 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1628 				    IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1629 	if (rc)
1630 		return rc;
1631 
1632 	rc = ixgbe_restart_an_internal_phy_x550em(hw);
1633 
1634 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1635 }
1636 
1637 /**
1638  *  ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1639  *  @hw: pointer to hardware structure
1640  */
ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw * hw)1641 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1642 {
1643 	struct ixgbe_mac_info *mac = &hw->mac;
1644 
1645 	DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
1646 
1647 	switch (hw->mac.ops.get_media_type(hw)) {
1648 	case ixgbe_media_type_fiber:
1649 		/* CS4227 does not support autoneg, so disable the laser control
1650 		 * functions for SFP+ fiber
1651 		 */
1652 		mac->ops.disable_tx_laser = NULL;
1653 		mac->ops.enable_tx_laser = NULL;
1654 		mac->ops.flap_tx_laser = NULL;
1655 		mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
1656 		mac->ops.set_rate_select_speed =
1657 					ixgbe_set_soft_rate_select_speed;
1658 
1659 		if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
1660 		    (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
1661 			mac->ops.setup_mac_link =
1662 						ixgbe_setup_mac_link_sfp_x550a;
1663 		else
1664 			mac->ops.setup_mac_link =
1665 						ixgbe_setup_mac_link_sfp_x550em;
1666 		break;
1667 	case ixgbe_media_type_copper:
1668 		if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T)
1669 			break;
1670 		if (hw->mac.type == ixgbe_mac_X550EM_a) {
1671 			if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
1672 			    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
1673 				mac->ops.setup_link = ixgbe_setup_sgmii_fw;
1674 				mac->ops.check_link =
1675 						   ixgbe_check_mac_link_generic;
1676 			} else {
1677 				mac->ops.setup_link =
1678 						  ixgbe_setup_mac_link_t_X550em;
1679 			}
1680 		} else {
1681 			mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
1682 			mac->ops.check_link = ixgbe_check_link_t_X550em;
1683 		}
1684 		break;
1685 	case ixgbe_media_type_backplane:
1686 		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
1687 		    hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
1688 			mac->ops.setup_link = ixgbe_setup_sgmii;
1689 		break;
1690 	default:
1691 		break;
1692 	}
1693 }
1694 
1695 /**
1696  *  ixgbe_get_link_capabilities_x550em - Determines link capabilities
1697  *  @hw: pointer to hardware structure
1698  *  @speed: pointer to link speed
1699  *  @autoneg: TRUE when autoneg or autotry is enabled
1700  */
ixgbe_get_link_capabilities_X550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)1701 int32_t ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
1702 					   ixgbe_link_speed *speed,
1703 					   bool *autoneg)
1704 {
1705 	DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
1706 
1707 
1708 	if (hw->phy.type == ixgbe_phy_fw) {
1709 		*autoneg = TRUE;
1710 		*speed = hw->phy.speeds_supported;
1711 		return 0;
1712 	}
1713 
1714 	/* SFP */
1715 	if (hw->phy.media_type == ixgbe_media_type_fiber) {
1716 
1717 		/* CS4227 SFP must not enable auto-negotiation */
1718 		*autoneg = FALSE;
1719 
1720 		/* Check if 1G SFP module. */
1721 		if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1722 		    hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
1723 		    || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1724 		    hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
1725 			*speed = IXGBE_LINK_SPEED_1GB_FULL;
1726 			return IXGBE_SUCCESS;
1727 		}
1728 
1729 		/* Link capabilities are based on SFP */
1730 		if (hw->phy.multispeed_fiber)
1731 			*speed = IXGBE_LINK_SPEED_10GB_FULL |
1732 				 IXGBE_LINK_SPEED_1GB_FULL;
1733 		else
1734 			*speed = IXGBE_LINK_SPEED_10GB_FULL;
1735 	} else {
1736 		switch (hw->phy.type) {
1737 		case ixgbe_phy_ext_1g_t:
1738 		case ixgbe_phy_sgmii:
1739 			*speed = IXGBE_LINK_SPEED_1GB_FULL;
1740 			break;
1741 		case ixgbe_phy_x550em_kr:
1742 			if (hw->mac.type == ixgbe_mac_X550EM_a) {
1743 				/* check different backplane modes */
1744 				if (hw->phy.nw_mng_if_sel &
1745 					   IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
1746 					*speed = IXGBE_LINK_SPEED_2_5GB_FULL;
1747 					break;
1748 				} else if (hw->device_id ==
1749 						   IXGBE_DEV_ID_X550EM_A_KR_L) {
1750 					*speed = IXGBE_LINK_SPEED_1GB_FULL;
1751 					break;
1752 				}
1753 			}
1754 			/* fall through */
1755 		default:
1756 			*speed = IXGBE_LINK_SPEED_10GB_FULL |
1757 				 IXGBE_LINK_SPEED_1GB_FULL;
1758 			break;
1759 		}
1760 		*autoneg = TRUE;
1761 	}
1762 
1763 	return IXGBE_SUCCESS;
1764 }
1765 
1766 /**
1767  * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
1768  * @hw: pointer to hardware structure
1769  * @lsc: pointer to boolean flag which indicates whether external Base T
1770  *       PHY interrupt is lsc
1771  *
1772  * Determime if external Base T PHY interrupt cause is high temperature
1773  * failure alarm or link status change.
1774  *
1775  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1776  * failure alarm, else return PHY access status.
1777  */
ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw * hw,bool * lsc)1778 int32_t ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
1779 {
1780 	uint32_t status;
1781 	uint16_t reg;
1782 
1783 	*lsc = FALSE;
1784 
1785 	/* Vendor alarm triggered */
1786 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1787 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1788 				      &reg);
1789 
1790 	if (status != IXGBE_SUCCESS ||
1791 	    !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
1792 		return status;
1793 
1794 	/* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
1795 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
1796 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1797 				      &reg);
1798 
1799 	if (status != IXGBE_SUCCESS ||
1800 	    !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1801 	    IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
1802 		return status;
1803 
1804 	/* Global alarm triggered */
1805 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
1806 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1807 				      &reg);
1808 
1809 	if (status != IXGBE_SUCCESS)
1810 		return status;
1811 
1812 	/* If high temperature failure, then return over temp error and exit */
1813 	if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
1814 		/* power down the PHY in case the PHY FW didn't already */
1815 		ixgbe_set_copper_phy_power(hw, FALSE);
1816 		return IXGBE_ERR_OVERTEMP;
1817 	} else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
1818 		/*  device fault alarm triggered */
1819 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
1820 					  IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1821 					  &reg);
1822 
1823 		if (status != IXGBE_SUCCESS)
1824 			return status;
1825 
1826 		/* if device fault was due to high temp alarm handle and exit */
1827 		if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
1828 			/* power down the PHY in case the PHY FW didn't */
1829 			ixgbe_set_copper_phy_power(hw, FALSE);
1830 			return IXGBE_ERR_OVERTEMP;
1831 		}
1832 	}
1833 
1834 	/* Vendor alarm 2 triggered */
1835 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1836 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1837 
1838 	if (status != IXGBE_SUCCESS ||
1839 	    !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
1840 		return status;
1841 
1842 	/* link connect/disconnect event occurred */
1843 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
1844 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1845 
1846 	if (status != IXGBE_SUCCESS)
1847 		return status;
1848 
1849 	/* Indicate LSC */
1850 	if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
1851 		*lsc = TRUE;
1852 
1853 	return IXGBE_SUCCESS;
1854 }
1855 
1856 /**
1857  * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
1858  * @hw: pointer to hardware structure
1859  *
1860  * Enable link status change and temperature failure alarm for the external
1861  * Base T PHY
1862  *
1863  * Returns PHY access status
1864  */
ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw * hw)1865 int32_t ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
1866 {
1867 	uint32_t status;
1868 	uint16_t reg;
1869 	bool lsc;
1870 
1871 	/* Clear interrupt flags */
1872 	status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
1873 
1874 	/* Enable link status change alarm */
1875 
1876 	/* Enable the LASI interrupts on X552 devices to receive notifications
1877 	 * of the link configurations of the external PHY and correspondingly
1878 	 * support the configuration of the internal iXFI link, since iXFI does
1879 	 * not support auto-negotiation. This is not required for X553 devices
1880 	 * having KR support, which performs auto-negotiations and which is used
1881 	 * as the internal link to the external PHY. Hence adding a check here
1882 	 * to avoid enabling LASI interrupts for X553 devices.
1883 	 */
1884 	if (hw->mac.type != ixgbe_mac_X550EM_a) {
1885 		status = hw->phy.ops.read_reg(hw,
1886 					IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1887 					IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1888 
1889 		if (status != IXGBE_SUCCESS)
1890 			return status;
1891 
1892 		reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
1893 
1894 		status = hw->phy.ops.write_reg(hw,
1895 					IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1896 					IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
1897 
1898 		if (status != IXGBE_SUCCESS)
1899 			return status;
1900 	}
1901 
1902 	/* Enable high temperature failure and global fault alarms */
1903 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1904 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1905 				      &reg);
1906 
1907 	if (status != IXGBE_SUCCESS)
1908 		return status;
1909 
1910 	reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
1911 		IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
1912 
1913 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1914 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1915 				       reg);
1916 
1917 	if (status != IXGBE_SUCCESS)
1918 		return status;
1919 
1920 	/* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
1921 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1922 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1923 				      &reg);
1924 
1925 	if (status != IXGBE_SUCCESS)
1926 		return status;
1927 
1928 	reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1929 		IXGBE_MDIO_GLOBAL_ALARM_1_INT);
1930 
1931 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1932 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1933 				       reg);
1934 
1935 	if (status != IXGBE_SUCCESS)
1936 		return status;
1937 
1938 	/* Enable chip-wide vendor alarm */
1939 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1940 				      IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1941 				      &reg);
1942 
1943 	if (status != IXGBE_SUCCESS)
1944 		return status;
1945 
1946 	reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
1947 
1948 	status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1949 				       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1950 				       reg);
1951 
1952 	return status;
1953 }
1954 
1955 /**
1956  *  ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
1957  *  @hw: pointer to hardware structure
1958  *  @speed: link speed
1959  *
1960  *  Configures the integrated KR PHY.
1961  **/
ixgbe_setup_kr_speed_x550em(struct ixgbe_hw * hw,ixgbe_link_speed speed)1962 int32_t ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
1963 				    ixgbe_link_speed speed)
1964 {
1965 	int32_t status;
1966 	uint32_t reg_val;
1967 
1968 	status = hw->mac.ops.read_iosf_sb_reg(hw,
1969 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1970 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1971 	if (status)
1972 		return status;
1973 
1974 	reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1975 	reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
1976 		     IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
1977 
1978 	/* Advertise 10G support. */
1979 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1980 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
1981 
1982 	/* Advertise 1G support. */
1983 	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
1984 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
1985 
1986 	status = hw->mac.ops.write_iosf_sb_reg(hw,
1987 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1988 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1989 
1990 	if (hw->mac.type == ixgbe_mac_X550EM_a) {
1991 		/* Set lane mode  to KR auto negotiation */
1992 		status = hw->mac.ops.read_iosf_sb_reg(hw,
1993 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1994 				    IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1995 
1996 		if (status)
1997 			return status;
1998 
1999 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2000 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2001 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2002 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2003 		reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2004 
2005 		status = hw->mac.ops.write_iosf_sb_reg(hw,
2006 				    IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2007 				    IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2008 	}
2009 
2010 	return ixgbe_restart_an_internal_phy_x550em(hw);
2011 }
2012 
2013 /**
2014  * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
2015  * @hw: pointer to hardware structure
2016  */
ixgbe_reset_phy_fw(struct ixgbe_hw * hw)2017 int32_t ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
2018 {
2019 	uint32_t store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2020 	int32_t rc;
2021 
2022 	if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
2023 		return IXGBE_SUCCESS;
2024 
2025 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
2026 	if (rc)
2027 		return rc;
2028 	memset(store, 0, sizeof(store));
2029 
2030 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
2031 	if (rc)
2032 		return rc;
2033 
2034 	return ixgbe_setup_fw_link(hw);
2035 }
2036 
2037 /**
2038  * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
2039  * @hw: pointer to hardware structure
2040  */
ixgbe_check_overtemp_fw(struct ixgbe_hw * hw)2041 int32_t ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
2042 {
2043 	uint32_t store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2044 	int32_t rc;
2045 
2046 	rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
2047 	if (rc)
2048 		return rc;
2049 
2050 	if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
2051 		ixgbe_shutdown_fw_phy(hw);
2052 		return IXGBE_ERR_OVERTEMP;
2053 	}
2054 	return IXGBE_SUCCESS;
2055 }
2056 
2057 /**
2058  *  ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
2059  *  @hw: pointer to hardware structure
2060  *
2061  *  Read NW_MNG_IF_SEL register and save field values, and check for valid field
2062  *  values.
2063  **/
ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw * hw)2064 int32_t ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
2065 {
2066 	/* Save NW management interface connected on board. This is used
2067 	 * to determine internal PHY mode.
2068 	 */
2069 	hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
2070 
2071 	/* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
2072 	 * PHY address. This register field was has only been used for X552.
2073 	 */
2074 	if (hw->mac.type == ixgbe_mac_X550EM_a &&
2075 	    hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
2076 		hw->phy.addr = (hw->phy.nw_mng_if_sel &
2077 				IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
2078 			       IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
2079 	}
2080 
2081 	return IXGBE_SUCCESS;
2082 }
2083 
2084 /**
2085  *  ixgbe_init_phy_ops_X550em - PHY/SFP specific init
2086  *  @hw: pointer to hardware structure
2087  *
2088  *  Initialize any function pointers that were not able to be
2089  *  set during init_shared_code because the PHY/SFP type was
2090  *  not known.  Perform the SFP init if necessary.
2091  */
ixgbe_init_phy_ops_X550em(struct ixgbe_hw * hw)2092 int32_t ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
2093 {
2094 	struct ixgbe_phy_info *phy = &hw->phy;
2095 	int32_t ret_val;
2096 
2097 	DEBUGFUNC("ixgbe_init_phy_ops_X550em");
2098 
2099 	hw->mac.ops.set_lan_id(hw);
2100 	ixgbe_read_mng_if_sel_x550em(hw);
2101 
2102 	if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
2103 		phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2104 		ixgbe_setup_mux_ctl(hw);
2105 		phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
2106 	}
2107 
2108 	switch (hw->device_id) {
2109 	case IXGBE_DEV_ID_X550EM_A_1G_T:
2110 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2111 		phy->ops.read_reg_mdi = NULL;
2112 		phy->ops.write_reg_mdi = NULL;
2113 		hw->phy.ops.read_reg = NULL;
2114 		hw->phy.ops.write_reg = NULL;
2115 		phy->ops.check_overtemp = ixgbe_check_overtemp_fw;
2116 		if (hw->bus.lan_id)
2117 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2118 		else
2119 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2120 
2121 		break;
2122 	case IXGBE_DEV_ID_X550EM_A_10G_T:
2123 	case IXGBE_DEV_ID_X550EM_A_SFP:
2124 		hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
2125 		hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
2126 		if (hw->bus.lan_id)
2127 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2128 		else
2129 			hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2130 		break;
2131 	case IXGBE_DEV_ID_X550EM_X_SFP:
2132 		/* set up for CS4227 usage */
2133 		hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2134 		break;
2135 	case IXGBE_DEV_ID_X550EM_X_1G_T:
2136 		phy->ops.read_reg_mdi = NULL;
2137 		phy->ops.write_reg_mdi = NULL;
2138 	default:
2139 		break;
2140 	}
2141 
2142 	/* Identify the PHY or SFP module */
2143 	ret_val = phy->ops.identify(hw);
2144 	if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2145 	    ret_val == IXGBE_ERR_PHY_ADDR_INVALID)
2146 		return ret_val;
2147 
2148 	/* Setup function pointers based on detected hardware */
2149 	ixgbe_init_mac_link_ops_X550em(hw);
2150 	if (phy->sfp_type != ixgbe_sfp_type_unknown)
2151 		phy->ops.reset = NULL;
2152 
2153 	/* Set functions pointers based on phy type */
2154 	switch (hw->phy.type) {
2155 	case ixgbe_phy_x550em_kx4:
2156 		phy->ops.setup_link = NULL;
2157 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2158 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2159 		break;
2160 	case ixgbe_phy_x550em_kr:
2161 		phy->ops.setup_link = ixgbe_setup_kr_x550em;
2162 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2163 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2164 		break;
2165 	case ixgbe_phy_ext_1g_t:
2166 		/* link is managed by FW */
2167 		phy->ops.setup_link = NULL;
2168 		phy->ops.reset = NULL;
2169 		break;
2170 	case ixgbe_phy_x550em_xfi:
2171 		/* link is managed by HW */
2172 		phy->ops.setup_link = NULL;
2173 		phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2174 		phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2175 		break;
2176 	case ixgbe_phy_x550em_ext_t:
2177 		/* If internal link mode is XFI, then setup iXFI internal link,
2178 		 * else setup KR now.
2179 		 */
2180 		phy->ops.setup_internal_link =
2181 					      ixgbe_setup_internal_phy_t_x550em;
2182 
2183 		/* setup SW LPLU only for first revision of X550EM_x */
2184 		if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
2185 		    !(IXGBE_FUSES0_REV_MASK &
2186 		      IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
2187 			phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2188 
2189 		phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
2190 		phy->ops.reset = ixgbe_reset_phy_t_X550em;
2191 		break;
2192 	case ixgbe_phy_sgmii:
2193 		phy->ops.setup_link = NULL;
2194 		break;
2195 	case ixgbe_phy_fw:
2196 		phy->ops.setup_link = ixgbe_setup_fw_link;
2197 		phy->ops.reset = ixgbe_reset_phy_fw;
2198 		break;
2199 	default:
2200 		break;
2201 	}
2202 	return ret_val;
2203 }
2204 
2205 /**
2206  * ixgbe_set_mdio_speed - Set MDIO clock speed
2207  *  @hw: pointer to hardware structure
2208  */
ixgbe_set_mdio_speed(struct ixgbe_hw * hw)2209 void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
2210 {
2211 	uint32_t hlreg0;
2212 
2213 	switch (hw->device_id) {
2214 	case IXGBE_DEV_ID_X550EM_X_10G_T:
2215 	case IXGBE_DEV_ID_X550EM_A_SGMII:
2216 	case IXGBE_DEV_ID_X550EM_A_SGMII_L:
2217 	case IXGBE_DEV_ID_X550EM_A_10G_T:
2218 	case IXGBE_DEV_ID_X550EM_A_SFP:
2219 	case IXGBE_DEV_ID_X550EM_A_QSFP:
2220 		/* Config MDIO clock speed before the first MDIO PHY access */
2221 		hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2222 		hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2223 		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2224 		break;
2225 	case IXGBE_DEV_ID_X550EM_A_1G_T:
2226 	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2227 		/* Select fast MDIO clock speed for these devices */
2228 		hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2229 		hlreg0 |= IXGBE_HLREG0_MDCSPD;
2230 		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2231 		break;
2232 	default:
2233 		break;
2234 	}
2235 }
2236 
2237 /**
2238  *  ixgbe_reset_hw_X550em - Perform hardware reset
2239  *  @hw: pointer to hardware structure
2240  *
2241  *  Resets the hardware by resetting the transmit and receive units, masks
2242  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2243  *  reset.
2244  */
ixgbe_reset_hw_X550em(struct ixgbe_hw * hw)2245 int32_t ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
2246 {
2247 	ixgbe_link_speed link_speed;
2248 	int32_t status;
2249 	uint32_t ctrl = 0;
2250 	uint32_t i;
2251 	bool link_up = FALSE;
2252 	uint32_t swfw_mask = hw->phy.phy_semaphore_mask;
2253 
2254 	DEBUGFUNC("ixgbe_reset_hw_X550em");
2255 
2256 	/* Call adapter stop to disable Tx/Rx and clear interrupts */
2257 	status = hw->mac.ops.stop_adapter(hw);
2258 	if (status != IXGBE_SUCCESS) {
2259 		DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status);
2260 		return status;
2261 	}
2262 	/* flush pending Tx transactions */
2263 	ixgbe_clear_tx_pending(hw);
2264 
2265 	ixgbe_set_mdio_speed(hw);
2266 
2267 	/* PHY ops must be identified and initialized prior to reset */
2268 	status = hw->phy.ops.init(hw);
2269 
2270 	if (status)
2271 		DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
2272 			  status);
2273 
2274 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2275 	    status == IXGBE_ERR_PHY_ADDR_INVALID) {
2276 		DEBUGOUT("Returning from reset HW due to PHY init failure\n");
2277 		return status;
2278 	}
2279 
2280 	/* start the external PHY */
2281 	if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2282 		status = ixgbe_init_ext_t_x550em(hw);
2283 		if (status) {
2284 			DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n",
2285 				  status);
2286 			return status;
2287 		}
2288 	}
2289 
2290 	/* Setup SFP module if there is one present. */
2291 	if (hw->phy.sfp_setup_needed) {
2292 		status = hw->mac.ops.setup_sfp(hw);
2293 		hw->phy.sfp_setup_needed = FALSE;
2294 	}
2295 
2296 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
2297 		return status;
2298 
2299 	/* Reset PHY */
2300 	if (!hw->phy.reset_disable && hw->phy.ops.reset) {
2301 		if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP)
2302 			return IXGBE_ERR_OVERTEMP;
2303 	}
2304 
2305 mac_reset_top:
2306 	/* Issue global reset to the MAC.  Needs to be SW reset if link is up.
2307 	 * If link reset is used when link is up, it might reset the PHY when
2308 	 * mng is using it.  If link is down or the flag to force full link
2309 	 * reset is set, then perform link reset.
2310 	 */
2311 	ctrl = IXGBE_CTRL_LNK_RST;
2312 	if (!hw->force_full_reset) {
2313 		hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
2314 		if (link_up)
2315 			ctrl = IXGBE_CTRL_RST;
2316 	}
2317 
2318 	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
2319 	if (status != IXGBE_SUCCESS) {
2320 		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2321 			"semaphore failed with %d", status);
2322 		return IXGBE_ERR_SWFW_SYNC;
2323 	}
2324 	ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2325 	IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2326 	IXGBE_WRITE_FLUSH(hw);
2327 	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2328 
2329 	/* Poll for reset bit to self-clear meaning reset is complete */
2330 	for (i = 0; i < 10; i++) {
2331 		usec_delay(1);
2332 		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2333 		if (!(ctrl & IXGBE_CTRL_RST_MASK))
2334 			break;
2335 	}
2336 
2337 	if (ctrl & IXGBE_CTRL_RST_MASK) {
2338 		status = IXGBE_ERR_RESET_FAILED;
2339 		DEBUGOUT("Reset polling failed to complete.\n");
2340 	}
2341 
2342 	msec_delay(50);
2343 
2344 	/* Double resets are required for recovery from certain error
2345 	 * conditions.  Between resets, it is necessary to stall to
2346 	 * allow time for any pending HW events to complete.
2347 	 */
2348 	if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2349 		hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2350 		goto mac_reset_top;
2351 	}
2352 
2353 	/* Store the permanent mac address */
2354 	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2355 
2356 	/* Store MAC address from RAR0, clear receive address registers, and
2357 	 * clear the multicast table.  Also reset num_rar_entries to 128,
2358 	 * since we modify this value when programming the SAN MAC address.
2359 	 */
2360 	hw->mac.num_rar_entries = 128;
2361 	hw->mac.ops.init_rx_addrs(hw);
2362 
2363 	ixgbe_set_mdio_speed(hw);
2364 
2365 	if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2366 		ixgbe_setup_mux_ctl(hw);
2367 
2368 	if (status != IXGBE_SUCCESS)
2369 		DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
2370 
2371 	return status;
2372 }
2373 
2374 /**
2375  * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2376  * @hw: pointer to hardware structure
2377  */
ixgbe_init_ext_t_x550em(struct ixgbe_hw * hw)2378 int32_t ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
2379 {
2380 	uint32_t status;
2381 	uint16_t reg;
2382 
2383 	status = hw->phy.ops.read_reg(hw,
2384 				      IXGBE_MDIO_TX_VENDOR_ALARMS_3,
2385 				      IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2386 				      &reg);
2387 
2388 	if (status != IXGBE_SUCCESS)
2389 		return status;
2390 
2391 	/* If PHY FW reset completed bit is set then this is the first
2392 	 * SW instance after a power on so the PHY FW must be un-stalled.
2393 	 */
2394 	if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2395 		status = hw->phy.ops.read_reg(hw,
2396 					IXGBE_MDIO_GLOBAL_RES_PR_10,
2397 					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2398 					&reg);
2399 
2400 		if (status != IXGBE_SUCCESS)
2401 			return status;
2402 
2403 		reg &= ~IXGBE_MDIO_POWER_UP_STALL;
2404 
2405 		status = hw->phy.ops.write_reg(hw,
2406 					IXGBE_MDIO_GLOBAL_RES_PR_10,
2407 					IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2408 					reg);
2409 
2410 		if (status != IXGBE_SUCCESS)
2411 			return status;
2412 	}
2413 
2414 	return status;
2415 }
2416 
2417 /**
2418  *  ixgbe_setup_kr_x550em - Configure the KR PHY.
2419  *  @hw: pointer to hardware structure
2420  **/
ixgbe_setup_kr_x550em(struct ixgbe_hw * hw)2421 int32_t ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
2422 {
2423 	/* leave link alone for 2.5G */
2424 	if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
2425 		return IXGBE_SUCCESS;
2426 
2427 	if (ixgbe_check_reset_blocked(hw))
2428 		return 0;
2429 
2430 	return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
2431 }
2432 
2433 /**
2434  *  ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
2435  *  @hw: pointer to hardware structure
2436  *  @speed: new link speed
2437  *  @autoneg_wait_to_complete: unused
2438  *
2439  *  Configure the external PHY and the integrated KR PHY for SFP support.
2440  **/
ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)2441 int32_t ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
2442 					ixgbe_link_speed speed,
2443 					bool autoneg_wait_to_complete)
2444 {
2445 	int32_t ret_val;
2446 	uint16_t reg_slice, reg_val;
2447 	bool setup_linear = FALSE;
2448 
2449 	/* Check if SFP module is supported and linear */
2450 	ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2451 
2452 	/* If no SFP module present, then return success. Return success since
2453 	 * there is no reason to configure CS4227 and SFP not present error is
2454 	 * not excepted in the setup MAC link flow.
2455 	 */
2456 	if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2457 		return IXGBE_SUCCESS;
2458 
2459 	if (ret_val != IXGBE_SUCCESS)
2460 		return ret_val;
2461 
2462 	/* Configure internal PHY for KR/KX. */
2463 	ixgbe_setup_kr_speed_x550em(hw, speed);
2464 
2465 	/* Configure CS4227 LINE side to proper mode. */
2466 	reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
2467 		    (hw->bus.lan_id << 12);
2468 	if (setup_linear)
2469 		reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2470 	else
2471 		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2472 	ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2473 					  reg_val);
2474 	return ret_val;
2475 }
2476 
2477 /**
2478  *  ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
2479  *  @hw: pointer to hardware structure
2480  *  @speed: the link speed to force
2481  *
2482  *  Configures the integrated PHY for native SFI mode. Used to connect the
2483  *  internal PHY directly to an SFP cage, without autonegotiation.
2484  **/
ixgbe_setup_sfi_x550a(struct ixgbe_hw * hw,ixgbe_link_speed * speed)2485 int32_t ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2486 {
2487 	struct ixgbe_mac_info *mac = &hw->mac;
2488 	int32_t status;
2489 	uint32_t reg_val;
2490 
2491 	/* Disable all AN and force speed to 10G Serial. */
2492 	status = mac->ops.read_iosf_sb_reg(hw,
2493 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2494 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2495 	if (status != IXGBE_SUCCESS)
2496 		return status;
2497 
2498 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2499 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2500 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2501 	reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2502 
2503 	/* Select forced link speed for internal PHY. */
2504 	switch (*speed) {
2505 	case IXGBE_LINK_SPEED_10GB_FULL:
2506 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
2507 		break;
2508 	case IXGBE_LINK_SPEED_1GB_FULL:
2509 		reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
2510 		break;
2511 	default:
2512 		/* Other link speeds are not supported by internal PHY. */
2513 		return IXGBE_ERR_LINK_SETUP;
2514 	}
2515 
2516 	status = mac->ops.write_iosf_sb_reg(hw,
2517 				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2518 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2519 
2520 	/* Toggle port SW reset by AN reset. */
2521 	status = ixgbe_restart_an_internal_phy_x550em(hw);
2522 
2523 	return status;
2524 }
2525 
2526 /**
2527  *  ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
2528  *  @hw: pointer to hardware structure
2529  *  @speed: new link speed
2530  *  @autoneg_wait_to_complete: unused
2531  *
2532  *  Configure the integrated PHY for SFP support.
2533  **/
ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)2534 int32_t ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
2535 				       ixgbe_link_speed speed,
2536 				       bool autoneg_wait_to_complete)
2537 {
2538 	int32_t ret_val;
2539 	uint16_t reg_phy_ext;
2540 	bool setup_linear = FALSE;
2541 	uint32_t reg_slice, reg_phy_int, slice_offset;
2542 
2543 	/* Check if SFP module is supported and linear */
2544 	ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2545 
2546 	/* If no SFP module present, then return success. Return success since
2547 	 * SFP not present error is not excepted in the setup MAC link flow.
2548 	 */
2549 	if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2550 		return IXGBE_SUCCESS;
2551 
2552 	if (ret_val != IXGBE_SUCCESS)
2553 		return ret_val;
2554 
2555 	if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
2556 		/* Configure internal PHY for native SFI based on module type */
2557 		ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
2558 				   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2559 				   IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
2560 
2561 		if (ret_val != IXGBE_SUCCESS)
2562 			return ret_val;
2563 
2564 		reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
2565 		if (!setup_linear)
2566 			reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
2567 
2568 		ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
2569 				   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2570 				   IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
2571 
2572 		if (ret_val != IXGBE_SUCCESS)
2573 			return ret_val;
2574 
2575 		/* Setup SFI internal link. */
2576 		ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
2577 	} else {
2578 		/* Configure internal PHY for KR/KX. */
2579 		ixgbe_setup_kr_speed_x550em(hw, speed);
2580 
2581 		if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
2582 			/* Find Address */
2583 			DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
2584 			return IXGBE_ERR_PHY_ADDR_INVALID;
2585 		}
2586 
2587 		/* Get external PHY SKU id */
2588 		ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
2589 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2590 
2591 		if (ret_val != IXGBE_SUCCESS)
2592 			return ret_val;
2593 
2594 		/* When configuring quad port CS4223, the MAC instance is part
2595 		 * of the slice offset.
2596 		 */
2597 		if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
2598 			slice_offset = (hw->bus.lan_id +
2599 					(hw->bus.instance_id << 1)) << 12;
2600 		else
2601 			slice_offset = hw->bus.lan_id << 12;
2602 
2603 		/* Configure CS4227/CS4223 LINE side to proper mode. */
2604 		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
2605 
2606 		ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2607 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2608 
2609 		if (ret_val != IXGBE_SUCCESS)
2610 			return ret_val;
2611 
2612 		reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
2613 				 (IXGBE_CS4227_EDC_MODE_SR << 1));
2614 
2615 		if (setup_linear)
2616 			reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2617 		else
2618 			reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2619 		ret_val = hw->phy.ops.write_reg(hw, reg_slice,
2620 					 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
2621 
2622 		/* Flush previous write with a read */
2623 		ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2624 					IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2625 	}
2626 	return ret_val;
2627 }
2628 
2629 /**
2630  *  ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
2631  *  @hw: pointer to hardware structure
2632  *
2633  *  iXfI configuration needed for ixgbe_mac_X550EM_x devices.
2634  **/
ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw * hw)2635 int32_t ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
2636 {
2637 	struct ixgbe_mac_info *mac = &hw->mac;
2638 	int32_t status;
2639 	uint32_t reg_val;
2640 
2641 	/* Disable training protocol FSM. */
2642 	status = mac->ops.read_iosf_sb_reg(hw,
2643 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2644 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2645 	if (status != IXGBE_SUCCESS)
2646 		return status;
2647 	reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
2648 	status = mac->ops.write_iosf_sb_reg(hw,
2649 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2650 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2651 	if (status != IXGBE_SUCCESS)
2652 		return status;
2653 
2654 	/* Disable Flex from training TXFFE. */
2655 	status = mac->ops.read_iosf_sb_reg(hw,
2656 				IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2657 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2658 	if (status != IXGBE_SUCCESS)
2659 		return status;
2660 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2661 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2662 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2663 	status = mac->ops.write_iosf_sb_reg(hw,
2664 				IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2665 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2666 	if (status != IXGBE_SUCCESS)
2667 		return status;
2668 	status = mac->ops.read_iosf_sb_reg(hw,
2669 				IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2670 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2671 	if (status != IXGBE_SUCCESS)
2672 		return status;
2673 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2674 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2675 	reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2676 	status = mac->ops.write_iosf_sb_reg(hw,
2677 				IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2678 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2679 	if (status != IXGBE_SUCCESS)
2680 		return status;
2681 
2682 	/* Enable override for coefficients. */
2683 	status = mac->ops.read_iosf_sb_reg(hw,
2684 				IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2685 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2686 	if (status != IXGBE_SUCCESS)
2687 		return status;
2688 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
2689 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
2690 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
2691 	reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
2692 	status = mac->ops.write_iosf_sb_reg(hw,
2693 				IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2694 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2695 	return status;
2696 }
2697 
2698 /**
2699  *  ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
2700  *  @hw: pointer to hardware structure
2701  *  @speed: the link speed to force
2702  *
2703  *  Configures the integrated KR PHY to use iXFI mode. Used to connect an
2704  *  internal and external PHY at a specific speed, without autonegotiation.
2705  **/
ixgbe_setup_ixfi_x550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed)2706 int32_t ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2707 {
2708 	struct ixgbe_mac_info *mac = &hw->mac;
2709 	int32_t status;
2710 	uint32_t reg_val;
2711 
2712 	/* iXFI is only supported with X552 */
2713 	if (mac->type != ixgbe_mac_X550EM_x)
2714 		return IXGBE_ERR_LINK_SETUP;
2715 
2716 	/* Disable AN and force speed to 10G Serial. */
2717 	status = mac->ops.read_iosf_sb_reg(hw,
2718 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2719 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2720 	if (status != IXGBE_SUCCESS)
2721 		return status;
2722 
2723 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2724 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
2725 
2726 	/* Select forced link speed for internal PHY. */
2727 	switch (*speed) {
2728 	case IXGBE_LINK_SPEED_10GB_FULL:
2729 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
2730 		break;
2731 	case IXGBE_LINK_SPEED_1GB_FULL:
2732 		reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
2733 		break;
2734 	default:
2735 		/* Other link speeds are not supported by internal KR PHY. */
2736 		return IXGBE_ERR_LINK_SETUP;
2737 	}
2738 
2739 	status = mac->ops.write_iosf_sb_reg(hw,
2740 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2741 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2742 	if (status != IXGBE_SUCCESS)
2743 		return status;
2744 
2745 	/* Additional configuration needed for x550em_x */
2746 	if (hw->mac.type == ixgbe_mac_X550EM_x) {
2747 		status = ixgbe_setup_ixfi_x550em_x(hw);
2748 		if (status != IXGBE_SUCCESS)
2749 			return status;
2750 	}
2751 
2752 	/* Toggle port SW reset by AN reset. */
2753 	status = ixgbe_restart_an_internal_phy_x550em(hw);
2754 
2755 	return status;
2756 }
2757 
2758 /**
2759  * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
2760  * @hw: address of hardware structure
2761  * @link_up: address of boolean to indicate link status
2762  *
2763  * Returns error code if unable to get link status.
2764  */
ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw * hw,bool * link_up)2765 int32_t ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
2766 {
2767 	uint32_t ret;
2768 	uint16_t autoneg_status;
2769 
2770 	*link_up = FALSE;
2771 
2772 	/* read this twice back to back to indicate current status */
2773 	ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2774 				   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2775 				   &autoneg_status);
2776 	if (ret != IXGBE_SUCCESS)
2777 		return ret;
2778 
2779 	ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2780 				   IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2781 				   &autoneg_status);
2782 	if (ret != IXGBE_SUCCESS)
2783 		return ret;
2784 
2785 	*link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
2786 
2787 	return IXGBE_SUCCESS;
2788 }
2789 
2790 /**
2791  * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
2792  * @hw: point to hardware structure
2793  *
2794  * Configures the link between the integrated KR PHY and the external X557 PHY
2795  * The driver will call this function when it gets a link status change
2796  * interrupt from the X557 PHY. This function configures the link speed
2797  * between the PHYs to match the link speed of the BASE-T link.
2798  *
2799  * A return of a non-zero value indicates an error, and the base driver should
2800  * not report link up.
2801  */
ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw * hw)2802 int32_t ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
2803 {
2804 	ixgbe_link_speed force_speed;
2805 	bool link_up;
2806 	uint32_t status;
2807 	uint16_t speed;
2808 
2809 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
2810 		return IXGBE_ERR_CONFIG;
2811 
2812 	if (hw->mac.type == ixgbe_mac_X550EM_x &&
2813 	    !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
2814 		/* If link is down, there is no setup necessary so return  */
2815 		status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2816 		if (status != IXGBE_SUCCESS)
2817 			return status;
2818 
2819 		if (!link_up)
2820 			return IXGBE_SUCCESS;
2821 
2822 		status = hw->phy.ops.read_reg(hw,
2823 					      IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
2824 					      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2825 					      &speed);
2826 		if (status != IXGBE_SUCCESS)
2827 			return status;
2828 
2829 		/* If link is still down - no setup is required so return */
2830 		status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2831 		if (status != IXGBE_SUCCESS)
2832 			return status;
2833 		if (!link_up)
2834 			return IXGBE_SUCCESS;
2835 
2836 		/* clear everything but the speed and duplex bits */
2837 		speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
2838 
2839 		switch (speed) {
2840 		case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
2841 			force_speed = IXGBE_LINK_SPEED_10GB_FULL;
2842 			break;
2843 		case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
2844 			force_speed = IXGBE_LINK_SPEED_1GB_FULL;
2845 			break;
2846 		default:
2847 			/* Internal PHY does not support anything else */
2848 			return IXGBE_ERR_INVALID_LINK_SETTINGS;
2849 		}
2850 
2851 		return ixgbe_setup_ixfi_x550em(hw, &force_speed);
2852 	} else {
2853 		speed = IXGBE_LINK_SPEED_10GB_FULL |
2854 			IXGBE_LINK_SPEED_1GB_FULL;
2855 		return ixgbe_setup_kr_speed_x550em(hw, speed);
2856 	}
2857 }
2858 
2859 /**
2860  *  ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
2861  *  @hw: pointer to hardware structure
2862  *
2863  *  Configures the integrated KR PHY to use internal loopback mode.
2864  **/
ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw * hw)2865 int32_t ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
2866 {
2867 	int32_t status;
2868 	uint32_t reg_val;
2869 
2870 	/* Disable AN and force speed to 10G Serial. */
2871 	status = hw->mac.ops.read_iosf_sb_reg(hw,
2872 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2873 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2874 	if (status != IXGBE_SUCCESS)
2875 		return status;
2876 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2877 	reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
2878 	reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
2879 	status = hw->mac.ops.write_iosf_sb_reg(hw,
2880 					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2881 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2882 	if (status != IXGBE_SUCCESS)
2883 		return status;
2884 
2885 	/* Set near-end loopback clocks. */
2886 	status = hw->mac.ops.read_iosf_sb_reg(hw,
2887 				IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
2888 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2889 	if (status != IXGBE_SUCCESS)
2890 		return status;
2891 	reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
2892 	reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
2893 	status = hw->mac.ops.write_iosf_sb_reg(hw,
2894 				IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
2895 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2896 	if (status != IXGBE_SUCCESS)
2897 		return status;
2898 
2899 	/* Set loopback enable. */
2900 	status = hw->mac.ops.read_iosf_sb_reg(hw,
2901 				IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
2902 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2903 	if (status != IXGBE_SUCCESS)
2904 		return status;
2905 	reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
2906 	status = hw->mac.ops.write_iosf_sb_reg(hw,
2907 				IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
2908 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2909 	if (status != IXGBE_SUCCESS)
2910 		return status;
2911 
2912 	/* Training bypass. */
2913 	status = hw->mac.ops.read_iosf_sb_reg(hw,
2914 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2915 				IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2916 	if (status != IXGBE_SUCCESS)
2917 		return status;
2918 	reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
2919 	status = hw->mac.ops.write_iosf_sb_reg(hw,
2920 				IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2921 				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2922 
2923 	return status;
2924 }
2925 
2926 /**
2927  *  ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
2928  *  assuming that the semaphore is already obtained.
2929  *  @hw: pointer to hardware structure
2930  *  @offset: offset of  word in the EEPROM to read
2931  *  @data: word read from the EEPROM
2932  *
2933  *  Reads a 16 bit word from the EEPROM using the hostif.
2934  **/
ixgbe_read_ee_hostif_X550(struct ixgbe_hw * hw,uint16_t offset,uint16_t * data)2935 int32_t ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset,uint16_t *data)
2936 {
2937 	const uint32_t mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
2938 	struct ixgbe_hic_read_shadow_ram buffer;
2939 	int32_t status;
2940 
2941 	DEBUGFUNC("ixgbe_read_ee_hostif_X550");
2942 	buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
2943 	buffer.hdr.req.buf_lenh = 0;
2944 	buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
2945 	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
2946 
2947 	/* convert offset from words to bytes */
2948 	buffer.address = htobe32(offset * 2);
2949 	/* one word */
2950 	buffer.length = htobe16(sizeof(uint16_t));
2951 	buffer.pad2 = 0;
2952 	buffer.pad3 = 0;
2953 
2954 	status = hw->mac.ops.acquire_swfw_sync(hw, mask);
2955 	if (status)
2956 		return status;
2957 
2958 	status = ixgbe_hic_unlocked(hw, (uint32_t *)&buffer, sizeof(buffer),
2959 				    IXGBE_HI_COMMAND_TIMEOUT);
2960 	if (!status) {
2961 		*data = (uint16_t)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
2962 						  FW_NVM_DATA_OFFSET);
2963 	}
2964 
2965 	hw->mac.ops.release_swfw_sync(hw, mask);
2966 	return status;
2967 }
2968 
2969 /**
2970  *  ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
2971  *  @hw: pointer to hardware structure
2972  *  @offset: offset of  word in the EEPROM to read
2973  *  @words: number of words
2974  *  @data: word(s) read from the EEPROM
2975  *
2976  *  Reads a 16 bit word(s) from the EEPROM using the hostif.
2977  **/
ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw * hw,uint16_t offset,uint16_t words,uint16_t * data)2978 int32_t ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
2979 					 uint16_t offset, uint16_t words,
2980 					 uint16_t *data)
2981 {
2982 	const uint32_t mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
2983 	struct ixgbe_hic_read_shadow_ram buffer;
2984 	uint32_t current_word = 0;
2985 	uint16_t words_to_read;
2986 	int32_t status;
2987 	uint32_t i;
2988 
2989 	DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
2990 
2991 	/* Take semaphore for the entire operation. */
2992 	status = hw->mac.ops.acquire_swfw_sync(hw, mask);
2993 	if (status) {
2994 		DEBUGOUT("EEPROM read buffer - semaphore failed\n");
2995 		return status;
2996 	}
2997 
2998 	while (words) {
2999 		if (words > FW_MAX_READ_BUFFER_SIZE / 2)
3000 			words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
3001 		else
3002 			words_to_read = words;
3003 
3004 		buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3005 		buffer.hdr.req.buf_lenh = 0;
3006 		buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3007 		buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3008 
3009 		/* convert offset from words to bytes */
3010 		buffer.address = htobe32((offset + current_word) * 2);
3011 		buffer.length = htobe16(words_to_read * 2);
3012 		buffer.pad2 = 0;
3013 		buffer.pad3 = 0;
3014 
3015 		status = ixgbe_hic_unlocked(hw, (uint32_t *)&buffer, sizeof(buffer),
3016 					    IXGBE_HI_COMMAND_TIMEOUT);
3017 
3018 		if (status) {
3019 			DEBUGOUT("Host interface command failed\n");
3020 			goto out;
3021 		}
3022 
3023 		for (i = 0; i < words_to_read; i++) {
3024 			uint32_t reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
3025 				  2 * i;
3026 			uint32_t value = IXGBE_READ_REG(hw, reg);
3027 
3028 			data[current_word] = (uint16_t)(value & 0xffff);
3029 			current_word++;
3030 			i++;
3031 			if (i < words_to_read) {
3032 				value >>= 16;
3033 				data[current_word] = (uint16_t)(value & 0xffff);
3034 				current_word++;
3035 			}
3036 		}
3037 		words -= words_to_read;
3038 	}
3039 
3040 out:
3041 	hw->mac.ops.release_swfw_sync(hw, mask);
3042 	return status;
3043 }
3044 
3045 /**
3046  *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3047  *  @hw: pointer to hardware structure
3048  *  @offset: offset of  word in the EEPROM to write
3049  *  @data: word write to the EEPROM
3050  *
3051  *  Write a 16 bit word to the EEPROM using the hostif.
3052  **/
ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw * hw,uint16_t offset,uint16_t data)3053 int32_t ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, uint16_t offset,
3054 					uint16_t data)
3055 {
3056 	int32_t status;
3057 	struct ixgbe_hic_write_shadow_ram buffer;
3058 
3059 	DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
3060 
3061 	buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
3062 	buffer.hdr.req.buf_lenh = 0;
3063 	buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
3064 	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3065 
3066 	 /* one word */
3067 	buffer.length = htobe16(sizeof(uint16_t));
3068 	buffer.data = data;
3069 	buffer.address = htobe32(offset * 2);
3070 
3071 	status = ixgbe_host_interface_command(hw, (uint32_t *)&buffer,
3072 					      sizeof(buffer),
3073 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
3074 
3075 	return status;
3076 }
3077 
3078 /**
3079  *  ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3080  *  @hw: pointer to hardware structure
3081  *  @offset: offset of  word in the EEPROM to write
3082  *  @data: word write to the EEPROM
3083  *
3084  *  Write a 16 bit word to the EEPROM using the hostif.
3085  **/
ixgbe_write_ee_hostif_X550(struct ixgbe_hw * hw,uint16_t offset,uint16_t data)3086 int32_t ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, uint16_t offset,
3087 				   uint16_t data)
3088 {
3089 	int32_t status = IXGBE_SUCCESS;
3090 
3091 	DEBUGFUNC("ixgbe_write_ee_hostif_X550");
3092 
3093 	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
3094 	    IXGBE_SUCCESS) {
3095 		status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
3096 		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3097 	} else {
3098 		DEBUGOUT("write ee hostif failed to get semaphore");
3099 		status = IXGBE_ERR_SWFW_SYNC;
3100 	}
3101 
3102 	return status;
3103 }
3104 
3105 /**
3106  * ixgbe_checksum_ptr_x550 - Checksum one pointer region
3107  * @hw: pointer to hardware structure
3108  * @ptr: pointer offset in eeprom
3109  * @size: size of section pointed by ptr, if 0 first word will be used as size
3110  * @csum: address of checksum to update
3111  * @buffer: pointer to buffer containing calculated checksum
3112  * @buffer_size: size of buffer
3113  *
3114  * Returns error status for any failure
3115  */
ixgbe_checksum_ptr_x550(struct ixgbe_hw * hw,uint16_t ptr,uint16_t size,uint16_t * csum,uint16_t * buffer,uint32_t buffer_size)3116 int32_t ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, uint16_t ptr,
3117 				uint16_t size, uint16_t *csum, uint16_t *buffer,
3118 				uint32_t buffer_size)
3119 {
3120 	uint16_t buf[256];
3121 	int32_t status;
3122 	uint16_t length, bufsz, i, start;
3123 	uint16_t *local_buffer;
3124 
3125 	bufsz = sizeof(buf) / sizeof(buf[0]);
3126 
3127 	/* Read a chunk at the pointer location */
3128 	if (!buffer) {
3129 		status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
3130 		if (status) {
3131 			DEBUGOUT("Failed to read EEPROM image\n");
3132 			return status;
3133 		}
3134 		local_buffer = buf;
3135 	} else {
3136 		if (buffer_size < ptr)
3137 			return  IXGBE_ERR_PARAM;
3138 		local_buffer = &buffer[ptr];
3139 	}
3140 
3141 	if (size) {
3142 		start = 0;
3143 		length = size;
3144 	} else {
3145 		start = 1;
3146 		length = local_buffer[0];
3147 
3148 		/* Skip pointer section if length is invalid. */
3149 		if (length == 0xFFFF || length == 0 ||
3150 		    (ptr + length) >= hw->eeprom.word_size)
3151 			return IXGBE_SUCCESS;
3152 	}
3153 
3154 	if (buffer && ((uint32_t)start + (uint32_t)length > buffer_size))
3155 		return IXGBE_ERR_PARAM;
3156 
3157 	for (i = start; length; i++, length--) {
3158 		if (i == bufsz && !buffer) {
3159 			ptr += bufsz;
3160 			i = 0;
3161 			if (length < bufsz)
3162 				bufsz = length;
3163 
3164 			/* Read a chunk at the pointer location */
3165 			status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
3166 								  bufsz, buf);
3167 			if (status) {
3168 				DEBUGOUT("Failed to read EEPROM image\n");
3169 				return status;
3170 			}
3171 		}
3172 		*csum += local_buffer[i];
3173 	}
3174 	return IXGBE_SUCCESS;
3175 }
3176 
3177 /**
3178  *  ixgbe_calc_checksum_X550 - Calculates and returns the checksum
3179  *  @hw: pointer to hardware structure
3180  *  @buffer: pointer to buffer containing calculated checksum
3181  *  @buffer_size: size of buffer
3182  *
3183  *  Returns a negative error code on error, or the 16-bit checksum
3184  **/
ixgbe_calc_checksum_X550(struct ixgbe_hw * hw,uint16_t * buffer,uint32_t buffer_size)3185 int32_t ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, uint16_t *buffer,
3186 				 uint32_t buffer_size)
3187 {
3188 	uint16_t eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
3189 	uint16_t *local_buffer;
3190 	int32_t status;
3191 	uint16_t checksum = 0;
3192 	uint16_t pointer, i, size;
3193 
3194 	DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
3195 
3196 	hw->eeprom.ops.init_params(hw);
3197 
3198 	if (!buffer) {
3199 		/* Read pointer area */
3200 		status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
3201 						     IXGBE_EEPROM_LAST_WORD + 1,
3202 						     eeprom_ptrs);
3203 		if (status) {
3204 			DEBUGOUT("Failed to read EEPROM image\n");
3205 			return status;
3206 		}
3207 		local_buffer = eeprom_ptrs;
3208 	} else {
3209 		if (buffer_size < IXGBE_EEPROM_LAST_WORD)
3210 			return IXGBE_ERR_PARAM;
3211 		local_buffer = buffer;
3212 	}
3213 
3214 	/*
3215 	 * For X550 hardware include 0x0-0x41 in the checksum, skip the
3216 	 * checksum word itself
3217 	 */
3218 	for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
3219 		if (i != IXGBE_EEPROM_CHECKSUM)
3220 			checksum += local_buffer[i];
3221 
3222 	/*
3223 	 * Include all data from pointers 0x3, 0x6-0xE.  This excludes the
3224 	 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
3225 	 */
3226 	for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
3227 		if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
3228 			continue;
3229 
3230 		pointer = local_buffer[i];
3231 
3232 		/* Skip pointer section if the pointer is invalid. */
3233 		if (pointer == 0xFFFF || pointer == 0 ||
3234 		    pointer >= hw->eeprom.word_size)
3235 			continue;
3236 
3237 		switch (i) {
3238 		case IXGBE_PCIE_GENERAL_PTR:
3239 			size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
3240 			break;
3241 		case IXGBE_PCIE_CONFIG0_PTR:
3242 		case IXGBE_PCIE_CONFIG1_PTR:
3243 			size = IXGBE_PCIE_CONFIG_SIZE;
3244 			break;
3245 		default:
3246 			size = 0;
3247 			break;
3248 		}
3249 
3250 		status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
3251 						buffer, buffer_size);
3252 		if (status)
3253 			return status;
3254 	}
3255 
3256 	checksum = (uint16_t)IXGBE_EEPROM_SUM - checksum;
3257 
3258 	return (int32_t)checksum;
3259 }
3260 
3261 /**
3262  *  ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
3263  *  @hw: pointer to hardware structure
3264  *
3265  *  Returns a negative error code on error, or the 16-bit checksum
3266  **/
ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw * hw)3267 int32_t ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
3268 {
3269 	return ixgbe_calc_checksum_X550(hw, NULL, 0);
3270 }
3271 
3272 /**
3273  *  ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
3274  *  @hw: pointer to hardware structure
3275  *  @checksum_val: calculated checksum
3276  *
3277  *  Performs checksum calculation and validates the EEPROM checksum.  If the
3278  *  caller does not need checksum_val, the value can be NULL.
3279  **/
ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw * hw,uint16_t * checksum_val)3280 int32_t ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, uint16_t *checksum_val)
3281 {
3282 	int32_t status;
3283 	uint16_t checksum;
3284 	uint16_t read_checksum = 0;
3285 
3286 	DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
3287 
3288 	/* Read the first word from the EEPROM. If this times out or fails, do
3289 	 * not continue or we could be in for a very long wait while every
3290 	 * EEPROM read fails
3291 	 */
3292 	status = hw->eeprom.ops.read(hw, 0, &checksum);
3293 	if (status) {
3294 		DEBUGOUT("EEPROM read failed\n");
3295 		return status;
3296 	}
3297 
3298 	status = hw->eeprom.ops.calc_checksum(hw);
3299 	if (status < 0)
3300 		return status;
3301 
3302 	checksum = (uint16_t)(status & 0xffff);
3303 
3304 	status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3305 					   &read_checksum);
3306 	if (status)
3307 		return status;
3308 
3309 	/* Verify read checksum from EEPROM is the same as
3310 	 * calculated checksum
3311 	 */
3312 	if (read_checksum != checksum) {
3313 		status = IXGBE_ERR_EEPROM_CHECKSUM;
3314 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
3315 			     "Invalid EEPROM checksum");
3316 	}
3317 
3318 	/* If the user cares, return the calculated checksum */
3319 	if (checksum_val)
3320 		*checksum_val = checksum;
3321 
3322 	return status;
3323 }
3324 
3325 /**
3326  * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
3327  * @hw: pointer to hardware structure
3328  *
3329  * After writing EEPROM to shadow RAM using EEWR register, software calculates
3330  * checksum and updates the EEPROM and instructs the hardware to update
3331  * the flash.
3332  **/
ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw * hw)3333 int32_t ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
3334 {
3335 	int32_t status;
3336 	uint16_t checksum = 0;
3337 
3338 	DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
3339 
3340 	/* Read the first word from the EEPROM. If this times out or fails, do
3341 	 * not continue or we could be in for a very long wait while every
3342 	 * EEPROM read fails
3343 	 */
3344 	status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
3345 	if (status) {
3346 		DEBUGOUT("EEPROM read failed\n");
3347 		return status;
3348 	}
3349 
3350 	status = ixgbe_calc_eeprom_checksum_X550(hw);
3351 	if (status < 0)
3352 		return status;
3353 
3354 	checksum = (uint16_t)(status & 0xffff);
3355 
3356 	status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3357 					    checksum);
3358 	if (status)
3359 		return status;
3360 
3361 	status = ixgbe_update_flash_X550(hw);
3362 
3363 	return status;
3364 }
3365 
3366 /**
3367  *  ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
3368  *  @hw: pointer to hardware structure
3369  *
3370  *  Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
3371  **/
ixgbe_update_flash_X550(struct ixgbe_hw * hw)3372 int32_t ixgbe_update_flash_X550(struct ixgbe_hw *hw)
3373 {
3374 	int32_t status = IXGBE_SUCCESS;
3375 	union ixgbe_hic_hdr2 buffer;
3376 
3377 	DEBUGFUNC("ixgbe_update_flash_X550");
3378 
3379 	buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
3380 	buffer.req.buf_lenh = 0;
3381 	buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
3382 	buffer.req.checksum = FW_DEFAULT_CHECKSUM;
3383 
3384 	status = ixgbe_host_interface_command(hw, (uint32_t *)&buffer,
3385 					      sizeof(buffer),
3386 					      IXGBE_HI_COMMAND_TIMEOUT, FALSE);
3387 
3388 	return status;
3389 }
3390 
3391 /**
3392  *  ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
3393  *  @hw: pointer to hardware structure
3394  *
3395  *  Determines physical layer capabilities of the current configuration.
3396  **/
ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw * hw)3397 uint64_t ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
3398 {
3399 	uint64_t physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
3400 	uint16_t ext_ability = 0;
3401 
3402 	DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
3403 
3404 	hw->phy.ops.identify(hw);
3405 
3406 	switch (hw->phy.type) {
3407 	case ixgbe_phy_x550em_kr:
3408 		if (hw->mac.type == ixgbe_mac_X550EM_a) {
3409 			if (hw->phy.nw_mng_if_sel &
3410 			    IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
3411 				physical_layer =
3412 					IXGBE_PHYSICAL_LAYER_2500BASE_KX;
3413 				break;
3414 			} else if (hw->device_id ==
3415 				   IXGBE_DEV_ID_X550EM_A_KR_L) {
3416 				physical_layer =
3417 					IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3418 				break;
3419 			}
3420 		}
3421 		/* fall through */
3422 	case ixgbe_phy_x550em_xfi:
3423 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
3424 				 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3425 		break;
3426 	case ixgbe_phy_x550em_kx4:
3427 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
3428 				 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3429 		break;
3430 	case ixgbe_phy_x550em_ext_t:
3431 		hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
3432 				     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
3433 				     &ext_ability);
3434 		if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
3435 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
3436 		if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
3437 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3438 		break;
3439 	case ixgbe_phy_fw:
3440 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL)
3441 			physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3442 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL)
3443 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
3444 		if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL)
3445 			physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
3446 		break;
3447 	case ixgbe_phy_sgmii:
3448 		physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3449 		break;
3450 	case ixgbe_phy_ext_1g_t:
3451 		physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
3452 		break;
3453 	default:
3454 		break;
3455 	}
3456 
3457 	if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
3458 		physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
3459 
3460 	return physical_layer;
3461 }
3462 
3463 /**
3464  * ixgbe_get_bus_info_x550em - Set PCI bus info
3465  * @hw: pointer to hardware structure
3466  *
3467  * Sets bus link width and speed to unknown because X550em is
3468  * not a PCI device.
3469  **/
ixgbe_get_bus_info_X550em(struct ixgbe_hw * hw)3470 int32_t ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
3471 {
3472 
3473 	DEBUGFUNC("ixgbe_get_bus_info_x550em");
3474 
3475 	hw->bus.width = ixgbe_bus_width_unknown;
3476 	hw->bus.speed = ixgbe_bus_speed_unknown;
3477 
3478 	hw->mac.ops.set_lan_id(hw);
3479 
3480 	return IXGBE_SUCCESS;
3481 }
3482 
3483 /**
3484  * ixgbe_disable_rx_x550 - Disable RX unit
3485  * @hw: pointer to hardware structure
3486  *
3487  * Enables the Rx DMA unit for x550
3488  **/
ixgbe_disable_rx_x550(struct ixgbe_hw * hw)3489 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
3490 {
3491 	uint32_t rxctrl, pfdtxgswc;
3492 	int32_t status;
3493 	struct ixgbe_hic_disable_rxen fw_cmd;
3494 
3495 	DEBUGFUNC("ixgbe_enable_rx_dma_x550");
3496 
3497 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3498 	if (rxctrl & IXGBE_RXCTRL_RXEN) {
3499 		pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
3500 		if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
3501 			pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
3502 			IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
3503 			hw->mac.set_lben = TRUE;
3504 		} else {
3505 			hw->mac.set_lben = FALSE;
3506 		}
3507 
3508 		fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
3509 		fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
3510 		fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
3511 		fw_cmd.port_number = (uint8_t)hw->bus.lan_id;
3512 
3513 		status = ixgbe_host_interface_command(hw, (uint32_t *)&fw_cmd,
3514 					sizeof(struct ixgbe_hic_disable_rxen),
3515 					IXGBE_HI_COMMAND_TIMEOUT, TRUE);
3516 
3517 		/* If we fail - disable RX using register write */
3518 		if (status) {
3519 			rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3520 			if (rxctrl & IXGBE_RXCTRL_RXEN) {
3521 				rxctrl &= ~IXGBE_RXCTRL_RXEN;
3522 				IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
3523 			}
3524 		}
3525 	}
3526 }
3527 
3528 /**
3529  * ixgbe_enter_lplu_x550em - Transition to low power states
3530  *  @hw: pointer to hardware structure
3531  *
3532  * Configures Low Power Link Up on transition to low power states
3533  * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
3534  * X557 PHY immediately prior to entering LPLU.
3535  **/
ixgbe_enter_lplu_t_x550em(struct ixgbe_hw * hw)3536 int32_t ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
3537 {
3538 	uint16_t an_10g_cntl_reg, autoneg_reg, speed;
3539 	int32_t status;
3540 	ixgbe_link_speed lcd_speed;
3541 	uint32_t save_autoneg;
3542 	bool link_up;
3543 
3544 	/* SW LPLU not required on later HW revisions. */
3545 	if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
3546 	    (IXGBE_FUSES0_REV_MASK &
3547 	     IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
3548 		return IXGBE_SUCCESS;
3549 
3550 	/* If blocked by MNG FW, then don't restart AN */
3551 	if (ixgbe_check_reset_blocked(hw))
3552 		return IXGBE_SUCCESS;
3553 
3554 	status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3555 	if (status != IXGBE_SUCCESS)
3556 		return status;
3557 
3558 	status = hw->eeprom.ops.read(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
3559 	if (status != IXGBE_SUCCESS)
3560 		return status;
3561 
3562 	/* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
3563 	 * disabled, then force link down by entering low power mode.
3564 	 */
3565 	if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
3566 	    !(hw->wol_enabled || ixgbe_mng_present(hw)))
3567 		return ixgbe_set_copper_phy_power(hw, FALSE);
3568 
3569 	/* Determine LCD */
3570 	status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
3571 
3572 	if (status != IXGBE_SUCCESS)
3573 		return status;
3574 
3575 	/* If no valid LCD link speed, then force link down and exit. */
3576 	if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
3577 		return ixgbe_set_copper_phy_power(hw, FALSE);
3578 
3579 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
3580 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3581 				      &speed);
3582 
3583 	if (status != IXGBE_SUCCESS)
3584 		return status;
3585 
3586 	/* If no link now, speed is invalid so take link down */
3587 	status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3588 	if (status != IXGBE_SUCCESS)
3589 		return ixgbe_set_copper_phy_power(hw, FALSE);
3590 
3591 	/* clear everything but the speed bits */
3592 	speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
3593 
3594 	/* If current speed is already LCD, then exit. */
3595 	if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
3596 	     (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
3597 	    ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
3598 	     (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
3599 		return status;
3600 
3601 	/* Clear AN completed indication */
3602 	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
3603 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3604 				      &autoneg_reg);
3605 
3606 	if (status != IXGBE_SUCCESS)
3607 		return status;
3608 
3609 	status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
3610 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3611 			     &an_10g_cntl_reg);
3612 
3613 	if (status != IXGBE_SUCCESS)
3614 		return status;
3615 
3616 	status = hw->phy.ops.read_reg(hw,
3617 			     IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
3618 			     IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3619 			     &autoneg_reg);
3620 
3621 	if (status != IXGBE_SUCCESS)
3622 		return status;
3623 
3624 	save_autoneg = hw->phy.autoneg_advertised;
3625 
3626 	/* Setup link at least common link speed */
3627 	status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
3628 
3629 	/* restore autoneg from before setting lplu speed */
3630 	hw->phy.autoneg_advertised = save_autoneg;
3631 
3632 	return status;
3633 }
3634 
3635 /**
3636  * ixgbe_get_lcd_x550em - Determine lowest common denominator
3637  *  @hw: pointer to hardware structure
3638  *  @lcd_speed: pointer to lowest common link speed
3639  *
3640  * Determine lowest common link speed with link partner.
3641  **/
ixgbe_get_lcd_t_x550em(struct ixgbe_hw * hw,ixgbe_link_speed * lcd_speed)3642 int32_t ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
3643 {
3644 	uint16_t an_lp_status;
3645 	int32_t status;
3646 	uint16_t word = hw->eeprom.ctrl_word_3;
3647 
3648 	*lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
3649 
3650 	status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
3651 				      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3652 				      &an_lp_status);
3653 
3654 	if (status != IXGBE_SUCCESS)
3655 		return status;
3656 
3657 	/* If link partner advertised 1G, return 1G */
3658 	if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
3659 		*lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
3660 		return status;
3661 	}
3662 
3663 	/* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
3664 	if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
3665 	    (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
3666 		return status;
3667 
3668 	/* Link partner not capable of lower speeds, return 10G */
3669 	*lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
3670 	return status;
3671 }
3672 
3673 /**
3674  *  ixgbe_setup_fc_X550em - Set up flow control
3675  *  @hw: pointer to hardware structure
3676  *
3677  *  Called at init time to set up flow control.
3678  **/
ixgbe_setup_fc_X550em(struct ixgbe_hw * hw)3679 int32_t ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
3680 {
3681 	int32_t ret_val = IXGBE_SUCCESS;
3682 	uint32_t pause, asm_dir, reg_val;
3683 
3684 	DEBUGFUNC("ixgbe_setup_fc_X550em");
3685 
3686 	/* Validate the requested mode */
3687 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
3688 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3689 			"ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
3690 		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
3691 		goto out;
3692 	}
3693 
3694 	/* 10gig parts do not have a word in the EEPROM to determine the
3695 	 * default flow control setting, so we explicitly set it to full.
3696 	 */
3697 	if (hw->fc.requested_mode == ixgbe_fc_default)
3698 		hw->fc.requested_mode = ixgbe_fc_full;
3699 
3700 	/* Determine PAUSE and ASM_DIR bits. */
3701 	switch (hw->fc.requested_mode) {
3702 	case ixgbe_fc_none:
3703 		pause = 0;
3704 		asm_dir = 0;
3705 		break;
3706 	case ixgbe_fc_tx_pause:
3707 		pause = 0;
3708 		asm_dir = 1;
3709 		break;
3710 	case ixgbe_fc_rx_pause:
3711 		/* Rx Flow control is enabled and Tx Flow control is
3712 		 * disabled by software override. Since there really
3713 		 * isn't a way to advertise that we are capable of RX
3714 		 * Pause ONLY, we will advertise that we support both
3715 		 * symmetric and asymmetric Rx PAUSE, as such we fall
3716 		 * through to the fc_full statement.  Later, we will
3717 		 * disable the adapter's ability to send PAUSE frames.
3718 		 */
3719 	case ixgbe_fc_full:
3720 		pause = 1;
3721 		asm_dir = 1;
3722 		break;
3723 	default:
3724 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
3725 			"Flow control param set incorrectly\n");
3726 		ret_val = IXGBE_ERR_CONFIG;
3727 		goto out;
3728 	}
3729 
3730 	switch (hw->device_id) {
3731 	case IXGBE_DEV_ID_X550EM_X_KR:
3732 	case IXGBE_DEV_ID_X550EM_A_KR:
3733 	case IXGBE_DEV_ID_X550EM_A_KR_L:
3734 		ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
3735 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3736 					IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3737 		if (ret_val != IXGBE_SUCCESS)
3738 			goto out;
3739 		reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3740 			IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
3741 		if (pause)
3742 			reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
3743 		if (asm_dir)
3744 			reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3745 		ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
3746 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3747 					IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3748 
3749 		/* This device does not fully support AN. */
3750 		hw->fc.disable_fc_autoneg = TRUE;
3751 		break;
3752 	case IXGBE_DEV_ID_X550EM_X_XFI:
3753 		hw->fc.disable_fc_autoneg = TRUE;
3754 		break;
3755 	default:
3756 		break;
3757 	}
3758 
3759 out:
3760 	return ret_val;
3761 }
3762 
3763 /**
3764  *  ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
3765  *  @hw: pointer to hardware structure
3766  *
3767  *  Enable flow control according to IEEE clause 37.
3768  **/
ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw * hw)3769 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
3770 {
3771 	uint32_t link_s1, lp_an_page_low, an_cntl_1;
3772 	int32_t status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3773 	ixgbe_link_speed speed;
3774 	bool link_up;
3775 
3776 	/* AN should have completed when the cable was plugged in.
3777 	 * Look for reasons to bail out.  Bail out if:
3778 	 * - FC autoneg is disabled, or if
3779 	 * - link is not up.
3780 	 */
3781 	if (hw->fc.disable_fc_autoneg) {
3782 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3783 			     "Flow control autoneg is disabled");
3784 		goto out;
3785 	}
3786 
3787 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
3788 	if (!link_up) {
3789 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
3790 		goto out;
3791 	}
3792 
3793 	/* Check at auto-negotiation has completed */
3794 	status = hw->mac.ops.read_iosf_sb_reg(hw,
3795 					IXGBE_KRM_LINK_S1(hw->bus.lan_id),
3796 					IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
3797 
3798 	if (status != IXGBE_SUCCESS ||
3799 	    (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
3800 		DEBUGOUT("Auto-Negotiation did not complete\n");
3801 		status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3802 		goto out;
3803 	}
3804 
3805 	/* Read the 10g AN autoc and LP ability registers and resolve
3806 	 * local flow control settings accordingly
3807 	 */
3808 	status = hw->mac.ops.read_iosf_sb_reg(hw,
3809 				IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3810 				IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
3811 
3812 	if (status != IXGBE_SUCCESS) {
3813 		DEBUGOUT("Auto-Negotiation did not complete\n");
3814 		goto out;
3815 	}
3816 
3817 	status = hw->mac.ops.read_iosf_sb_reg(hw,
3818 				IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
3819 				IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
3820 
3821 	if (status != IXGBE_SUCCESS) {
3822 		DEBUGOUT("Auto-Negotiation did not complete\n");
3823 		goto out;
3824 	}
3825 
3826 	status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
3827 				    IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
3828 				    IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
3829 				    IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
3830 				    IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
3831 
3832 out:
3833 	if (status == IXGBE_SUCCESS) {
3834 		hw->fc.fc_was_autonegged = TRUE;
3835 	} else {
3836 		hw->fc.fc_was_autonegged = FALSE;
3837 		hw->fc.current_mode = hw->fc.requested_mode;
3838 	}
3839 }
3840 
3841 /**
3842  *  ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
3843  *  @hw: pointer to hardware structure
3844  *
3845  **/
ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw * hw)3846 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
3847 {
3848 	hw->fc.fc_was_autonegged = FALSE;
3849 	hw->fc.current_mode = hw->fc.requested_mode;
3850 }
3851 
3852 /**
3853  *  ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
3854  *  @hw: pointer to hardware structure
3855  *
3856  *  Enable flow control according to IEEE clause 37.
3857  **/
ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw * hw)3858 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
3859 {
3860 	int32_t status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3861 	uint32_t info[FW_PHY_ACT_DATA_COUNT] = { 0 };
3862 	ixgbe_link_speed speed;
3863 	bool link_up;
3864 
3865 	/* AN should have completed when the cable was plugged in.
3866 	 * Look for reasons to bail out.  Bail out if:
3867 	 * - FC autoneg is disabled, or if
3868 	 * - link is not up.
3869 	 */
3870 	if (hw->fc.disable_fc_autoneg) {
3871 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3872 			     "Flow control autoneg is disabled");
3873 		goto out;
3874 	}
3875 
3876 	hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
3877 	if (!link_up) {
3878 		ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
3879 		goto out;
3880 	}
3881 
3882 	/* Check if auto-negotiation has completed */
3883 	status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
3884 	if (status != IXGBE_SUCCESS ||
3885 	    !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
3886 		DEBUGOUT("Auto-Negotiation did not complete\n");
3887 		status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3888 		goto out;
3889 	}
3890 
3891 	/* Negotiate the flow control */
3892 	status = ixgbe_negotiate_fc(hw, info[0], info[0],
3893 				    FW_PHY_ACT_GET_LINK_INFO_FC_RX,
3894 				    FW_PHY_ACT_GET_LINK_INFO_FC_TX,
3895 				    FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
3896 				    FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
3897 
3898 out:
3899 	if (status == IXGBE_SUCCESS) {
3900 		hw->fc.fc_was_autonegged = TRUE;
3901 	} else {
3902 		hw->fc.fc_was_autonegged = FALSE;
3903 		hw->fc.current_mode = hw->fc.requested_mode;
3904 	}
3905 }
3906 
3907 /**
3908  *  ixgbe_setup_fc_backplane_x550em_a - Set up flow control
3909  *  @hw: pointer to hardware structure
3910  *
3911  *  Called at init time to set up flow control.
3912  **/
ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw * hw)3913 int32_t ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
3914 {
3915 	int32_t status = IXGBE_SUCCESS;
3916 	uint32_t an_cntl = 0;
3917 
3918 	DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
3919 
3920 	/* Validate the requested mode */
3921 	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
3922 		ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3923 			      "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
3924 		return IXGBE_ERR_INVALID_LINK_SETTINGS;
3925 	}
3926 
3927 	if (hw->fc.requested_mode == ixgbe_fc_default)
3928 		hw->fc.requested_mode = ixgbe_fc_full;
3929 
3930 	/* Set up the 1G and 10G flow control advertisement registers so the
3931 	 * HW will be able to do FC autoneg once the cable is plugged in.  If
3932 	 * we link at 10G, the 1G advertisement is harmless and vice versa.
3933 	 */
3934 	status = hw->mac.ops.read_iosf_sb_reg(hw,
3935 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3936 					IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
3937 
3938 	if (status != IXGBE_SUCCESS) {
3939 		DEBUGOUT("Auto-Negotiation did not complete\n");
3940 		return status;
3941 	}
3942 
3943 	/* The possible values of fc.requested_mode are:
3944 	 * 0: Flow control is completely disabled
3945 	 * 1: Rx flow control is enabled (we can receive pause frames,
3946 	 *    but not send pause frames).
3947 	 * 2: Tx flow control is enabled (we can send pause frames but
3948 	 *    we do not support receiving pause frames).
3949 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
3950 	 * other: Invalid.
3951 	 */
3952 	switch (hw->fc.requested_mode) {
3953 	case ixgbe_fc_none:
3954 		/* Flow control completely disabled by software override. */
3955 		an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3956 			     IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
3957 		break;
3958 	case ixgbe_fc_tx_pause:
3959 		/* Tx Flow control is enabled, and Rx Flow control is
3960 		 * disabled by software override.
3961 		 */
3962 		an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3963 		an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
3964 		break;
3965 	case ixgbe_fc_rx_pause:
3966 		/* Rx Flow control is enabled and Tx Flow control is
3967 		 * disabled by software override. Since there really
3968 		 * isn't a way to advertise that we are capable of RX
3969 		 * Pause ONLY, we will advertise that we support both
3970 		 * symmetric and asymmetric Rx PAUSE, as such we fall
3971 		 * through to the fc_full statement.  Later, we will
3972 		 * disable the adapter's ability to send PAUSE frames.
3973 		 */
3974 	case ixgbe_fc_full:
3975 		/* Flow control (both Rx and Tx) is enabled by SW override. */
3976 		an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3977 			   IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3978 		break;
3979 	default:
3980 		ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
3981 			      "Flow control param set incorrectly\n");
3982 		return IXGBE_ERR_CONFIG;
3983 	}
3984 
3985 	status = hw->mac.ops.write_iosf_sb_reg(hw,
3986 					IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3987 					IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
3988 
3989 	/* Restart auto-negotiation. */
3990 	status = ixgbe_restart_an_internal_phy_x550em(hw);
3991 
3992 	return status;
3993 }
3994 
3995 /**
3996  * ixgbe_set_mux - Set mux for port 1 access with CS4227
3997  * @hw: pointer to hardware structure
3998  * @state: set mux if 1, clear if 0
3999  */
ixgbe_set_mux(struct ixgbe_hw * hw,uint8_t state)4000 void ixgbe_set_mux(struct ixgbe_hw *hw, uint8_t state)
4001 {
4002 	uint32_t esdp;
4003 
4004 	if (!hw->bus.lan_id)
4005 		return;
4006 	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4007 	if (state)
4008 		esdp |= IXGBE_ESDP_SDP1;
4009 	else
4010 		esdp &= ~IXGBE_ESDP_SDP1;
4011 	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4012 	IXGBE_WRITE_FLUSH(hw);
4013 }
4014 
4015 /**
4016  *  ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
4017  *  @hw: pointer to hardware structure
4018  *  @mask: Mask to specify which semaphore to acquire
4019  *
4020  *  Acquires the SWFW semaphore and sets the I2C MUX
4021  **/
ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw * hw,uint32_t mask)4022 int32_t ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask)
4023 {
4024 	int32_t status;
4025 
4026 	DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
4027 
4028 	status = ixgbe_acquire_swfw_sync_X540(hw, mask);
4029 	if (status)
4030 		return status;
4031 
4032 	if (mask & IXGBE_GSSR_I2C_MASK)
4033 		ixgbe_set_mux(hw, 1);
4034 
4035 	return IXGBE_SUCCESS;
4036 }
4037 
4038 /**
4039  *  ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
4040  *  @hw: pointer to hardware structure
4041  *  @mask: Mask to specify which semaphore to release
4042  *
4043  *  Releases the SWFW semaphore and sets the I2C MUX
4044  **/
ixgbe_release_swfw_sync_X550em(struct ixgbe_hw * hw,uint32_t mask)4045 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, uint32_t mask)
4046 {
4047 	DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
4048 
4049 	if (mask & IXGBE_GSSR_I2C_MASK)
4050 		ixgbe_set_mux(hw, 0);
4051 
4052 	ixgbe_release_swfw_sync_X540(hw, mask);
4053 }
4054 
4055 /**
4056  *  ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
4057  *  @hw: pointer to hardware structure
4058  *  @mask: Mask to specify which semaphore to acquire
4059  *
4060  *  Acquires the SWFW semaphore and get the shared phy token as needed
4061  */
ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw * hw,uint32_t mask)4062 int32_t ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, uint32_t mask)
4063 {
4064 	uint32_t hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4065 	int retries = FW_PHY_TOKEN_RETRIES;
4066 	int32_t status = IXGBE_SUCCESS;
4067 
4068 	DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
4069 
4070 	while (--retries) {
4071 		status = IXGBE_SUCCESS;
4072 		if (hmask)
4073 			status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
4074 		if (status) {
4075 			DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n",
4076 				  status);
4077 			return status;
4078 		}
4079 		if (!(mask & IXGBE_GSSR_TOKEN_SM))
4080 			return IXGBE_SUCCESS;
4081 
4082 		status = ixgbe_get_phy_token(hw);
4083 		if (status == IXGBE_ERR_TOKEN_RETRY)
4084 			DEBUGOUT1("Could not acquire PHY token, Status = %d\n",
4085 				  status);
4086 
4087 		if (status == IXGBE_SUCCESS)
4088 			return IXGBE_SUCCESS;
4089 
4090 		if (hmask)
4091 			ixgbe_release_swfw_sync_X540(hw, hmask);
4092 
4093 		if (status != IXGBE_ERR_TOKEN_RETRY) {
4094 			DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n",
4095 				  status);
4096 			return status;
4097 		}
4098 	}
4099 
4100 	DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n",
4101 		  hw->phy.id);
4102 	return status;
4103 }
4104 
4105 /**
4106  *  ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
4107  *  @hw: pointer to hardware structure
4108  *  @mask: Mask to specify which semaphore to release
4109  *
4110  *  Releases the SWFW semaphore and puts the shared phy token as needed
4111  */
ixgbe_release_swfw_sync_X550a(struct ixgbe_hw * hw,uint32_t mask)4112 void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, uint32_t mask)
4113 {
4114 	uint32_t hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4115 
4116 	DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
4117 
4118 	if (mask & IXGBE_GSSR_TOKEN_SM)
4119 		ixgbe_put_phy_token(hw);
4120 
4121 	if (hmask)
4122 		ixgbe_release_swfw_sync_X540(hw, hmask);
4123 }
4124 
4125 /**
4126  *  ixgbe_read_phy_reg_x550a  - Reads specified PHY register
4127  *  @hw: pointer to hardware structure
4128  *  @reg_addr: 32 bit address of PHY register to read
4129  *  @device_type: 5 bit device type
4130  *  @phy_data: Pointer to read data from PHY register
4131  *
4132  *  Reads a value from a specified PHY register using the SWFW lock and PHY
4133  *  Token. The PHY Token is needed since the MDIO is shared between to MAC
4134  *  instances.
4135  **/
ixgbe_read_phy_reg_x550a(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint16_t * phy_data)4136 int32_t ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
4137 			       uint32_t device_type, uint16_t *phy_data)
4138 {
4139 	int32_t status;
4140 	uint32_t mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4141 
4142 	DEBUGFUNC("ixgbe_read_phy_reg_x550a");
4143 
4144 	if (hw->mac.ops.acquire_swfw_sync(hw, mask))
4145 		return IXGBE_ERR_SWFW_SYNC;
4146 
4147 	status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
4148 
4149 	hw->mac.ops.release_swfw_sync(hw, mask);
4150 
4151 	return status;
4152 }
4153 
4154 /**
4155  *  ixgbe_write_phy_reg_x550a - Writes specified PHY register
4156  *  @hw: pointer to hardware structure
4157  *  @reg_addr: 32 bit PHY register to write
4158  *  @device_type: 5 bit device type
4159  *  @phy_data: Data to write to the PHY register
4160  *
4161  *  Writes a value to specified PHY register using the SWFW lock and PHY Token.
4162  *  The PHY Token is needed since the MDIO is shared between to MAC instances.
4163  **/
ixgbe_write_phy_reg_x550a(struct ixgbe_hw * hw,uint32_t reg_addr,uint32_t device_type,uint16_t phy_data)4164 int32_t ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, uint32_t reg_addr,
4165 				uint32_t device_type, uint16_t phy_data)
4166 {
4167 	int32_t status;
4168 	uint32_t mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4169 
4170 	DEBUGFUNC("ixgbe_write_phy_reg_x550a");
4171 
4172 	if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) {
4173 		status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
4174 						 phy_data);
4175 		hw->mac.ops.release_swfw_sync(hw, mask);
4176 	} else {
4177 		status = IXGBE_ERR_SWFW_SYNC;
4178 	}
4179 
4180 	return status;
4181 }
4182 
4183 /**
4184  * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
4185  * @hw: pointer to hardware structure
4186  *
4187  * Handle external Base T PHY interrupt. If high temperature
4188  * failure alarm then return error, else if link status change
4189  * then setup internal/external PHY link
4190  *
4191  * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
4192  * failure alarm, else return PHY access status.
4193  */
ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw * hw)4194 int32_t ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
4195 {
4196 	bool lsc;
4197 	uint32_t status;
4198 
4199 	status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
4200 
4201 	if (status != IXGBE_SUCCESS)
4202 		return status;
4203 
4204 	if (lsc)
4205 		return hw->phy.ops.setup_internal_link(hw);
4206 
4207 	return IXGBE_SUCCESS;
4208 }
4209 
4210 /**
4211  * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
4212  * @hw: pointer to hardware structure
4213  * @speed: new link speed
4214  * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
4215  *
4216  * Setup internal/external PHY link speed based on link speed, then set
4217  * external PHY auto advertised link speed.
4218  *
4219  * Returns error status for any failure
4220  **/
ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)4221 int32_t ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
4222 				      ixgbe_link_speed speed,
4223 				      bool autoneg_wait_to_complete)
4224 {
4225 	int32_t status;
4226 	ixgbe_link_speed force_speed;
4227 
4228 	DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
4229 
4230 	/* Setup internal/external PHY link speed to iXFI (10G), unless
4231 	 * only 1G is auto advertised then setup KX link.
4232 	 */
4233 	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
4234 		force_speed = IXGBE_LINK_SPEED_10GB_FULL;
4235 	else
4236 		force_speed = IXGBE_LINK_SPEED_1GB_FULL;
4237 
4238 	/* If X552 and internal link mode is XFI, then setup XFI internal link.
4239 	 */
4240 	if (hw->mac.type == ixgbe_mac_X550EM_x &&
4241 	    !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
4242 		status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
4243 
4244 		if (status != IXGBE_SUCCESS)
4245 			return status;
4246 	}
4247 
4248 	return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
4249 }
4250 
4251 /**
4252  * ixgbe_check_link_t_X550em - Determine link and speed status
4253  * @hw: pointer to hardware structure
4254  * @speed: pointer to link speed
4255  * @link_up: TRUE when link is up
4256  * @link_up_wait_to_complete: bool used to wait for link up or not
4257  *
4258  * Check that both the MAC and X557 external PHY have link.
4259  **/
ixgbe_check_link_t_X550em(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)4260 int32_t ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
4261 				  bool *link_up, bool link_up_wait_to_complete)
4262 {
4263 	uint32_t status;
4264 	uint16_t i, autoneg_status = 0;
4265 
4266 	if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
4267 		return IXGBE_ERR_CONFIG;
4268 
4269 	status = ixgbe_check_mac_link_generic(hw, speed, link_up,
4270 					      link_up_wait_to_complete);
4271 
4272 	/* If check link fails or MAC link is not up, then return */
4273 	if (status != IXGBE_SUCCESS || !(*link_up))
4274 		return status;
4275 
4276 	/* MAC link is up, so check external PHY link.
4277 	 * X557 PHY. Link status is latching low, and can only be used to detect
4278 	 * link drop, and not the current status of the link without performing
4279 	 * back-to-back reads.
4280 	 */
4281 	for (i = 0; i < 2; i++) {
4282 		status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
4283 					      IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4284 					      &autoneg_status);
4285 
4286 		if (status != IXGBE_SUCCESS)
4287 			return status;
4288 	}
4289 
4290 	/* If external PHY link is not up, then indicate link not up */
4291 	if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
4292 		*link_up = FALSE;
4293 
4294 	return IXGBE_SUCCESS;
4295 }
4296 
4297 /**
4298  *  ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
4299  *  @hw: pointer to hardware structure
4300  **/
ixgbe_reset_phy_t_X550em(struct ixgbe_hw * hw)4301 int32_t ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
4302 {
4303 	int32_t status;
4304 
4305 	status = ixgbe_reset_phy_generic(hw);
4306 
4307 	if (status != IXGBE_SUCCESS)
4308 		return status;
4309 
4310 	/* Configure Link Status Alarm and Temperature Threshold interrupts */
4311 	return ixgbe_enable_lasi_ext_t_x550em(hw);
4312 }
4313 
4314 /**
4315  *  ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
4316  *  @hw: pointer to hardware structure
4317  *  @led_idx: led number to turn on
4318  **/
ixgbe_led_on_t_X550em(struct ixgbe_hw * hw,uint32_t led_idx)4319 int32_t ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx)
4320 {
4321 	uint16_t phy_data;
4322 
4323 	DEBUGFUNC("ixgbe_led_on_t_X550em");
4324 
4325 	if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4326 		return IXGBE_ERR_PARAM;
4327 
4328 	if (hw->phy.id == 0)
4329 		ixgbe_identify_phy(hw);
4330 
4331 	/* To turn on the LED, set mode to ON. */
4332 	hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4333 			   IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4334 	phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
4335 	hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4336 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4337 
4338 	/* Some designs have the LEDs wired to the MAC */
4339 	return ixgbe_led_on_generic(hw, led_idx);
4340 }
4341 
4342 /**
4343  *  ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
4344  *  @hw: pointer to hardware structure
4345  *  @led_idx: led number to turn off
4346  **/
ixgbe_led_off_t_X550em(struct ixgbe_hw * hw,uint32_t led_idx)4347 int32_t ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, uint32_t led_idx)
4348 {
4349 	uint16_t phy_data;
4350 
4351 	DEBUGFUNC("ixgbe_led_off_t_X550em");
4352 
4353 	if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4354 		return IXGBE_ERR_PARAM;
4355 
4356 	if (hw->phy.id == 0)
4357 		ixgbe_identify_phy(hw);
4358 
4359 	/* To turn on the LED, set mode to ON. */
4360 	hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4361 			   IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4362 	phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
4363 	hw->phy.ops.write_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4364 			    IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4365 
4366 	/* Some designs have the LEDs wired to the MAC */
4367 	return ixgbe_led_off_generic(hw, led_idx);
4368 }
4369