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