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