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