1 /******************************************************************************
3 Copyright (c) 2001-2017, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
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.
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.
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.
32 ******************************************************************************/
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"
42 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
43 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
44 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
45 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
48 * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
49 * @hw: pointer to hardware structure
51 * Initialize the function pointers and assign the MAC type for X550.
52 * Does not touch the hardware.
54 s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
56 struct ixgbe_mac_info *mac = &hw->mac;
57 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
60 DEBUGFUNC("ixgbe_init_ops_X550");
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;
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;
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_1G_T:
91 hw->mac.ops.led_on = NULL;
92 hw->mac.ops.led_off = NULL;
94 case IXGBE_DEV_ID_X550EM_X_10G_T:
95 case IXGBE_DEV_ID_X550EM_A_10G_T:
96 hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
97 hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
106 * ixgbe_read_cs4227 - Read CS4227 register
107 * @hw: pointer to hardware structure
108 * @reg: register number to write
109 * @value: pointer to receive value read
111 * Returns status code
113 static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
115 return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
119 * ixgbe_write_cs4227 - Write CS4227 register
120 * @hw: pointer to hardware structure
121 * @reg: register number to write
122 * @value: value to write to register
124 * Returns status code
126 static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
128 return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
132 * ixgbe_read_pe - Read register from port expander
133 * @hw: pointer to hardware structure
134 * @reg: register number to read
135 * @value: pointer to receive read value
137 * Returns status code
139 static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
143 status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
144 if (status != IXGBE_SUCCESS)
145 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
146 "port expander access failed with %d\n", status);
151 * ixgbe_write_pe - Write register to port expander
152 * @hw: pointer to hardware structure
153 * @reg: register number to write
154 * @value: value to write
156 * Returns status code
158 static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
162 status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
163 if (status != IXGBE_SUCCESS)
164 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
165 "port expander access failed with %d\n", status);
170 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
171 * @hw: pointer to hardware structure
173 * This function assumes that the caller has acquired the proper semaphore.
176 static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
183 /* Trigger hard reset. */
184 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
185 if (status != IXGBE_SUCCESS)
187 reg |= IXGBE_PE_BIT1;
188 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
189 if (status != IXGBE_SUCCESS)
192 status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, ®);
193 if (status != IXGBE_SUCCESS)
195 reg &= ~IXGBE_PE_BIT1;
196 status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
197 if (status != IXGBE_SUCCESS)
200 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
201 if (status != IXGBE_SUCCESS)
203 reg &= ~IXGBE_PE_BIT1;
204 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
205 if (status != IXGBE_SUCCESS)
208 usec_delay(IXGBE_CS4227_RESET_HOLD);
210 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
211 if (status != IXGBE_SUCCESS)
213 reg |= IXGBE_PE_BIT1;
214 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
215 if (status != IXGBE_SUCCESS)
218 /* Wait for the reset to complete. */
219 msec_delay(IXGBE_CS4227_RESET_DELAY);
220 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
221 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
223 if (status == IXGBE_SUCCESS &&
224 value == IXGBE_CS4227_EEPROM_LOAD_OK)
226 msec_delay(IXGBE_CS4227_CHECK_DELAY);
228 if (retry == IXGBE_CS4227_RETRIES) {
229 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
230 "CS4227 reset did not complete.");
231 return IXGBE_ERR_PHY;
234 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
235 if (status != IXGBE_SUCCESS ||
236 !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
237 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
238 "CS4227 EEPROM did not load successfully.");
239 return IXGBE_ERR_PHY;
242 return IXGBE_SUCCESS;
246 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
247 * @hw: pointer to hardware structure
249 static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
251 s32 status = IXGBE_SUCCESS;
252 u32 swfw_mask = hw->phy.phy_semaphore_mask;
256 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
257 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
258 if (status != IXGBE_SUCCESS) {
259 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
260 "semaphore failed with %d", status);
261 msec_delay(IXGBE_CS4227_CHECK_DELAY);
265 /* Get status of reset flow. */
266 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
268 if (status == IXGBE_SUCCESS &&
269 value == IXGBE_CS4227_RESET_COMPLETE)
272 if (status != IXGBE_SUCCESS ||
273 value != IXGBE_CS4227_RESET_PENDING)
276 /* Reset is pending. Wait and check again. */
277 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
278 msec_delay(IXGBE_CS4227_CHECK_DELAY);
281 /* If still pending, assume other instance failed. */
282 if (retry == IXGBE_CS4227_RETRIES) {
283 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
284 if (status != IXGBE_SUCCESS) {
285 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
286 "semaphore failed with %d", status);
291 /* Reset the CS4227. */
292 status = ixgbe_reset_cs4227(hw);
293 if (status != IXGBE_SUCCESS) {
294 ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
295 "CS4227 reset failed: %d", status);
299 /* Reset takes so long, temporarily release semaphore in case the
300 * other driver instance is waiting for the reset indication.
302 ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
303 IXGBE_CS4227_RESET_PENDING);
304 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
306 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
307 if (status != IXGBE_SUCCESS) {
308 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
309 "semaphore failed with %d", status);
313 /* Record completion for next time. */
314 status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
315 IXGBE_CS4227_RESET_COMPLETE);
318 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
319 msec_delay(hw->eeprom.semaphore_delay);
323 * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
324 * @hw: pointer to hardware structure
326 static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
328 u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
330 if (hw->bus.lan_id) {
331 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
332 esdp |= IXGBE_ESDP_SDP1_DIR;
334 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
335 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
336 IXGBE_WRITE_FLUSH(hw);
340 * ixgbe_identify_phy_x550em - Get PHY type based on device id
341 * @hw: pointer to hardware structure
345 static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
347 hw->mac.ops.set_lan_id(hw);
349 ixgbe_read_mng_if_sel_x550em(hw);
351 switch (hw->device_id) {
352 case IXGBE_DEV_ID_X550EM_A_SFP:
353 return ixgbe_identify_module_generic(hw);
354 case IXGBE_DEV_ID_X550EM_X_SFP:
355 /* set up for CS4227 usage */
356 ixgbe_setup_mux_ctl(hw);
357 ixgbe_check_cs4227(hw);
360 case IXGBE_DEV_ID_X550EM_A_SFP_N:
361 return ixgbe_identify_module_generic(hw);
363 case IXGBE_DEV_ID_X550EM_X_KX4:
364 hw->phy.type = ixgbe_phy_x550em_kx4;
366 case IXGBE_DEV_ID_X550EM_X_XFI:
367 hw->phy.type = ixgbe_phy_x550em_xfi;
369 case IXGBE_DEV_ID_X550EM_X_KR:
370 case IXGBE_DEV_ID_X550EM_A_KR:
371 case IXGBE_DEV_ID_X550EM_A_KR_L:
372 hw->phy.type = ixgbe_phy_x550em_kr;
374 case IXGBE_DEV_ID_X550EM_A_10G_T:
375 case IXGBE_DEV_ID_X550EM_X_10G_T:
376 return ixgbe_identify_phy_generic(hw);
377 case IXGBE_DEV_ID_X550EM_X_1G_T:
378 hw->phy.type = ixgbe_phy_ext_1g_t;
380 case IXGBE_DEV_ID_X550EM_A_1G_T:
381 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
382 hw->phy.type = ixgbe_phy_fw;
384 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
386 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
391 return IXGBE_SUCCESS;
395 * ixgbe_fw_phy_activity - Perform an activity on a PHY
396 * @hw: pointer to hardware structure
397 * @activity: activity to perform
398 * @data: Pointer to 4 32-bit words of data
400 s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
401 u32 (*data)[FW_PHY_ACT_DATA_COUNT])
404 struct ixgbe_hic_phy_activity_req cmd;
405 struct ixgbe_hic_phy_activity_resp rsp;
407 u16 retries = FW_PHY_ACT_RETRIES;
412 memset(&hic, 0, sizeof(hic));
413 hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
414 hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
415 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
416 hic.cmd.port_number = hw->bus.lan_id;
417 hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
418 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
419 hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
421 rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
423 IXGBE_HI_COMMAND_TIMEOUT,
425 if (rc != IXGBE_SUCCESS)
427 if (hic.rsp.hdr.cmd_or_resp.ret_status ==
428 FW_CEM_RESP_STATUS_SUCCESS) {
429 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
430 (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
431 return IXGBE_SUCCESS;
435 } while (retries > 0);
437 return IXGBE_ERR_HOST_INTERFACE_COMMAND;
440 static const struct {
442 ixgbe_link_speed phy_speed;
444 { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
445 { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
446 { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
447 { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
448 { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
449 { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
453 * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
454 * @hw: pointer to hardware structure
458 static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
460 u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
466 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
470 hw->phy.speeds_supported = 0;
471 phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
472 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
473 if (phy_speeds & ixgbe_fw_map[i].fw_speed)
474 hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
476 if (!hw->phy.autoneg_advertised)
477 hw->phy.autoneg_advertised = hw->phy.speeds_supported;
479 hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
480 phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
481 hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
482 hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
483 if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
484 return IXGBE_ERR_PHY_ADDR_INVALID;
485 return IXGBE_SUCCESS;
489 * ixgbe_identify_phy_fw - Get PHY type based on firmware command
490 * @hw: pointer to hardware structure
494 static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
497 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
499 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
501 hw->phy.type = ixgbe_phy_fw;
502 hw->phy.ops.read_reg = NULL;
503 hw->phy.ops.write_reg = NULL;
504 return ixgbe_get_phy_id_fw(hw);
508 * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
509 * @hw: pointer to hardware structure
513 s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
515 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
517 setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
518 return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
521 static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
522 u32 device_type, u16 *phy_data)
524 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
525 return IXGBE_NOT_IMPLEMENTED;
528 static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
529 u32 device_type, u16 phy_data)
531 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
532 return IXGBE_NOT_IMPLEMENTED;
536 * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
537 * @hw: pointer to the hardware structure
538 * @addr: I2C bus address to read from
539 * @reg: I2C device register to read from
540 * @val: pointer to location to receive read value
542 * Returns an error code on error.
544 static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
547 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
551 * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
552 * @hw: pointer to the hardware structure
553 * @addr: I2C bus address to read from
554 * @reg: I2C device register to read from
555 * @val: pointer to location to receive read value
557 * Returns an error code on error.
560 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
563 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
567 * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
568 * @hw: pointer to the hardware structure
569 * @addr: I2C bus address to write to
570 * @reg: I2C device register to write to
571 * @val: value to write
573 * Returns an error code on error.
575 static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
576 u8 addr, u16 reg, u16 val)
578 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
582 * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
583 * @hw: pointer to the hardware structure
584 * @addr: I2C bus address to write to
585 * @reg: I2C device register to write to
586 * @val: value to write
588 * Returns an error code on error.
591 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
592 u8 addr, u16 reg, u16 val)
594 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
598 * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
599 * @hw: pointer to hardware structure
601 * Initialize the function pointers and for MAC type X550EM.
602 * Does not touch the hardware.
604 s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
606 struct ixgbe_mac_info *mac = &hw->mac;
607 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
608 struct ixgbe_phy_info *phy = &hw->phy;
611 DEBUGFUNC("ixgbe_init_ops_X550EM");
613 /* Similar to X550 so start there. */
614 ret_val = ixgbe_init_ops_X550(hw);
616 /* Since this function eventually calls
617 * ixgbe_init_ops_540 by design, we are setting
618 * the pointers to NULL explicitly here to overwrite
619 * the values being set in the x540 function.
622 /* Bypass not supported in x550EM */
623 mac->ops.bypass_rw = NULL;
624 mac->ops.bypass_valid_rd = NULL;
625 mac->ops.bypass_set = NULL;
626 mac->ops.bypass_rd_eep = NULL;
628 /* FCOE not supported in x550EM */
629 mac->ops.get_san_mac_addr = NULL;
630 mac->ops.set_san_mac_addr = NULL;
631 mac->ops.get_wwn_prefix = NULL;
632 mac->ops.get_fcoe_boot_status = NULL;
634 /* IPsec not supported in x550EM */
635 mac->ops.disable_sec_rx_path = NULL;
636 mac->ops.enable_sec_rx_path = NULL;
638 /* AUTOC register is not present in x550EM. */
639 mac->ops.prot_autoc_read = NULL;
640 mac->ops.prot_autoc_write = NULL;
642 /* X550EM bus type is internal*/
643 hw->bus.type = ixgbe_bus_type_internal;
644 mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
647 mac->ops.get_media_type = ixgbe_get_media_type_X550em;
648 mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
649 mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
650 mac->ops.reset_hw = ixgbe_reset_hw_X550em;
651 mac->ops.get_supported_physical_layer =
652 ixgbe_get_supported_physical_layer_X550em;
654 if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
655 mac->ops.setup_fc = ixgbe_setup_fc_generic;
657 mac->ops.setup_fc = ixgbe_setup_fc_X550em;
660 phy->ops.init = ixgbe_init_phy_ops_X550em;
661 switch (hw->device_id) {
662 case IXGBE_DEV_ID_X550EM_A_1G_T:
663 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
664 mac->ops.setup_fc = NULL;
665 phy->ops.identify = ixgbe_identify_phy_fw;
666 phy->ops.set_phy_power = NULL;
667 phy->ops.get_firmware_version = NULL;
669 case IXGBE_DEV_ID_X550EM_X_1G_T:
670 mac->ops.setup_fc = NULL;
671 phy->ops.identify = ixgbe_identify_phy_x550em;
672 phy->ops.set_phy_power = NULL;
675 phy->ops.identify = ixgbe_identify_phy_x550em;
678 if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
679 phy->ops.set_phy_power = NULL;
683 eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
684 eeprom->ops.read = ixgbe_read_ee_hostif_X550;
685 eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
686 eeprom->ops.write = ixgbe_write_ee_hostif_X550;
687 eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
688 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
689 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
690 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
696 * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
697 * @hw: pointer to hardware structure
699 static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
701 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
705 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
708 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
709 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
710 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
711 return IXGBE_ERR_INVALID_LINK_SETTINGS;
714 switch (hw->fc.requested_mode) {
716 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
717 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
719 case ixgbe_fc_rx_pause:
720 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
721 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
723 case ixgbe_fc_tx_pause:
724 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
725 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
731 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
732 if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
733 setup[0] |= (u32)(ixgbe_fw_map[i].fw_speed);
735 setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
737 if (hw->phy.eee_speeds_advertised)
738 setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
740 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
743 if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
744 return IXGBE_ERR_OVERTEMP;
745 return IXGBE_SUCCESS;
749 * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
750 * @hw: pointer to hardware structure
752 * Called at init time to set up flow control.
754 static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
756 if (hw->fc.requested_mode == ixgbe_fc_default)
757 hw->fc.requested_mode = ixgbe_fc_full;
759 return ixgbe_setup_fw_link(hw);
763 * ixgbe_setup_eee_fw - Enable/disable EEE support
764 * @hw: pointer to the HW structure
765 * @enable_eee: boolean flag to enable EEE
767 * Enable/disable EEE based on enable_eee flag.
768 * This function controls EEE for firmware-based PHY implementations.
770 static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
772 if (!!hw->phy.eee_speeds_advertised == enable_eee)
773 return IXGBE_SUCCESS;
775 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
777 hw->phy.eee_speeds_advertised = 0;
778 return hw->phy.ops.setup_link(hw);
782 * ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
783 * @hw: pointer to hardware structure
785 * Initialize the function pointers and for MAC type X550EM_a.
786 * Does not touch the hardware.
788 s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
790 struct ixgbe_mac_info *mac = &hw->mac;
793 DEBUGFUNC("ixgbe_init_ops_X550EM_a");
795 /* Start with generic X550EM init */
796 ret_val = ixgbe_init_ops_X550EM(hw);
798 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
799 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
800 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
801 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
803 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
804 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
806 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
807 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
809 switch (mac->ops.get_media_type(hw)) {
810 case ixgbe_media_type_fiber:
811 mac->ops.setup_fc = NULL;
812 mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
814 case ixgbe_media_type_backplane:
815 mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
816 mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
822 switch (hw->device_id) {
823 case IXGBE_DEV_ID_X550EM_A_1G_T:
824 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
825 mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
826 mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
827 mac->ops.setup_eee = ixgbe_setup_eee_fw;
828 hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
829 IXGBE_LINK_SPEED_1GB_FULL;
830 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
840 * ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
841 * @hw: pointer to hardware structure
843 * Initialize the function pointers and for MAC type X550EM_x.
844 * Does not touch the hardware.
846 s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
848 struct ixgbe_mac_info *mac = &hw->mac;
849 struct ixgbe_link_info *link = &hw->link;
852 DEBUGFUNC("ixgbe_init_ops_X550EM_x");
854 /* Start with generic X550EM init */
855 ret_val = ixgbe_init_ops_X550EM(hw);
857 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
858 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
859 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
860 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
861 link->ops.read_link = ixgbe_read_i2c_combined_generic;
862 link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
863 link->ops.write_link = ixgbe_write_i2c_combined_generic;
864 link->ops.write_link_unlocked =
865 ixgbe_write_i2c_combined_generic_unlocked;
866 link->addr = IXGBE_CS4227;
868 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) {
869 mac->ops.setup_fc = NULL;
870 mac->ops.setup_eee = NULL;
871 mac->ops.init_led_link_act = NULL;
878 * ixgbe_dmac_config_X550
879 * @hw: pointer to hardware structure
881 * Configure DMA coalescing. If enabling dmac, dmac is activated.
882 * When disabling dmac, dmac enable dmac bit is cleared.
884 s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
886 u32 reg, high_pri_tc;
888 DEBUGFUNC("ixgbe_dmac_config_X550");
890 /* Disable DMA coalescing before configuring */
891 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
892 reg &= ~IXGBE_DMACR_DMAC_EN;
893 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
895 /* Disable DMA Coalescing if the watchdog timer is 0 */
896 if (!hw->mac.dmac_config.watchdog_timer)
899 ixgbe_dmac_config_tcs_X550(hw);
901 /* Configure DMA Coalescing Control Register */
902 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
904 /* Set the watchdog timer in units of 40.96 usec */
905 reg &= ~IXGBE_DMACR_DMACWT_MASK;
906 reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
908 reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
909 /* If fcoe is enabled, set high priority traffic class */
910 if (hw->mac.dmac_config.fcoe_en) {
911 high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
912 reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
913 IXGBE_DMACR_HIGH_PRI_TC_MASK);
915 reg |= IXGBE_DMACR_EN_MNG_IND;
917 /* Enable DMA coalescing after configuration */
918 reg |= IXGBE_DMACR_DMAC_EN;
919 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
922 return IXGBE_SUCCESS;
926 * ixgbe_dmac_config_tcs_X550
927 * @hw: pointer to hardware structure
929 * Configure DMA coalescing threshold per TC. The dmac enable bit must
930 * be cleared before configuring.
932 s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
934 u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
936 DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
938 /* Configure DMA coalescing enabled */
939 switch (hw->mac.dmac_config.link_speed) {
940 case IXGBE_LINK_SPEED_10_FULL:
941 case IXGBE_LINK_SPEED_100_FULL:
942 pb_headroom = IXGBE_DMACRXT_100M;
944 case IXGBE_LINK_SPEED_1GB_FULL:
945 pb_headroom = IXGBE_DMACRXT_1G;
948 pb_headroom = IXGBE_DMACRXT_10G;
952 maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
953 IXGBE_MHADD_MFS_SHIFT) / 1024);
955 /* Set the per Rx packet buffer receive threshold */
956 for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
957 reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
958 reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
960 if (tc < hw->mac.dmac_config.num_tcs) {
962 rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
963 rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
964 IXGBE_RXPBSIZE_SHIFT;
966 /* Calculate receive buffer threshold in kilobytes */
967 if (rx_pb_size > pb_headroom)
968 rx_pb_size = rx_pb_size - pb_headroom;
972 /* Minimum of MFS shall be set for DMCTH */
973 reg |= (rx_pb_size > maxframe_size_kb) ?
974 rx_pb_size : maxframe_size_kb;
976 IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
978 return IXGBE_SUCCESS;
982 * ixgbe_dmac_update_tcs_X550
983 * @hw: pointer to hardware structure
985 * Disables dmac, updates per TC settings, and then enables dmac.
987 s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
991 DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
993 /* Disable DMA coalescing before configuring */
994 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
995 reg &= ~IXGBE_DMACR_DMAC_EN;
996 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
998 ixgbe_dmac_config_tcs_X550(hw);
1000 /* Enable DMA coalescing after configuration */
1001 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
1002 reg |= IXGBE_DMACR_DMAC_EN;
1003 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
1005 return IXGBE_SUCCESS;
1009 * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
1010 * @hw: pointer to hardware structure
1012 * Initializes the EEPROM parameters ixgbe_eeprom_info within the
1013 * ixgbe_hw struct in order to set up EEPROM access.
1015 s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
1017 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
1021 DEBUGFUNC("ixgbe_init_eeprom_params_X550");
1023 if (eeprom->type == ixgbe_eeprom_uninitialized) {
1024 eeprom->semaphore_delay = 10;
1025 eeprom->type = ixgbe_flash;
1027 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
1028 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
1029 IXGBE_EEC_SIZE_SHIFT);
1030 eeprom->word_size = 1 << (eeprom_size +
1031 IXGBE_EEPROM_WORD_SIZE_SHIFT);
1033 DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
1034 eeprom->type, eeprom->word_size);
1037 return IXGBE_SUCCESS;
1041 * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
1042 * @hw: pointer to hardware structure
1043 * @enable: enable or disable source address pruning
1044 * @pool: Rx pool to set source address pruning for
1046 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
1051 /* max rx pool is 63 */
1055 pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
1056 pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
1059 pfflp |= (1ULL << pool);
1061 pfflp &= ~(1ULL << pool);
1063 IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
1064 IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
1068 * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
1069 * @hw: pointer to hardware structure
1070 * @enable: enable or disable switch for Ethertype anti-spoofing
1071 * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
1074 void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
1075 bool enable, int vf)
1077 int vf_target_reg = vf >> 3;
1078 int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
1081 DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
1083 pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
1085 pfvfspoof |= (1 << vf_target_shift);
1087 pfvfspoof &= ~(1 << vf_target_shift);
1089 IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
1093 * ixgbe_iosf_wait - Wait for IOSF command completion
1094 * @hw: pointer to hardware structure
1095 * @ctrl: pointer to location to receive final IOSF control value
1097 * Returns failing status on timeout
1099 * Note: ctrl can be NULL if the IOSF control register value is not needed
1101 static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
1105 /* Check every 10 usec to see if the address cycle completed.
1106 * The SB IOSF BUSY bit will clear when the operation is
1109 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
1110 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
1111 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
1117 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
1118 ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
1119 return IXGBE_ERR_PHY;
1122 return IXGBE_SUCCESS;
1126 * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
1127 * of the IOSF device
1128 * @hw: pointer to hardware structure
1129 * @reg_addr: 32 bit PHY register to write
1130 * @device_type: 3 bit device type
1131 * @data: Data to write to the register
1133 s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1134 u32 device_type, u32 data)
1136 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1137 u32 command, error __unused;
1140 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1141 if (ret != IXGBE_SUCCESS)
1144 ret = ixgbe_iosf_wait(hw, NULL);
1145 if (ret != IXGBE_SUCCESS)
1148 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1149 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1151 /* Write IOSF control register */
1152 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1154 /* Write IOSF data register */
1155 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
1157 ret = ixgbe_iosf_wait(hw, &command);
1159 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1160 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1161 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1162 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1163 "Failed to write, error %x\n", error);
1164 ret = IXGBE_ERR_PHY;
1168 ixgbe_release_swfw_semaphore(hw, gssr);
1173 * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
1174 * @hw: pointer to hardware structure
1175 * @reg_addr: 32 bit PHY register to write
1176 * @device_type: 3 bit device type
1177 * @data: Pointer to read data from the register
1179 s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1180 u32 device_type, u32 *data)
1182 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1183 u32 command, error __unused;
1186 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1187 if (ret != IXGBE_SUCCESS)
1190 ret = ixgbe_iosf_wait(hw, NULL);
1191 if (ret != IXGBE_SUCCESS)
1194 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1195 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1197 /* Write IOSF control register */
1198 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1200 ret = ixgbe_iosf_wait(hw, &command);
1202 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1203 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1204 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1205 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1206 "Failed to read, error %x\n", error);
1207 ret = IXGBE_ERR_PHY;
1210 if (ret == IXGBE_SUCCESS)
1211 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
1214 ixgbe_release_swfw_semaphore(hw, gssr);
1219 * ixgbe_get_phy_token - Get the token for shared phy access
1220 * @hw: Pointer to hardware structure
1223 s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
1225 struct ixgbe_hic_phy_token_req token_cmd;
1228 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1229 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1230 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1231 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1232 token_cmd.port_number = hw->bus.lan_id;
1233 token_cmd.command_type = FW_PHY_TOKEN_REQ;
1235 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1237 IXGBE_HI_COMMAND_TIMEOUT,
1240 DEBUGOUT1("Issuing host interface command failed with Status = %d\n",
1244 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1245 return IXGBE_SUCCESS;
1246 if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) {
1247 DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n",
1248 token_cmd.hdr.cmd_or_resp.ret_status);
1249 return IXGBE_ERR_FW_RESP_INVALID;
1252 DEBUGOUT("Returning IXGBE_ERR_TOKEN_RETRY\n");
1253 return IXGBE_ERR_TOKEN_RETRY;
1257 * ixgbe_put_phy_token - Put the token for shared phy access
1258 * @hw: Pointer to hardware structure
1261 s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
1263 struct ixgbe_hic_phy_token_req token_cmd;
1266 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1267 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1268 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1269 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1270 token_cmd.port_number = hw->bus.lan_id;
1271 token_cmd.command_type = FW_PHY_TOKEN_REL;
1273 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1275 IXGBE_HI_COMMAND_TIMEOUT,
1279 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1280 return IXGBE_SUCCESS;
1282 DEBUGOUT("Put PHY Token host interface command failed");
1283 return IXGBE_ERR_FW_RESP_INVALID;
1287 * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
1288 * of the IOSF device
1289 * @hw: pointer to hardware structure
1290 * @reg_addr: 32 bit PHY register to write
1291 * @device_type: 3 bit device type
1292 * @data: Data to write to the register
1294 s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1295 u32 device_type, u32 data)
1297 struct ixgbe_hic_internal_phy_req write_cmd;
1299 UNREFERENCED_1PARAMETER(device_type);
1301 memset(&write_cmd, 0, sizeof(write_cmd));
1302 write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1303 write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1304 write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1305 write_cmd.port_number = hw->bus.lan_id;
1306 write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
1307 write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1308 write_cmd.write_data = IXGBE_CPU_TO_BE32(data);
1310 status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd,
1312 IXGBE_HI_COMMAND_TIMEOUT, FALSE);
1318 * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
1319 * @hw: pointer to hardware structure
1320 * @reg_addr: 32 bit PHY register to write
1321 * @device_type: 3 bit device type
1322 * @data: Pointer to read data from the register
1324 s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1325 u32 device_type, u32 *data)
1328 struct ixgbe_hic_internal_phy_req cmd;
1329 struct ixgbe_hic_internal_phy_resp rsp;
1332 UNREFERENCED_1PARAMETER(device_type);
1334 memset(&hic, 0, sizeof(hic));
1335 hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1336 hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1337 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1338 hic.cmd.port_number = hw->bus.lan_id;
1339 hic.cmd.command_type = FW_INT_PHY_REQ_READ;
1340 hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1342 status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
1344 IXGBE_HI_COMMAND_TIMEOUT, TRUE);
1346 /* Extract the register value from the response. */
1347 *data = IXGBE_BE32_TO_CPU(hic.rsp.read_data);
1353 * ixgbe_disable_mdd_X550
1354 * @hw: pointer to hardware structure
1356 * Disable malicious driver detection
1358 void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
1362 DEBUGFUNC("ixgbe_disable_mdd_X550");
1364 /* Disable MDD for TX DMA and interrupt */
1365 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1366 reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1367 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1369 /* Disable MDD for RX and interrupt */
1370 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1371 reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1372 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1376 * ixgbe_enable_mdd_X550
1377 * @hw: pointer to hardware structure
1379 * Enable malicious driver detection
1381 void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
1385 DEBUGFUNC("ixgbe_enable_mdd_X550");
1387 /* Enable MDD for TX DMA and interrupt */
1388 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1389 reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1390 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1392 /* Enable MDD for RX and interrupt */
1393 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1394 reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1395 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1399 * ixgbe_restore_mdd_vf_X550
1400 * @hw: pointer to hardware structure
1403 * Restore VF that was disabled during malicious driver detection event
1405 void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
1407 u32 idx, reg, num_qs, start_q, bitmask;
1409 DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
1411 /* Map VF to queues */
1412 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1413 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1414 case IXGBE_MRQC_VMDQRT8TCEN:
1415 num_qs = 8; /* 16 VFs / pools */
1416 bitmask = 0x000000FF;
1418 case IXGBE_MRQC_VMDQRSS32EN:
1419 case IXGBE_MRQC_VMDQRT4TCEN:
1420 num_qs = 4; /* 32 VFs / pools */
1421 bitmask = 0x0000000F;
1423 default: /* 64 VFs / pools */
1425 bitmask = 0x00000003;
1428 start_q = vf * num_qs;
1430 /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
1433 reg |= (bitmask << (start_q % 32));
1434 IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
1435 IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
1439 * ixgbe_mdd_event_X550
1440 * @hw: pointer to hardware structure
1441 * @vf_bitmap: vf bitmap of malicious vfs
1443 * Handle malicious driver detection event.
1445 void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
1448 u32 i, j, reg, q, shift, vf, idx;
1450 DEBUGFUNC("ixgbe_mdd_event_X550");
1452 /* figure out pool size for mapping to vf's */
1453 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1454 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1455 case IXGBE_MRQC_VMDQRT8TCEN:
1456 shift = 3; /* 16 VFs / pools */
1458 case IXGBE_MRQC_VMDQRSS32EN:
1459 case IXGBE_MRQC_VMDQRT4TCEN:
1460 shift = 2; /* 32 VFs / pools */
1463 shift = 1; /* 64 VFs / pools */
1467 /* Read WQBR_TX and WQBR_RX and check for malicious queues */
1468 for (i = 0; i < 4; i++) {
1469 wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
1470 wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
1475 /* Get malicious queue */
1476 for (j = 0; j < 32 && wqbr; j++) {
1478 if (!(wqbr & (1 << j)))
1481 /* Get queue from bitmask */
1484 /* Map queue to vf */
1487 /* Set vf bit in vf_bitmap */
1489 vf_bitmap[idx] |= (1 << (vf % 32));
1496 * ixgbe_get_media_type_X550em - Get media type
1497 * @hw: pointer to hardware structure
1499 * Returns the media type (fiber, copper, backplane)
1501 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
1503 enum ixgbe_media_type media_type;
1505 DEBUGFUNC("ixgbe_get_media_type_X550em");
1507 /* Detect if there is a copper PHY attached. */
1508 switch (hw->device_id) {
1509 case IXGBE_DEV_ID_X550EM_X_KR:
1510 case IXGBE_DEV_ID_X550EM_X_KX4:
1511 case IXGBE_DEV_ID_X550EM_X_XFI:
1512 case IXGBE_DEV_ID_X550EM_A_KR:
1513 case IXGBE_DEV_ID_X550EM_A_KR_L:
1514 media_type = ixgbe_media_type_backplane;
1516 case IXGBE_DEV_ID_X550EM_X_SFP:
1517 case IXGBE_DEV_ID_X550EM_A_SFP:
1518 case IXGBE_DEV_ID_X550EM_A_SFP_N:
1519 case IXGBE_DEV_ID_X550EM_A_QSFP:
1520 case IXGBE_DEV_ID_X550EM_A_QSFP_N:
1521 media_type = ixgbe_media_type_fiber;
1523 case IXGBE_DEV_ID_X550EM_X_1G_T:
1524 case IXGBE_DEV_ID_X550EM_X_10G_T:
1525 case IXGBE_DEV_ID_X550EM_A_10G_T:
1526 media_type = ixgbe_media_type_copper;
1528 case IXGBE_DEV_ID_X550EM_A_SGMII:
1529 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
1530 media_type = ixgbe_media_type_backplane;
1531 hw->phy.type = ixgbe_phy_sgmii;
1533 case IXGBE_DEV_ID_X550EM_A_1G_T:
1534 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
1535 media_type = ixgbe_media_type_copper;
1538 media_type = ixgbe_media_type_unknown;
1545 * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1546 * @hw: pointer to hardware structure
1547 * @linear: TRUE if SFP module is linear
1549 static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1551 DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
1553 switch (hw->phy.sfp_type) {
1554 case ixgbe_sfp_type_not_present:
1555 return IXGBE_ERR_SFP_NOT_PRESENT;
1556 case ixgbe_sfp_type_da_cu_core0:
1557 case ixgbe_sfp_type_da_cu_core1:
1560 case ixgbe_sfp_type_srlr_core0:
1561 case ixgbe_sfp_type_srlr_core1:
1562 case ixgbe_sfp_type_da_act_lmt_core0:
1563 case ixgbe_sfp_type_da_act_lmt_core1:
1564 case ixgbe_sfp_type_1g_sx_core0:
1565 case ixgbe_sfp_type_1g_sx_core1:
1566 case ixgbe_sfp_type_1g_lx_core0:
1567 case ixgbe_sfp_type_1g_lx_core1:
1570 case ixgbe_sfp_type_unknown:
1571 case ixgbe_sfp_type_1g_cu_core0:
1572 case ixgbe_sfp_type_1g_cu_core1:
1574 return IXGBE_ERR_SFP_NOT_SUPPORTED;
1577 return IXGBE_SUCCESS;
1581 * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
1582 * @hw: pointer to hardware structure
1584 * Searches for and identifies the SFP module and assigns appropriate PHY type.
1586 s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
1591 DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
1593 status = ixgbe_identify_module_generic(hw);
1595 if (status != IXGBE_SUCCESS)
1598 /* Check if SFP module is supported */
1599 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1605 * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
1606 * @hw: pointer to hardware structure
1608 s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1613 DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
1615 /* Check if SFP module is supported */
1616 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1618 if (status != IXGBE_SUCCESS)
1621 ixgbe_init_mac_link_ops_X550em(hw);
1622 hw->phy.ops.reset = NULL;
1624 return IXGBE_SUCCESS;
1628 * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
1630 * @hw: pointer to hardware structure
1632 static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
1637 /* Restart auto-negotiation. */
1638 status = hw->mac.ops.read_iosf_sb_reg(hw,
1639 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1640 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
1643 DEBUGOUT("Auto-negotiation did not complete\n");
1647 link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1648 status = hw->mac.ops.write_iosf_sb_reg(hw,
1649 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1650 IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
1652 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1655 /* Indicate to FW that AN restart has been asserted */
1656 status = hw->mac.ops.read_iosf_sb_reg(hw,
1657 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1658 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
1661 DEBUGOUT("Auto-negotiation did not complete\n");
1665 flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
1666 status = hw->mac.ops.write_iosf_sb_reg(hw,
1667 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1668 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
1675 * ixgbe_setup_sgmii - Set up link for sgmii
1676 * @hw: pointer to hardware structure
1677 * @speed: new link speed
1678 * @autoneg_wait: TRUE when waiting for completion is needed
1680 static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1683 struct ixgbe_mac_info *mac = &hw->mac;
1684 u32 lval, sval, flx_val;
1687 rc = mac->ops.read_iosf_sb_reg(hw,
1688 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1689 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1693 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1694 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1695 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1696 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1697 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1698 rc = mac->ops.write_iosf_sb_reg(hw,
1699 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1700 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1704 rc = mac->ops.read_iosf_sb_reg(hw,
1705 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1706 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1710 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1711 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1712 rc = mac->ops.write_iosf_sb_reg(hw,
1713 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1714 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1718 rc = mac->ops.read_iosf_sb_reg(hw,
1719 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1720 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1724 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1725 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1726 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1727 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1728 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1730 rc = mac->ops.write_iosf_sb_reg(hw,
1731 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1732 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1736 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1740 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1744 * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation
1745 * @hw: pointer to hardware structure
1746 * @speed: new link speed
1747 * @autoneg_wait: TRUE when waiting for completion is needed
1749 static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1752 struct ixgbe_mac_info *mac = &hw->mac;
1753 u32 lval, sval, flx_val;
1756 rc = mac->ops.read_iosf_sb_reg(hw,
1757 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1758 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1762 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1763 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1764 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1765 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1766 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1767 rc = mac->ops.write_iosf_sb_reg(hw,
1768 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1769 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1773 rc = mac->ops.read_iosf_sb_reg(hw,
1774 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1775 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1779 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1780 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1781 rc = mac->ops.write_iosf_sb_reg(hw,
1782 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1783 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1787 rc = mac->ops.write_iosf_sb_reg(hw,
1788 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1789 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1793 rc = mac->ops.read_iosf_sb_reg(hw,
1794 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1795 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1799 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1800 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
1801 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1802 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1803 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1805 rc = mac->ops.write_iosf_sb_reg(hw,
1806 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1807 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1811 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1813 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1817 * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1818 * @hw: pointer to hardware structure
1820 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1822 struct ixgbe_mac_info *mac = &hw->mac;
1824 DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
1826 switch (hw->mac.ops.get_media_type(hw)) {
1827 case ixgbe_media_type_fiber:
1828 /* CS4227 does not support autoneg, so disable the laser control
1829 * functions for SFP+ fiber
1831 mac->ops.disable_tx_laser = NULL;
1832 mac->ops.enable_tx_laser = NULL;
1833 mac->ops.flap_tx_laser = NULL;
1834 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
1835 mac->ops.set_rate_select_speed =
1836 ixgbe_set_soft_rate_select_speed;
1838 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
1839 (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
1840 mac->ops.setup_mac_link =
1841 ixgbe_setup_mac_link_sfp_x550a;
1843 mac->ops.setup_mac_link =
1844 ixgbe_setup_mac_link_sfp_x550em;
1846 case ixgbe_media_type_copper:
1847 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T)
1849 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1850 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
1851 hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
1852 mac->ops.setup_link = ixgbe_setup_sgmii_fw;
1853 mac->ops.check_link =
1854 ixgbe_check_mac_link_generic;
1856 mac->ops.setup_link =
1857 ixgbe_setup_mac_link_t_X550em;
1860 mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
1861 mac->ops.check_link = ixgbe_check_link_t_X550em;
1864 case ixgbe_media_type_backplane:
1865 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
1866 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
1867 mac->ops.setup_link = ixgbe_setup_sgmii;
1875 * ixgbe_get_link_capabilities_x550em - Determines link capabilities
1876 * @hw: pointer to hardware structure
1877 * @speed: pointer to link speed
1878 * @autoneg: TRUE when autoneg or autotry is enabled
1880 s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
1881 ixgbe_link_speed *speed,
1884 DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
1887 if (hw->phy.type == ixgbe_phy_fw) {
1889 *speed = hw->phy.speeds_supported;
1894 if (hw->phy.media_type == ixgbe_media_type_fiber) {
1896 /* CS4227 SFP must not enable auto-negotiation */
1899 /* Check if 1G SFP module. */
1900 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1901 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
1902 || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1903 hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
1904 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1905 return IXGBE_SUCCESS;
1908 /* Link capabilities are based on SFP */
1909 if (hw->phy.multispeed_fiber)
1910 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1911 IXGBE_LINK_SPEED_1GB_FULL;
1913 *speed = IXGBE_LINK_SPEED_10GB_FULL;
1917 switch (hw->phy.type) {
1918 case ixgbe_phy_x550em_xfi:
1919 *speed = IXGBE_LINK_SPEED_1GB_FULL |
1920 IXGBE_LINK_SPEED_10GB_FULL;
1923 case ixgbe_phy_ext_1g_t:
1924 case ixgbe_phy_sgmii:
1925 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1927 case ixgbe_phy_x550em_kr:
1928 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1929 /* check different backplane modes */
1930 if (hw->phy.nw_mng_if_sel &
1931 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
1932 *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
1934 } else if (hw->device_id ==
1935 IXGBE_DEV_ID_X550EM_A_KR_L) {
1936 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1942 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1943 IXGBE_LINK_SPEED_1GB_FULL;
1948 return IXGBE_SUCCESS;
1952 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
1953 * @hw: pointer to hardware structure
1954 * @lsc: pointer to boolean flag which indicates whether external Base T
1955 * PHY interrupt is lsc
1957 * Determime if external Base T PHY interrupt cause is high temperature
1958 * failure alarm or link status change.
1960 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1961 * failure alarm, else return PHY access status.
1963 static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
1970 /* Vendor alarm triggered */
1971 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1972 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1975 if (status != IXGBE_SUCCESS ||
1976 !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
1979 /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
1980 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
1981 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1984 if (status != IXGBE_SUCCESS ||
1985 !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1986 IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
1989 /* Global alarm triggered */
1990 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
1991 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1994 if (status != IXGBE_SUCCESS)
1997 /* If high temperature failure, then return over temp error and exit */
1998 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
1999 /* power down the PHY in case the PHY FW didn't already */
2000 ixgbe_set_copper_phy_power(hw, FALSE);
2001 return IXGBE_ERR_OVERTEMP;
2002 } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
2003 /* device fault alarm triggered */
2004 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
2005 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2008 if (status != IXGBE_SUCCESS)
2011 /* if device fault was due to high temp alarm handle and exit */
2012 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
2013 /* power down the PHY in case the PHY FW didn't */
2014 ixgbe_set_copper_phy_power(hw, FALSE);
2015 return IXGBE_ERR_OVERTEMP;
2019 /* Vendor alarm 2 triggered */
2020 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2021 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2023 if (status != IXGBE_SUCCESS ||
2024 !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
2027 /* link connect/disconnect event occurred */
2028 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
2029 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2031 if (status != IXGBE_SUCCESS)
2035 if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
2038 return IXGBE_SUCCESS;
2042 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
2043 * @hw: pointer to hardware structure
2045 * Enable link status change and temperature failure alarm for the external
2048 * Returns PHY access status
2050 static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
2056 /* Clear interrupt flags */
2057 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
2059 /* Enable link status change alarm */
2061 /* Enable the LASI interrupts on X552 devices to receive notifications
2062 * of the link configurations of the external PHY and correspondingly
2063 * support the configuration of the internal iXFI link, since iXFI does
2064 * not support auto-negotiation. This is not required for X553 devices
2065 * having KR support, which performs auto-negotiations and which is used
2066 * as the internal link to the external PHY. Hence adding a check here
2067 * to avoid enabling LASI interrupts for X553 devices.
2069 if (hw->mac.type != ixgbe_mac_X550EM_a) {
2070 status = hw->phy.ops.read_reg(hw,
2071 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2072 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2074 if (status != IXGBE_SUCCESS)
2077 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
2079 status = hw->phy.ops.write_reg(hw,
2080 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2081 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
2083 if (status != IXGBE_SUCCESS)
2087 /* Enable high temperature failure and global fault alarms */
2088 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2089 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2092 if (status != IXGBE_SUCCESS)
2095 reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
2096 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
2098 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2099 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2102 if (status != IXGBE_SUCCESS)
2105 /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
2106 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2107 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2110 if (status != IXGBE_SUCCESS)
2113 reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2114 IXGBE_MDIO_GLOBAL_ALARM_1_INT);
2116 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2117 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2120 if (status != IXGBE_SUCCESS)
2123 /* Enable chip-wide vendor alarm */
2124 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2125 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2128 if (status != IXGBE_SUCCESS)
2131 reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
2133 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2134 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2141 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
2142 * @hw: pointer to hardware structure
2143 * @speed: link speed
2145 * Configures the integrated KR PHY.
2147 static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
2148 ixgbe_link_speed speed)
2153 status = hw->mac.ops.read_iosf_sb_reg(hw,
2154 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2155 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2159 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2160 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
2161 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
2163 /* Advertise 10G support. */
2164 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
2165 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
2167 /* Advertise 1G support. */
2168 if (speed & IXGBE_LINK_SPEED_1GB_FULL)
2169 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
2171 status = hw->mac.ops.write_iosf_sb_reg(hw,
2172 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2173 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2175 if (hw->mac.type == ixgbe_mac_X550EM_a) {
2176 /* Set lane mode to KR auto negotiation */
2177 status = hw->mac.ops.read_iosf_sb_reg(hw,
2178 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2179 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2184 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2185 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2186 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2187 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2188 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2190 status = hw->mac.ops.write_iosf_sb_reg(hw,
2191 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2192 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2195 return ixgbe_restart_an_internal_phy_x550em(hw);
2199 * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
2200 * @hw: pointer to hardware structure
2202 static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
2204 u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2207 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
2208 return IXGBE_SUCCESS;
2210 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
2213 memset(store, 0, sizeof(store));
2215 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
2219 return ixgbe_setup_fw_link(hw);
2223 * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
2224 * @hw: pointer to hardware structure
2226 static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
2228 u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2231 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
2235 if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
2236 ixgbe_shutdown_fw_phy(hw);
2237 return IXGBE_ERR_OVERTEMP;
2239 return IXGBE_SUCCESS;
2243 * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
2244 * @hw: pointer to hardware structure
2246 * Read NW_MNG_IF_SEL register and save field values, and check for valid field
2249 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
2251 /* Save NW management interface connected on board. This is used
2252 * to determine internal PHY mode.
2254 hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
2256 /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
2257 * PHY address. This register field was has only been used for X552.
2259 if (hw->mac.type == ixgbe_mac_X550EM_a &&
2260 hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
2261 hw->phy.addr = (hw->phy.nw_mng_if_sel &
2262 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
2263 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
2266 return IXGBE_SUCCESS;
2270 * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
2271 * @hw: pointer to hardware structure
2273 * Initialize any function pointers that were not able to be
2274 * set during init_shared_code because the PHY/SFP type was
2275 * not known. Perform the SFP init if necessary.
2277 s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
2279 struct ixgbe_phy_info *phy = &hw->phy;
2282 DEBUGFUNC("ixgbe_init_phy_ops_X550em");
2284 hw->mac.ops.set_lan_id(hw);
2285 ixgbe_read_mng_if_sel_x550em(hw);
2287 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
2288 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2289 ixgbe_setup_mux_ctl(hw);
2290 phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
2293 switch (hw->device_id) {
2294 case IXGBE_DEV_ID_X550EM_A_1G_T:
2295 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2296 phy->ops.read_reg_mdi = NULL;
2297 phy->ops.write_reg_mdi = NULL;
2298 hw->phy.ops.read_reg = NULL;
2299 hw->phy.ops.write_reg = NULL;
2300 phy->ops.check_overtemp = ixgbe_check_overtemp_fw;
2302 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2304 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2307 case IXGBE_DEV_ID_X550EM_A_10G_T:
2308 case IXGBE_DEV_ID_X550EM_A_SFP:
2309 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
2310 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
2312 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2314 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2316 case IXGBE_DEV_ID_X550EM_X_SFP:
2317 /* set up for CS4227 usage */
2318 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2320 case IXGBE_DEV_ID_X550EM_X_1G_T:
2321 phy->ops.read_reg_mdi = NULL;
2322 phy->ops.write_reg_mdi = NULL;
2327 /* Identify the PHY or SFP module */
2328 ret_val = phy->ops.identify(hw);
2329 if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2330 ret_val == IXGBE_ERR_PHY_ADDR_INVALID)
2333 /* Setup function pointers based on detected hardware */
2334 ixgbe_init_mac_link_ops_X550em(hw);
2335 if (phy->sfp_type != ixgbe_sfp_type_unknown)
2336 phy->ops.reset = NULL;
2338 /* Set functions pointers based on phy type */
2339 switch (hw->phy.type) {
2340 case ixgbe_phy_x550em_kx4:
2341 phy->ops.setup_link = NULL;
2342 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2343 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2345 case ixgbe_phy_x550em_kr:
2346 phy->ops.setup_link = ixgbe_setup_kr_x550em;
2347 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2348 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2350 case ixgbe_phy_ext_1g_t:
2351 /* link is managed by FW */
2352 phy->ops.setup_link = NULL;
2353 phy->ops.reset = NULL;
2355 case ixgbe_phy_x550em_xfi:
2356 /* link is managed by HW */
2357 phy->ops.setup_link = NULL;
2358 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2359 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2361 case ixgbe_phy_x550em_ext_t:
2362 /* If internal link mode is XFI, then setup iXFI internal link,
2363 * else setup KR now.
2365 phy->ops.setup_internal_link =
2366 ixgbe_setup_internal_phy_t_x550em;
2368 /* setup SW LPLU only for first revision of X550EM_x */
2369 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
2370 !(IXGBE_FUSES0_REV_MASK &
2371 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
2372 phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2374 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
2375 phy->ops.reset = ixgbe_reset_phy_t_X550em;
2377 case ixgbe_phy_sgmii:
2378 phy->ops.setup_link = NULL;
2381 phy->ops.setup_link = ixgbe_setup_fw_link;
2382 phy->ops.reset = ixgbe_reset_phy_fw;
2391 * ixgbe_set_mdio_speed - Set MDIO clock speed
2392 * @hw: pointer to hardware structure
2394 static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
2398 switch (hw->device_id) {
2399 case IXGBE_DEV_ID_X550EM_X_10G_T:
2400 case IXGBE_DEV_ID_X550EM_A_SGMII:
2401 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
2402 case IXGBE_DEV_ID_X550EM_A_10G_T:
2403 case IXGBE_DEV_ID_X550EM_A_SFP:
2404 case IXGBE_DEV_ID_X550EM_A_QSFP:
2405 /* Config MDIO clock speed before the first MDIO PHY access */
2406 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2407 hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2408 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2410 case IXGBE_DEV_ID_X550EM_A_1G_T:
2411 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2412 /* Select fast MDIO clock speed for these devices */
2413 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2414 hlreg0 |= IXGBE_HLREG0_MDCSPD;
2415 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2423 * ixgbe_reset_hw_X550em - Perform hardware reset
2424 * @hw: pointer to hardware structure
2426 * Resets the hardware by resetting the transmit and receive units, masks
2427 * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2430 s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
2432 ixgbe_link_speed link_speed;
2436 bool link_up = FALSE;
2437 u32 swfw_mask = hw->phy.phy_semaphore_mask;
2439 DEBUGFUNC("ixgbe_reset_hw_X550em");
2441 /* Call adapter stop to disable Tx/Rx and clear interrupts */
2442 status = hw->mac.ops.stop_adapter(hw);
2443 if (status != IXGBE_SUCCESS) {
2444 DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status);
2447 /* flush pending Tx transactions */
2448 ixgbe_clear_tx_pending(hw);
2450 ixgbe_set_mdio_speed(hw);
2452 /* PHY ops must be identified and initialized prior to reset */
2453 status = hw->phy.ops.init(hw);
2456 DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
2459 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2460 status == IXGBE_ERR_PHY_ADDR_INVALID) {
2461 DEBUGOUT("Returning from reset HW due to PHY init failure\n");
2465 /* start the external PHY */
2466 if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2467 status = ixgbe_init_ext_t_x550em(hw);
2469 DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n",
2475 /* Setup SFP module if there is one present. */
2476 if (hw->phy.sfp_setup_needed) {
2477 status = hw->mac.ops.setup_sfp(hw);
2478 hw->phy.sfp_setup_needed = FALSE;
2481 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
2485 if (!hw->phy.reset_disable && hw->phy.ops.reset) {
2486 if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP)
2487 return IXGBE_ERR_OVERTEMP;
2491 /* Issue global reset to the MAC. Needs to be SW reset if link is up.
2492 * If link reset is used when link is up, it might reset the PHY when
2493 * mng is using it. If link is down or the flag to force full link
2494 * reset is set, then perform link reset.
2496 ctrl = IXGBE_CTRL_LNK_RST;
2497 if (!hw->force_full_reset) {
2498 hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
2500 ctrl = IXGBE_CTRL_RST;
2503 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
2504 if (status != IXGBE_SUCCESS) {
2505 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2506 "semaphore failed with %d", status);
2507 return IXGBE_ERR_SWFW_SYNC;
2509 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2510 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2511 IXGBE_WRITE_FLUSH(hw);
2512 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2514 /* Poll for reset bit to self-clear meaning reset is complete */
2515 for (i = 0; i < 10; i++) {
2517 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2518 if (!(ctrl & IXGBE_CTRL_RST_MASK))
2522 if (ctrl & IXGBE_CTRL_RST_MASK) {
2523 status = IXGBE_ERR_RESET_FAILED;
2524 DEBUGOUT("Reset polling failed to complete.\n");
2529 /* Double resets are required for recovery from certain error
2530 * conditions. Between resets, it is necessary to stall to
2531 * allow time for any pending HW events to complete.
2533 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2534 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2538 /* Store the permanent mac address */
2539 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2541 /* Store MAC address from RAR0, clear receive address registers, and
2542 * clear the multicast table. Also reset num_rar_entries to 128,
2543 * since we modify this value when programming the SAN MAC address.
2545 hw->mac.num_rar_entries = 128;
2546 hw->mac.ops.init_rx_addrs(hw);
2548 ixgbe_set_mdio_speed(hw);
2550 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2551 ixgbe_setup_mux_ctl(hw);
2553 if (status != IXGBE_SUCCESS)
2554 DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
2560 * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2561 * @hw: pointer to hardware structure
2563 s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
2568 status = hw->phy.ops.read_reg(hw,
2569 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
2570 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2573 if (status != IXGBE_SUCCESS)
2576 /* If PHY FW reset completed bit is set then this is the first
2577 * SW instance after a power on so the PHY FW must be un-stalled.
2579 if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2580 status = hw->phy.ops.read_reg(hw,
2581 IXGBE_MDIO_GLOBAL_RES_PR_10,
2582 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2585 if (status != IXGBE_SUCCESS)
2588 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
2590 status = hw->phy.ops.write_reg(hw,
2591 IXGBE_MDIO_GLOBAL_RES_PR_10,
2592 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2595 if (status != IXGBE_SUCCESS)
2603 * ixgbe_setup_kr_x550em - Configure the KR PHY.
2604 * @hw: pointer to hardware structure
2606 s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
2608 /* leave link alone for 2.5G */
2609 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
2610 return IXGBE_SUCCESS;
2612 if (ixgbe_check_reset_blocked(hw))
2615 return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
2619 * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
2620 * @hw: pointer to hardware structure
2621 * @speed: new link speed
2622 * @autoneg_wait_to_complete: unused
2624 * Configure the external PHY and the integrated KR PHY for SFP support.
2626 s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
2627 ixgbe_link_speed speed,
2628 bool autoneg_wait_to_complete)
2631 u16 reg_slice, reg_val;
2632 bool setup_linear = FALSE;
2633 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
2635 /* Check if SFP module is supported and linear */
2636 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2638 /* If no SFP module present, then return success. Return success since
2639 * there is no reason to configure CS4227 and SFP not present error is
2640 * not excepted in the setup MAC link flow.
2642 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2643 return IXGBE_SUCCESS;
2645 if (ret_val != IXGBE_SUCCESS)
2648 /* Configure internal PHY for KR/KX. */
2649 ixgbe_setup_kr_speed_x550em(hw, speed);
2651 /* Configure CS4227 LINE side to proper mode. */
2652 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
2653 (hw->bus.lan_id << 12);
2655 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2657 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2658 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2664 * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
2665 * @hw: pointer to hardware structure
2666 * @speed: the link speed to force
2668 * Configures the integrated PHY for native SFI mode. Used to connect the
2669 * internal PHY directly to an SFP cage, without autonegotiation.
2671 static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2673 struct ixgbe_mac_info *mac = &hw->mac;
2677 /* Disable all AN and force speed to 10G Serial. */
2678 status = mac->ops.read_iosf_sb_reg(hw,
2679 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2680 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2681 if (status != IXGBE_SUCCESS)
2684 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2685 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2686 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2687 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2689 /* Select forced link speed for internal PHY. */
2691 case IXGBE_LINK_SPEED_10GB_FULL:
2692 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
2694 case IXGBE_LINK_SPEED_1GB_FULL:
2695 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
2698 /* Other link speeds are not supported by internal PHY. */
2699 return IXGBE_ERR_LINK_SETUP;
2702 status = mac->ops.write_iosf_sb_reg(hw,
2703 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2704 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2706 /* Toggle port SW reset by AN reset. */
2707 status = ixgbe_restart_an_internal_phy_x550em(hw);
2713 * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
2714 * @hw: pointer to hardware structure
2715 * @speed: new link speed
2716 * @autoneg_wait_to_complete: unused
2718 * Configure the the integrated PHY for SFP support.
2720 s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
2721 ixgbe_link_speed speed,
2722 bool autoneg_wait_to_complete)
2726 bool setup_linear = FALSE;
2727 u32 reg_slice, reg_phy_int, slice_offset;
2729 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
2731 /* Check if SFP module is supported and linear */
2732 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2734 /* If no SFP module present, then return success. Return success since
2735 * SFP not present error is not excepted in the setup MAC link flow.
2737 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2738 return IXGBE_SUCCESS;
2740 if (ret_val != IXGBE_SUCCESS)
2743 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
2744 /* Configure internal PHY for native SFI based on module type */
2745 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
2746 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2747 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int);
2749 if (ret_val != IXGBE_SUCCESS)
2752 reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
2754 reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
2756 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
2757 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2758 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
2760 if (ret_val != IXGBE_SUCCESS)
2763 /* Setup SFI internal link. */
2764 ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
2766 /* Configure internal PHY for KR/KX. */
2767 ixgbe_setup_kr_speed_x550em(hw, speed);
2769 if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
2771 DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
2772 return IXGBE_ERR_PHY_ADDR_INVALID;
2775 /* Get external PHY SKU id */
2776 ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
2777 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
2779 if (ret_val != IXGBE_SUCCESS)
2782 /* When configuring quad port CS4223, the MAC instance is part
2783 * of the slice offset.
2785 if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
2786 slice_offset = (hw->bus.lan_id +
2787 (hw->bus.instance_id << 1)) << 12;
2789 slice_offset = hw->bus.lan_id << 12;
2791 /* Configure CS4227/CS4223 LINE side to proper mode. */
2792 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
2794 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2795 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
2797 if (ret_val != IXGBE_SUCCESS)
2800 reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
2801 (IXGBE_CS4227_EDC_MODE_SR << 1));
2804 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2806 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2807 ret_val = hw->phy.ops.write_reg(hw, reg_slice,
2808 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
2810 /* Flush previous write with a read */
2811 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2812 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
2818 * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
2819 * @hw: pointer to hardware structure
2821 * iXfI configuration needed for ixgbe_mac_X550EM_x devices.
2823 static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
2825 struct ixgbe_mac_info *mac = &hw->mac;
2829 /* Disable training protocol FSM. */
2830 status = mac->ops.read_iosf_sb_reg(hw,
2831 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2832 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2833 if (status != IXGBE_SUCCESS)
2835 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
2836 status = mac->ops.write_iosf_sb_reg(hw,
2837 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2838 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2839 if (status != IXGBE_SUCCESS)
2842 /* Disable Flex from training TXFFE. */
2843 status = mac->ops.read_iosf_sb_reg(hw,
2844 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2845 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2846 if (status != IXGBE_SUCCESS)
2848 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2849 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2850 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2851 status = mac->ops.write_iosf_sb_reg(hw,
2852 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2853 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2854 if (status != IXGBE_SUCCESS)
2856 status = mac->ops.read_iosf_sb_reg(hw,
2857 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2858 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2859 if (status != IXGBE_SUCCESS)
2861 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2862 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2863 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2864 status = mac->ops.write_iosf_sb_reg(hw,
2865 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2866 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2867 if (status != IXGBE_SUCCESS)
2870 /* Enable override for coefficients. */
2871 status = mac->ops.read_iosf_sb_reg(hw,
2872 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2873 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2874 if (status != IXGBE_SUCCESS)
2876 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
2877 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
2878 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
2879 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
2880 status = mac->ops.write_iosf_sb_reg(hw,
2881 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2882 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2887 * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
2888 * @hw: pointer to hardware structure
2889 * @speed: the link speed to force
2891 * Configures the integrated KR PHY to use iXFI mode. Used to connect an
2892 * internal and external PHY at a specific speed, without autonegotiation.
2894 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2896 struct ixgbe_mac_info *mac = &hw->mac;
2900 /* iXFI is only supported with X552 */
2901 if (mac->type != ixgbe_mac_X550EM_x)
2902 return IXGBE_ERR_LINK_SETUP;
2904 /* Disable AN and force speed to 10G Serial. */
2905 status = mac->ops.read_iosf_sb_reg(hw,
2906 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2907 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2908 if (status != IXGBE_SUCCESS)
2911 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2912 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
2914 /* Select forced link speed for internal PHY. */
2916 case IXGBE_LINK_SPEED_10GB_FULL:
2917 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
2919 case IXGBE_LINK_SPEED_1GB_FULL:
2920 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
2923 /* Other link speeds are not supported by internal KR PHY. */
2924 return IXGBE_ERR_LINK_SETUP;
2927 status = mac->ops.write_iosf_sb_reg(hw,
2928 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2929 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2930 if (status != IXGBE_SUCCESS)
2933 /* Additional configuration needed for x550em_x */
2934 if (hw->mac.type == ixgbe_mac_X550EM_x) {
2935 status = ixgbe_setup_ixfi_x550em_x(hw);
2936 if (status != IXGBE_SUCCESS)
2940 /* Toggle port SW reset by AN reset. */
2941 status = ixgbe_restart_an_internal_phy_x550em(hw);
2947 * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
2948 * @hw: address of hardware structure
2949 * @link_up: address of boolean to indicate link status
2951 * Returns error code if unable to get link status.
2953 static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
2960 /* read this twice back to back to indicate current status */
2961 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2962 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2964 if (ret != IXGBE_SUCCESS)
2967 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2968 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2970 if (ret != IXGBE_SUCCESS)
2973 *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
2975 return IXGBE_SUCCESS;
2979 * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
2980 * @hw: point to hardware structure
2982 * Configures the link between the integrated KR PHY and the external X557 PHY
2983 * The driver will call this function when it gets a link status change
2984 * interrupt from the X557 PHY. This function configures the link speed
2985 * between the PHYs to match the link speed of the BASE-T link.
2987 * A return of a non-zero value indicates an error, and the base driver should
2988 * not report link up.
2990 s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
2992 ixgbe_link_speed force_speed;
2997 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
2998 return IXGBE_ERR_CONFIG;
3000 if (hw->mac.type == ixgbe_mac_X550EM_x &&
3001 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
3002 /* If link is down, there is no setup necessary so return */
3003 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3004 if (status != IXGBE_SUCCESS)
3008 return IXGBE_SUCCESS;
3010 status = hw->phy.ops.read_reg(hw,
3011 IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
3012 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3014 if (status != IXGBE_SUCCESS)
3017 /* If link is still down - no setup is required so return */
3018 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3019 if (status != IXGBE_SUCCESS)
3022 return IXGBE_SUCCESS;
3024 /* clear everything but the speed and duplex bits */
3025 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
3028 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
3029 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
3031 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
3032 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
3035 /* Internal PHY does not support anything else */
3036 return IXGBE_ERR_INVALID_LINK_SETTINGS;
3039 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
3041 speed = IXGBE_LINK_SPEED_10GB_FULL |
3042 IXGBE_LINK_SPEED_1GB_FULL;
3043 return ixgbe_setup_kr_speed_x550em(hw, speed);
3048 * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
3049 * @hw: pointer to hardware structure
3051 * Configures the integrated KR PHY to use internal loopback mode.
3053 s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
3058 /* Disable AN and force speed to 10G Serial. */
3059 status = hw->mac.ops.read_iosf_sb_reg(hw,
3060 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3061 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3062 if (status != IXGBE_SUCCESS)
3064 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
3065 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
3066 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
3067 status = hw->mac.ops.write_iosf_sb_reg(hw,
3068 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3069 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3070 if (status != IXGBE_SUCCESS)
3073 /* Set near-end loopback clocks. */
3074 status = hw->mac.ops.read_iosf_sb_reg(hw,
3075 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3076 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3077 if (status != IXGBE_SUCCESS)
3079 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
3080 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
3081 status = hw->mac.ops.write_iosf_sb_reg(hw,
3082 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3083 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3084 if (status != IXGBE_SUCCESS)
3087 /* Set loopback enable. */
3088 status = hw->mac.ops.read_iosf_sb_reg(hw,
3089 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3090 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3091 if (status != IXGBE_SUCCESS)
3093 reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
3094 status = hw->mac.ops.write_iosf_sb_reg(hw,
3095 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3096 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3097 if (status != IXGBE_SUCCESS)
3100 /* Training bypass. */
3101 status = hw->mac.ops.read_iosf_sb_reg(hw,
3102 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3103 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3104 if (status != IXGBE_SUCCESS)
3106 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
3107 status = hw->mac.ops.write_iosf_sb_reg(hw,
3108 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3109 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3115 * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
3116 * assuming that the semaphore is already obtained.
3117 * @hw: pointer to hardware structure
3118 * @offset: offset of word in the EEPROM to read
3119 * @data: word read from the EEPROM
3121 * Reads a 16 bit word from the EEPROM using the hostif.
3123 s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
3125 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3126 struct ixgbe_hic_read_shadow_ram buffer;
3129 DEBUGFUNC("ixgbe_read_ee_hostif_X550");
3130 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3131 buffer.hdr.req.buf_lenh = 0;
3132 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3133 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3135 /* convert offset from words to bytes */
3136 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3138 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3143 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3147 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3148 IXGBE_HI_COMMAND_TIMEOUT);
3150 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
3151 FW_NVM_DATA_OFFSET);
3154 hw->mac.ops.release_swfw_sync(hw, mask);
3159 * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
3160 * @hw: pointer to hardware structure
3161 * @offset: offset of word in the EEPROM to read
3162 * @words: number of words
3163 * @data: word(s) read from the EEPROM
3165 * Reads a 16 bit word(s) from the EEPROM using the hostif.
3167 s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3168 u16 offset, u16 words, u16 *data)
3170 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3171 struct ixgbe_hic_read_shadow_ram buffer;
3172 u32 current_word = 0;
3177 DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
3179 /* Take semaphore for the entire operation. */
3180 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3182 DEBUGOUT("EEPROM read buffer - semaphore failed\n");
3187 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
3188 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
3190 words_to_read = words;
3192 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3193 buffer.hdr.req.buf_lenh = 0;
3194 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3195 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3197 /* convert offset from words to bytes */
3198 buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
3199 buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
3204 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3205 IXGBE_HI_COMMAND_TIMEOUT);
3208 DEBUGOUT("Host interface command failed\n");
3212 for (i = 0; i < words_to_read; i++) {
3213 u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
3215 u32 value = IXGBE_READ_REG(hw, reg);
3217 data[current_word] = (u16)(value & 0xffff);
3220 if (i < words_to_read) {
3222 data[current_word] = (u16)(value & 0xffff);
3226 words -= words_to_read;
3230 hw->mac.ops.release_swfw_sync(hw, mask);
3235 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3236 * @hw: pointer to hardware structure
3237 * @offset: offset of word in the EEPROM to write
3238 * @data: word write to the EEPROM
3240 * Write a 16 bit word to the EEPROM using the hostif.
3242 s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
3246 struct ixgbe_hic_write_shadow_ram buffer;
3248 DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
3250 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
3251 buffer.hdr.req.buf_lenh = 0;
3252 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
3253 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3256 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3258 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3260 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3262 IXGBE_HI_COMMAND_TIMEOUT, TRUE);
3263 if (status != IXGBE_SUCCESS) {
3264 DEBUGOUT2("for offset %04x failed with status %d\n",
3269 if (buffer.hdr.rsp.buf_lenh_status != FW_CEM_RESP_STATUS_SUCCESS) {
3270 DEBUGOUT2("for offset %04x host interface return status %02x\n",
3271 offset, buffer.hdr.rsp.buf_lenh_status);
3272 return IXGBE_ERR_HOST_INTERFACE_COMMAND;
3279 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3280 * @hw: pointer to hardware structure
3281 * @offset: offset of word in the EEPROM to write
3282 * @data: word write to the EEPROM
3284 * Write a 16 bit word to the EEPROM using the hostif.
3286 s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
3289 s32 status = IXGBE_SUCCESS;
3291 DEBUGFUNC("ixgbe_write_ee_hostif_X550");
3293 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
3295 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
3296 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3298 DEBUGOUT("write ee hostif failed to get semaphore");
3299 status = IXGBE_ERR_SWFW_SYNC;
3306 * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
3307 * @hw: pointer to hardware structure
3308 * @offset: offset of word in the EEPROM to write
3309 * @words: number of words
3310 * @data: word(s) write to the EEPROM
3312 * Write a 16 bit word(s) to the EEPROM using the hostif.
3314 s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3315 u16 offset, u16 words, u16 *data)
3317 s32 status = IXGBE_SUCCESS;
3320 DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
3322 /* Take semaphore for the entire operation. */
3323 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3324 if (status != IXGBE_SUCCESS) {
3325 DEBUGOUT("EEPROM write buffer - semaphore failed\n");
3329 for (i = 0; i < words; i++) {
3330 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
3333 if (status != IXGBE_SUCCESS) {
3334 DEBUGOUT("Eeprom buffered write failed\n");
3339 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3346 * ixgbe_checksum_ptr_x550 - Checksum one pointer region
3347 * @hw: pointer to hardware structure
3348 * @ptr: pointer offset in eeprom
3349 * @size: size of section pointed by ptr, if 0 first word will be used as size
3350 * @csum: address of checksum to update
3351 * @buffer: pointer to buffer containing calculated checksum
3352 * @buffer_size: size of buffer
3354 * Returns error status for any failure
3356 static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
3357 u16 size, u16 *csum, u16 *buffer,
3362 u16 length, bufsz, i, start;
3365 bufsz = sizeof(buf) / sizeof(buf[0]);
3367 /* Read a chunk at the pointer location */
3369 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
3371 DEBUGOUT("Failed to read EEPROM image\n");
3376 if (buffer_size < ptr)
3377 return IXGBE_ERR_PARAM;
3378 local_buffer = &buffer[ptr];
3386 length = local_buffer[0];
3388 /* Skip pointer section if length is invalid. */
3389 if (length == 0xFFFF || length == 0 ||
3390 (ptr + length) >= hw->eeprom.word_size)
3391 return IXGBE_SUCCESS;
3394 if (buffer && ((u32)start + (u32)length > buffer_size))
3395 return IXGBE_ERR_PARAM;
3397 for (i = start; length; i++, length--) {
3398 if (i == bufsz && !buffer) {
3404 /* Read a chunk at the pointer location */
3405 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
3408 DEBUGOUT("Failed to read EEPROM image\n");
3412 *csum += local_buffer[i];
3414 return IXGBE_SUCCESS;
3418 * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
3419 * @hw: pointer to hardware structure
3420 * @buffer: pointer to buffer containing calculated checksum
3421 * @buffer_size: size of buffer
3423 * Returns a negative error code on error, or the 16-bit checksum
3425 s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
3427 u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
3431 u16 pointer, i, size;
3433 DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
3435 hw->eeprom.ops.init_params(hw);
3438 /* Read pointer area */
3439 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
3440 IXGBE_EEPROM_LAST_WORD + 1,
3443 DEBUGOUT("Failed to read EEPROM image\n");
3446 local_buffer = eeprom_ptrs;
3448 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
3449 return IXGBE_ERR_PARAM;
3450 local_buffer = buffer;
3454 * For X550 hardware include 0x0-0x41 in the checksum, skip the
3455 * checksum word itself
3457 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
3458 if (i != IXGBE_EEPROM_CHECKSUM)
3459 checksum += local_buffer[i];
3462 * Include all data from pointers 0x3, 0x6-0xE. This excludes the
3463 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
3465 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
3466 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
3469 pointer = local_buffer[i];
3471 /* Skip pointer section if the pointer is invalid. */
3472 if (pointer == 0xFFFF || pointer == 0 ||
3473 pointer >= hw->eeprom.word_size)
3477 case IXGBE_PCIE_GENERAL_PTR:
3478 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
3480 case IXGBE_PCIE_CONFIG0_PTR:
3481 case IXGBE_PCIE_CONFIG1_PTR:
3482 size = IXGBE_PCIE_CONFIG_SIZE;
3489 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
3490 buffer, buffer_size);
3495 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
3497 return (s32)checksum;
3501 * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
3502 * @hw: pointer to hardware structure
3504 * Returns a negative error code on error, or the 16-bit checksum
3506 s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
3508 return ixgbe_calc_checksum_X550(hw, NULL, 0);
3512 * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
3513 * @hw: pointer to hardware structure
3514 * @checksum_val: calculated checksum
3516 * Performs checksum calculation and validates the EEPROM checksum. If the
3517 * caller does not need checksum_val, the value can be NULL.
3519 s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
3523 u16 read_checksum = 0;
3525 DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
3527 /* Read the first word from the EEPROM. If this times out or fails, do
3528 * not continue or we could be in for a very long wait while every
3531 status = hw->eeprom.ops.read(hw, 0, &checksum);
3533 DEBUGOUT("EEPROM read failed\n");
3537 status = hw->eeprom.ops.calc_checksum(hw);
3541 checksum = (u16)(status & 0xffff);
3543 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3548 /* Verify read checksum from EEPROM is the same as
3549 * calculated checksum
3551 if (read_checksum != checksum) {
3552 status = IXGBE_ERR_EEPROM_CHECKSUM;
3553 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
3554 "Invalid EEPROM checksum");
3557 /* If the user cares, return the calculated checksum */
3559 *checksum_val = checksum;
3565 * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
3566 * @hw: pointer to hardware structure
3568 * After writing EEPROM to shadow RAM using EEWR register, software calculates
3569 * checksum and updates the EEPROM and instructs the hardware to update
3572 s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
3577 DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
3579 /* Read the first word from the EEPROM. If this times out or fails, do
3580 * not continue or we could be in for a very long wait while every
3583 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
3585 DEBUGOUT("EEPROM read failed\n");
3589 status = ixgbe_calc_eeprom_checksum_X550(hw);
3593 checksum = (u16)(status & 0xffff);
3595 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3600 status = ixgbe_update_flash_X550(hw);
3606 * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
3607 * @hw: pointer to hardware structure
3609 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
3611 s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
3613 s32 status = IXGBE_SUCCESS;
3614 union ixgbe_hic_hdr2 buffer;
3616 DEBUGFUNC("ixgbe_update_flash_X550");
3618 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
3619 buffer.req.buf_lenh = 0;
3620 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
3621 buffer.req.checksum = FW_DEFAULT_CHECKSUM;
3623 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3625 IXGBE_HI_COMMAND_TIMEOUT, FALSE);
3631 * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
3632 * @hw: pointer to hardware structure
3634 * Determines physical layer capabilities of the current configuration.
3636 u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
3638 u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
3639 u16 ext_ability = 0;
3641 DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
3643 hw->phy.ops.identify(hw);
3645 switch (hw->phy.type) {
3646 case ixgbe_phy_x550em_kr:
3647 if (hw->mac.type == ixgbe_mac_X550EM_a) {
3648 if (hw->phy.nw_mng_if_sel &
3649 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
3651 IXGBE_PHYSICAL_LAYER_2500BASE_KX;
3653 } else if (hw->device_id ==
3654 IXGBE_DEV_ID_X550EM_A_KR_L) {
3656 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3661 case ixgbe_phy_x550em_xfi:
3662 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
3663 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3665 case ixgbe_phy_x550em_kx4:
3666 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
3667 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3669 case ixgbe_phy_x550em_ext_t:
3670 hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
3671 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
3673 if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
3674 physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
3675 if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
3676 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3679 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL)
3680 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3681 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL)
3682 physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
3683 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL)
3684 physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
3686 case ixgbe_phy_sgmii:
3687 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3689 case ixgbe_phy_ext_1g_t:
3690 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
3696 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
3697 physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
3699 return physical_layer;
3703 * ixgbe_get_bus_info_x550em - Set PCI bus info
3704 * @hw: pointer to hardware structure
3706 * Sets bus link width and speed to unknown because X550em is
3709 s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
3712 DEBUGFUNC("ixgbe_get_bus_info_x550em");
3714 hw->bus.width = ixgbe_bus_width_unknown;
3715 hw->bus.speed = ixgbe_bus_speed_unknown;
3717 hw->mac.ops.set_lan_id(hw);
3719 return IXGBE_SUCCESS;
3723 * ixgbe_disable_rx_x550 - Disable RX unit
3724 * @hw: pointer to hardware structure
3726 * Enables the Rx DMA unit for x550
3728 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
3730 u32 rxctrl, pfdtxgswc;
3732 struct ixgbe_hic_disable_rxen fw_cmd;
3734 DEBUGFUNC("ixgbe_enable_rx_dma_x550");
3736 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3737 if (rxctrl & IXGBE_RXCTRL_RXEN) {
3738 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
3739 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
3740 pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
3741 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
3742 hw->mac.set_lben = TRUE;
3744 hw->mac.set_lben = FALSE;
3747 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
3748 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
3749 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
3750 fw_cmd.port_number = (u8)hw->bus.lan_id;
3752 status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
3753 sizeof(struct ixgbe_hic_disable_rxen),
3754 IXGBE_HI_COMMAND_TIMEOUT, TRUE);
3756 /* If we fail - disable RX using register write */
3758 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3759 if (rxctrl & IXGBE_RXCTRL_RXEN) {
3760 rxctrl &= ~IXGBE_RXCTRL_RXEN;
3761 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
3768 * ixgbe_enter_lplu_x550em - Transition to low power states
3769 * @hw: pointer to hardware structure
3771 * Configures Low Power Link Up on transition to low power states
3772 * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
3773 * X557 PHY immediately prior to entering LPLU.
3775 s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
3777 u16 an_10g_cntl_reg, autoneg_reg, speed;
3779 ixgbe_link_speed lcd_speed;
3783 /* SW LPLU not required on later HW revisions. */
3784 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
3785 (IXGBE_FUSES0_REV_MASK &
3786 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
3787 return IXGBE_SUCCESS;
3789 /* If blocked by MNG FW, then don't restart AN */
3790 if (ixgbe_check_reset_blocked(hw))
3791 return IXGBE_SUCCESS;
3793 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3794 if (status != IXGBE_SUCCESS)
3797 status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
3799 if (status != IXGBE_SUCCESS)
3802 /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
3803 * disabled, then force link down by entering low power mode.
3805 if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
3806 !(hw->wol_enabled || ixgbe_mng_present(hw)))
3807 return ixgbe_set_copper_phy_power(hw, FALSE);
3810 status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
3812 if (status != IXGBE_SUCCESS)
3815 /* If no valid LCD link speed, then force link down and exit. */
3816 if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
3817 return ixgbe_set_copper_phy_power(hw, FALSE);
3819 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
3820 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3823 if (status != IXGBE_SUCCESS)
3826 /* If no link now, speed is invalid so take link down */
3827 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3828 if (status != IXGBE_SUCCESS)
3829 return ixgbe_set_copper_phy_power(hw, FALSE);
3831 /* clear everything but the speed bits */
3832 speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
3834 /* If current speed is already LCD, then exit. */
3835 if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
3836 (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
3837 ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
3838 (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
3841 /* Clear AN completed indication */
3842 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
3843 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3846 if (status != IXGBE_SUCCESS)
3849 status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
3850 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3853 if (status != IXGBE_SUCCESS)
3856 status = hw->phy.ops.read_reg(hw,
3857 IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
3858 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3861 if (status != IXGBE_SUCCESS)
3864 save_autoneg = hw->phy.autoneg_advertised;
3866 /* Setup link at least common link speed */
3867 status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
3869 /* restore autoneg from before setting lplu speed */
3870 hw->phy.autoneg_advertised = save_autoneg;
3876 * ixgbe_get_lcd_x550em - Determine lowest common denominator
3877 * @hw: pointer to hardware structure
3878 * @lcd_speed: pointer to lowest common link speed
3880 * Determine lowest common link speed with link partner.
3882 s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
3886 u16 word = hw->eeprom.ctrl_word_3;
3888 *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
3890 status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
3891 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3894 if (status != IXGBE_SUCCESS)
3897 /* If link partner advertised 1G, return 1G */
3898 if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
3899 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
3903 /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
3904 if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
3905 (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
3908 /* Link partner not capable of lower speeds, return 10G */
3909 *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
3914 * ixgbe_setup_fc_X550em - Set up flow control
3915 * @hw: pointer to hardware structure
3917 * Called at init time to set up flow control.
3919 s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
3921 s32 ret_val = IXGBE_SUCCESS;
3922 u32 pause, asm_dir, reg_val;
3924 DEBUGFUNC("ixgbe_setup_fc_X550em");
3926 /* Validate the requested mode */
3927 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
3928 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3929 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
3930 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
3934 /* 10gig parts do not have a word in the EEPROM to determine the
3935 * default flow control setting, so we explicitly set it to full.
3937 if (hw->fc.requested_mode == ixgbe_fc_default)
3938 hw->fc.requested_mode = ixgbe_fc_full;
3940 /* Determine PAUSE and ASM_DIR bits. */
3941 switch (hw->fc.requested_mode) {
3946 case ixgbe_fc_tx_pause:
3950 case ixgbe_fc_rx_pause:
3951 /* Rx Flow control is enabled and Tx Flow control is
3952 * disabled by software override. Since there really
3953 * isn't a way to advertise that we are capable of RX
3954 * Pause ONLY, we will advertise that we support both
3955 * symmetric and asymmetric Rx PAUSE, as such we fall
3956 * through to the fc_full statement. Later, we will
3957 * disable the adapter's ability to send PAUSE frames.
3964 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
3965 "Flow control param set incorrectly\n");
3966 ret_val = IXGBE_ERR_CONFIG;
3970 switch (hw->device_id) {
3971 case IXGBE_DEV_ID_X550EM_X_KR:
3972 case IXGBE_DEV_ID_X550EM_A_KR:
3973 case IXGBE_DEV_ID_X550EM_A_KR_L:
3974 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
3975 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3976 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3977 if (ret_val != IXGBE_SUCCESS)
3979 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3980 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
3982 reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
3984 reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3985 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
3986 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3987 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3989 /* This device does not fully support AN. */
3990 hw->fc.disable_fc_autoneg = TRUE;
3992 case IXGBE_DEV_ID_X550EM_X_XFI:
3993 hw->fc.disable_fc_autoneg = TRUE;
4004 * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
4005 * @hw: pointer to hardware structure
4007 * Enable flow control according to IEEE clause 37.
4009 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
4011 u32 link_s1, lp_an_page_low, an_cntl_1;
4012 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4013 ixgbe_link_speed speed;
4016 /* AN should have completed when the cable was plugged in.
4017 * Look for reasons to bail out. Bail out if:
4018 * - FC autoneg is disabled, or if
4021 if (hw->fc.disable_fc_autoneg) {
4022 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4023 "Flow control autoneg is disabled");
4027 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
4029 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4033 /* Check at auto-negotiation has completed */
4034 status = hw->mac.ops.read_iosf_sb_reg(hw,
4035 IXGBE_KRM_LINK_S1(hw->bus.lan_id),
4036 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
4038 if (status != IXGBE_SUCCESS ||
4039 (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
4040 DEBUGOUT("Auto-Negotiation did not complete\n");
4041 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4045 /* Read the 10g AN autoc and LP ability registers and resolve
4046 * local flow control settings accordingly
4048 status = hw->mac.ops.read_iosf_sb_reg(hw,
4049 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4050 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
4052 if (status != IXGBE_SUCCESS) {
4053 DEBUGOUT("Auto-Negotiation did not complete\n");
4057 status = hw->mac.ops.read_iosf_sb_reg(hw,
4058 IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
4059 IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
4061 if (status != IXGBE_SUCCESS) {
4062 DEBUGOUT("Auto-Negotiation did not complete\n");
4066 status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
4067 IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
4068 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
4069 IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
4070 IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
4073 if (status == IXGBE_SUCCESS) {
4074 hw->fc.fc_was_autonegged = TRUE;
4076 hw->fc.fc_was_autonegged = FALSE;
4077 hw->fc.current_mode = hw->fc.requested_mode;
4082 * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
4083 * @hw: pointer to hardware structure
4086 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
4088 hw->fc.fc_was_autonegged = FALSE;
4089 hw->fc.current_mode = hw->fc.requested_mode;
4093 * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
4094 * @hw: pointer to hardware structure
4096 * Enable flow control according to IEEE clause 37.
4098 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
4100 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4101 u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
4102 ixgbe_link_speed speed;
4105 /* AN should have completed when the cable was plugged in.
4106 * Look for reasons to bail out. Bail out if:
4107 * - FC autoneg is disabled, or if
4110 if (hw->fc.disable_fc_autoneg) {
4111 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4112 "Flow control autoneg is disabled");
4116 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
4118 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4122 /* Check if auto-negotiation has completed */
4123 status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
4124 if (status != IXGBE_SUCCESS ||
4125 !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
4126 DEBUGOUT("Auto-Negotiation did not complete\n");
4127 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4131 /* Negotiate the flow control */
4132 status = ixgbe_negotiate_fc(hw, info[0], info[0],
4133 FW_PHY_ACT_GET_LINK_INFO_FC_RX,
4134 FW_PHY_ACT_GET_LINK_INFO_FC_TX,
4135 FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
4136 FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
4139 if (status == IXGBE_SUCCESS) {
4140 hw->fc.fc_was_autonegged = TRUE;
4142 hw->fc.fc_was_autonegged = FALSE;
4143 hw->fc.current_mode = hw->fc.requested_mode;
4148 * ixgbe_setup_fc_backplane_x550em_a - Set up flow control
4149 * @hw: pointer to hardware structure
4151 * Called at init time to set up flow control.
4153 s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
4155 s32 status = IXGBE_SUCCESS;
4158 DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
4160 /* Validate the requested mode */
4161 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
4162 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4163 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
4164 return IXGBE_ERR_INVALID_LINK_SETTINGS;
4167 if (hw->fc.requested_mode == ixgbe_fc_default)
4168 hw->fc.requested_mode = ixgbe_fc_full;
4170 /* Set up the 1G and 10G flow control advertisement registers so the
4171 * HW will be able to do FC autoneg once the cable is plugged in. If
4172 * we link at 10G, the 1G advertisement is harmless and vice versa.
4174 status = hw->mac.ops.read_iosf_sb_reg(hw,
4175 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4176 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
4178 if (status != IXGBE_SUCCESS) {
4179 DEBUGOUT("Auto-Negotiation did not complete\n");
4183 /* The possible values of fc.requested_mode are:
4184 * 0: Flow control is completely disabled
4185 * 1: Rx flow control is enabled (we can receive pause frames,
4186 * but not send pause frames).
4187 * 2: Tx flow control is enabled (we can send pause frames but
4188 * we do not support receiving pause frames).
4189 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4192 switch (hw->fc.requested_mode) {
4194 /* Flow control completely disabled by software override. */
4195 an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4196 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
4198 case ixgbe_fc_tx_pause:
4199 /* Tx Flow control is enabled, and Rx Flow control is
4200 * disabled by software override.
4202 an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4203 an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
4205 case ixgbe_fc_rx_pause:
4206 /* Rx Flow control is enabled and Tx Flow control is
4207 * disabled by software override. Since there really
4208 * isn't a way to advertise that we are capable of RX
4209 * Pause ONLY, we will advertise that we support both
4210 * symmetric and asymmetric Rx PAUSE, as such we fall
4211 * through to the fc_full statement. Later, we will
4212 * disable the adapter's ability to send PAUSE frames.
4215 /* Flow control (both Rx and Tx) is enabled by SW override. */
4216 an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4217 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4220 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
4221 "Flow control param set incorrectly\n");
4222 return IXGBE_ERR_CONFIG;
4225 status = hw->mac.ops.write_iosf_sb_reg(hw,
4226 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4227 IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
4229 /* Restart auto-negotiation. */
4230 status = ixgbe_restart_an_internal_phy_x550em(hw);
4236 * ixgbe_set_mux - Set mux for port 1 access with CS4227
4237 * @hw: pointer to hardware structure
4238 * @state: set mux if 1, clear if 0
4240 static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
4244 if (!hw->bus.lan_id)
4246 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4248 esdp |= IXGBE_ESDP_SDP1;
4250 esdp &= ~IXGBE_ESDP_SDP1;
4251 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4252 IXGBE_WRITE_FLUSH(hw);
4256 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
4257 * @hw: pointer to hardware structure
4258 * @mask: Mask to specify which semaphore to acquire
4260 * Acquires the SWFW semaphore and sets the I2C MUX
4262 s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4266 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
4268 status = ixgbe_acquire_swfw_sync_X540(hw, mask);
4272 if (mask & IXGBE_GSSR_I2C_MASK)
4273 ixgbe_set_mux(hw, 1);
4275 return IXGBE_SUCCESS;
4279 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
4280 * @hw: pointer to hardware structure
4281 * @mask: Mask to specify which semaphore to release
4283 * Releases the SWFW semaphore and sets the I2C MUX
4285 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4287 DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
4289 if (mask & IXGBE_GSSR_I2C_MASK)
4290 ixgbe_set_mux(hw, 0);
4292 ixgbe_release_swfw_sync_X540(hw, mask);
4296 * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
4297 * @hw: pointer to hardware structure
4298 * @mask: Mask to specify which semaphore to acquire
4300 * Acquires the SWFW semaphore and get the shared phy token as needed
4302 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4304 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4305 int retries = FW_PHY_TOKEN_RETRIES;
4306 s32 status = IXGBE_SUCCESS;
4308 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
4311 status = IXGBE_SUCCESS;
4313 status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
4315 DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n",
4319 if (!(mask & IXGBE_GSSR_TOKEN_SM))
4320 return IXGBE_SUCCESS;
4322 status = ixgbe_get_phy_token(hw);
4323 if (status == IXGBE_ERR_TOKEN_RETRY)
4324 DEBUGOUT1("Could not acquire PHY token, Status = %d\n",
4327 if (status == IXGBE_SUCCESS)
4328 return IXGBE_SUCCESS;
4331 ixgbe_release_swfw_sync_X540(hw, hmask);
4333 if (status != IXGBE_ERR_TOKEN_RETRY) {
4334 DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n",
4340 DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n",
4346 * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
4347 * @hw: pointer to hardware structure
4348 * @mask: Mask to specify which semaphore to release
4350 * Releases the SWFW semaphore and puts the shared phy token as needed
4352 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4354 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4356 DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
4358 if (mask & IXGBE_GSSR_TOKEN_SM)
4359 ixgbe_put_phy_token(hw);
4362 ixgbe_release_swfw_sync_X540(hw, hmask);
4366 * ixgbe_read_phy_reg_x550a - Reads specified PHY register
4367 * @hw: pointer to hardware structure
4368 * @reg_addr: 32 bit address of PHY register to read
4369 * @device_type: 5 bit device type
4370 * @phy_data: Pointer to read data from PHY register
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
4376 s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4377 u32 device_type, u16 *phy_data)
4380 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4382 DEBUGFUNC("ixgbe_read_phy_reg_x550a");
4384 if (hw->mac.ops.acquire_swfw_sync(hw, mask))
4385 return IXGBE_ERR_SWFW_SYNC;
4387 status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
4389 hw->mac.ops.release_swfw_sync(hw, mask);
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
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.
4404 s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4405 u32 device_type, u16 phy_data)
4408 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4410 DEBUGFUNC("ixgbe_write_phy_reg_x550a");
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,
4415 hw->mac.ops.release_swfw_sync(hw, mask);
4417 status = IXGBE_ERR_SWFW_SYNC;
4424 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
4425 * @hw: pointer to hardware structure
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
4431 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
4432 * failure alarm, else return PHY access status.
4434 s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
4439 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
4441 if (status != IXGBE_SUCCESS)
4445 return ixgbe_setup_internal_phy(hw);
4447 return IXGBE_SUCCESS;
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
4456 * Setup internal/external PHY link speed based on link speed, then set
4457 * external PHY auto advertised link speed.
4459 * Returns error status for any failure
4461 s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
4462 ixgbe_link_speed speed,
4463 bool autoneg_wait_to_complete)
4466 ixgbe_link_speed force_speed;
4468 bool link_up = false;
4470 DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
4472 /* Setup internal/external PHY link speed to iXFI (10G), unless
4473 * only 1G is auto advertised then setup KX link.
4475 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
4476 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
4478 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
4480 /* If X552 and internal link mode is XFI, then setup XFI internal link.
4482 if (hw->mac.type == ixgbe_mac_X550EM_x &&
4483 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
4484 status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
4486 if (status != IXGBE_SUCCESS)
4489 /* Wait for the controller to acquire link */
4490 for (i = 0; i < 10; i++) {
4493 status = ixgbe_check_link(hw, &force_speed, &link_up,
4495 if (status != IXGBE_SUCCESS)
4503 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
4507 * ixgbe_check_link_t_X550em - Determine link and speed status
4508 * @hw: pointer to hardware structure
4509 * @speed: pointer to link speed
4510 * @link_up: TRUE when link is up
4511 * @link_up_wait_to_complete: bool used to wait for link up or not
4513 * Check that both the MAC and X557 external PHY have link.
4515 s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
4516 bool *link_up, bool link_up_wait_to_complete)
4519 u16 i, autoneg_status = 0;
4521 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
4522 return IXGBE_ERR_CONFIG;
4524 status = ixgbe_check_mac_link_generic(hw, speed, link_up,
4525 link_up_wait_to_complete);
4527 /* If check link fails or MAC link is not up, then return */
4528 if (status != IXGBE_SUCCESS || !(*link_up))
4531 /* MAC link is up, so check external PHY link.
4532 * X557 PHY. Link status is latching low, and can only be used to detect
4533 * link drop, and not the current status of the link without performing
4534 * back-to-back reads.
4536 for (i = 0; i < 2; i++) {
4537 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
4538 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4541 if (status != IXGBE_SUCCESS)
4545 /* If external PHY link is not up, then indicate link not up */
4546 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
4549 return IXGBE_SUCCESS;
4553 * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
4554 * @hw: pointer to hardware structure
4556 s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
4560 status = ixgbe_reset_phy_generic(hw);
4562 if (status != IXGBE_SUCCESS)
4565 /* Configure Link Status Alarm and Temperature Threshold interrupts */
4566 return ixgbe_enable_lasi_ext_t_x550em(hw);
4570 * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
4571 * @hw: pointer to hardware structure
4572 * @led_idx: led number to turn on
4574 s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4578 DEBUGFUNC("ixgbe_led_on_t_X550em");
4580 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4581 return IXGBE_ERR_PARAM;
4583 /* To turn on the LED, set mode to ON. */
4584 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4585 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4586 phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
4587 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4588 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4590 /* Some designs have the LEDs wired to the MAC */
4591 return ixgbe_led_on_generic(hw, led_idx);
4595 * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
4596 * @hw: pointer to hardware structure
4597 * @led_idx: led number to turn off
4599 s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4603 DEBUGFUNC("ixgbe_led_off_t_X550em");
4605 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4606 return IXGBE_ERR_PARAM;
4608 /* To turn on the LED, set mode to ON. */
4609 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4610 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4611 phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
4612 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4613 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4615 /* Some designs have the LEDs wired to the MAC */
4616 return ixgbe_led_off_generic(hw, led_idx);
4620 * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
4621 * @hw: pointer to the HW structure
4622 * @maj: driver version major number
4623 * @min: driver version minor number
4624 * @build: driver version build number
4625 * @sub: driver version sub build number
4626 * @len: length of driver_ver string
4627 * @driver_ver: driver string
4629 * Sends driver version number to firmware through the manageability
4630 * block. On success return IXGBE_SUCCESS
4631 * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
4632 * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
4634 s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
4635 u8 build, u8 sub, u16 len, const char *driver_ver)
4637 struct ixgbe_hic_drv_info2 fw_cmd;
4638 s32 ret_val = IXGBE_SUCCESS;
4641 DEBUGFUNC("ixgbe_set_fw_drv_ver_x550");
4643 if ((len == 0) || (driver_ver == NULL) ||
4644 (len > sizeof(fw_cmd.driver_string)))
4645 return IXGBE_ERR_INVALID_ARGUMENT;
4647 fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
4648 fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
4649 fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
4650 fw_cmd.port_num = (u8)hw->bus.func;
4651 fw_cmd.ver_maj = maj;
4652 fw_cmd.ver_min = min;
4653 fw_cmd.ver_build = build;
4654 fw_cmd.ver_sub = sub;
4655 fw_cmd.hdr.checksum = 0;
4656 memcpy(fw_cmd.driver_string, driver_ver, len);
4657 fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
4658 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
4660 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
4661 ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
4663 IXGBE_HI_COMMAND_TIMEOUT,
4665 if (ret_val != IXGBE_SUCCESS)
4668 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
4669 FW_CEM_RESP_STATUS_SUCCESS)
4670 ret_val = IXGBE_SUCCESS;
4672 ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;