1 /*******************************************************************************
3 Copyright (c) 2001-2015, 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 ***************************************************************************/
34 #include "ixgbe_x550.h"
35 #include "ixgbe_x540.h"
36 #include "ixgbe_type.h"
37 #include "ixgbe_api.h"
38 #include "ixgbe_common.h"
39 #include "ixgbe_phy.h"
41 STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
42 STATIC s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
43 STATIC void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
44 STATIC s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
47 * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
48 * @hw: pointer to hardware structure
50 * Initialize the function pointers and assign the MAC type for X550.
51 * Does not touch the hardware.
53 s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
55 struct ixgbe_mac_info *mac = &hw->mac;
56 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
59 DEBUGFUNC("ixgbe_init_ops_X550");
61 ret_val = ixgbe_init_ops_X540(hw);
62 mac->ops.dmac_config = ixgbe_dmac_config_X550;
63 mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
64 mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
65 mac->ops.setup_eee = NULL;
66 mac->ops.set_source_address_pruning =
67 ixgbe_set_source_address_pruning_X550;
68 mac->ops.set_ethertype_anti_spoofing =
69 ixgbe_set_ethertype_anti_spoofing_X550;
71 mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
72 eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
73 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
74 eeprom->ops.read = ixgbe_read_ee_hostif_X550;
75 eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
76 eeprom->ops.write = ixgbe_write_ee_hostif_X550;
77 eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
78 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
79 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
81 mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
82 mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
83 mac->ops.mdd_event = ixgbe_mdd_event_X550;
84 mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
85 mac->ops.disable_rx = ixgbe_disable_rx_x550;
86 /* Manageability interface */
87 mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550;
88 switch (hw->device_id) {
89 case IXGBE_DEV_ID_X550EM_X_10G_T:
90 case IXGBE_DEV_ID_X550EM_A_10G_T:
91 hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
92 hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
101 * ixgbe_read_cs4227 - Read CS4227 register
102 * @hw: pointer to hardware structure
103 * @reg: register number to write
104 * @value: pointer to receive value read
106 * Returns status code
108 STATIC s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
110 return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
114 * ixgbe_write_cs4227 - Write CS4227 register
115 * @hw: pointer to hardware structure
116 * @reg: register number to write
117 * @value: value to write to register
119 * Returns status code
121 STATIC s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
123 return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
127 * ixgbe_read_pe - Read register from port expander
128 * @hw: pointer to hardware structure
129 * @reg: register number to read
130 * @value: pointer to receive read value
132 * Returns status code
134 STATIC s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
138 status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
139 if (status != IXGBE_SUCCESS)
140 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
141 "port expander access failed with %d\n", status);
146 * ixgbe_write_pe - Write register to port expander
147 * @hw: pointer to hardware structure
148 * @reg: register number to write
149 * @value: value to write
151 * Returns status code
153 STATIC s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
157 status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
158 if (status != IXGBE_SUCCESS)
159 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
160 "port expander access failed with %d\n", status);
165 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
166 * @hw: pointer to hardware structure
168 * This function assumes that the caller has acquired the proper semaphore.
171 STATIC s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
178 /* Trigger hard reset. */
179 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
180 if (status != IXGBE_SUCCESS)
182 reg |= IXGBE_PE_BIT1;
183 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
184 if (status != IXGBE_SUCCESS)
187 status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, ®);
188 if (status != IXGBE_SUCCESS)
190 reg &= ~IXGBE_PE_BIT1;
191 status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
192 if (status != IXGBE_SUCCESS)
195 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
196 if (status != IXGBE_SUCCESS)
198 reg &= ~IXGBE_PE_BIT1;
199 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
200 if (status != IXGBE_SUCCESS)
203 usec_delay(IXGBE_CS4227_RESET_HOLD);
205 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
206 if (status != IXGBE_SUCCESS)
208 reg |= IXGBE_PE_BIT1;
209 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
210 if (status != IXGBE_SUCCESS)
213 /* Wait for the reset to complete. */
214 msec_delay(IXGBE_CS4227_RESET_DELAY);
215 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
216 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
218 if (status == IXGBE_SUCCESS &&
219 value == IXGBE_CS4227_EEPROM_LOAD_OK)
221 msec_delay(IXGBE_CS4227_CHECK_DELAY);
223 if (retry == IXGBE_CS4227_RETRIES) {
224 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
225 "CS4227 reset did not complete.");
226 return IXGBE_ERR_PHY;
229 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
230 if (status != IXGBE_SUCCESS ||
231 !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
232 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
233 "CS4227 EEPROM did not load successfully.");
234 return IXGBE_ERR_PHY;
237 return IXGBE_SUCCESS;
241 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
242 * @hw: pointer to hardware structure
244 STATIC void ixgbe_check_cs4227(struct ixgbe_hw *hw)
246 s32 status = IXGBE_SUCCESS;
247 u32 swfw_mask = hw->phy.phy_semaphore_mask;
251 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
252 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
253 if (status != IXGBE_SUCCESS) {
254 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
255 "semaphore failed with %d", status);
256 msec_delay(IXGBE_CS4227_CHECK_DELAY);
260 /* Get status of reset flow. */
261 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
263 if (status == IXGBE_SUCCESS &&
264 value == IXGBE_CS4227_RESET_COMPLETE)
267 if (status != IXGBE_SUCCESS ||
268 value != IXGBE_CS4227_RESET_PENDING)
271 /* Reset is pending. Wait and check again. */
272 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
273 msec_delay(IXGBE_CS4227_CHECK_DELAY);
276 /* If still pending, assume other instance failed. */
277 if (retry == IXGBE_CS4227_RETRIES) {
278 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
279 if (status != IXGBE_SUCCESS) {
280 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
281 "semaphore failed with %d", status);
286 /* Reset the CS4227. */
287 status = ixgbe_reset_cs4227(hw);
288 if (status != IXGBE_SUCCESS) {
289 ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
290 "CS4227 reset failed: %d", status);
294 /* Reset takes so long, temporarily release semaphore in case the
295 * other driver instance is waiting for the reset indication.
297 ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
298 IXGBE_CS4227_RESET_PENDING);
299 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
301 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
302 if (status != IXGBE_SUCCESS) {
303 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
304 "semaphore failed with %d", status);
308 /* Record completion for next time. */
309 status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
310 IXGBE_CS4227_RESET_COMPLETE);
313 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
314 msec_delay(hw->eeprom.semaphore_delay);
318 * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
319 * @hw: pointer to hardware structure
321 STATIC void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
323 u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
325 if (hw->bus.lan_id) {
326 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
327 esdp |= IXGBE_ESDP_SDP1_DIR;
329 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
330 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
331 IXGBE_WRITE_FLUSH(hw);
335 * ixgbe_read_phy_reg_mdi_22 - Read from a clause 22 PHY register without lock
336 * @hw: pointer to hardware structure
337 * @reg_addr: 32 bit address of PHY register to read
338 * @dev_type: always unused
339 * @phy_data: Pointer to read data from PHY register
341 STATIC s32 ixgbe_read_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr,
342 u32 dev_type, u16 *phy_data)
344 u32 i, data, command;
345 UNREFERENCED_1PARAMETER(dev_type);
347 /* Setup and write the read command */
348 command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) |
349 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
350 IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_READ_AUTOINC |
351 IXGBE_MSCA_MDI_COMMAND;
353 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
355 /* Check every 10 usec to see if the access completed.
356 * The MDI Command bit will clear when the operation is
359 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
362 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
363 if (!(command & IXGBE_MSCA_MDI_COMMAND))
367 if (command & IXGBE_MSCA_MDI_COMMAND) {
368 ERROR_REPORT1(IXGBE_ERROR_POLLING,
369 "PHY read command did not complete.\n");
370 return IXGBE_ERR_PHY;
373 /* Read operation is complete. Get the data from MSRWD */
374 data = IXGBE_READ_REG(hw, IXGBE_MSRWD);
375 data >>= IXGBE_MSRWD_READ_DATA_SHIFT;
376 *phy_data = (u16)data;
378 return IXGBE_SUCCESS;
382 * ixgbe_write_phy_reg_mdi_22 - Write to a clause 22 PHY register without lock
383 * @hw: pointer to hardware structure
384 * @reg_addr: 32 bit PHY register to write
385 * @dev_type: always unused
386 * @phy_data: Data to write to the PHY register
388 STATIC s32 ixgbe_write_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr,
389 u32 dev_type, u16 phy_data)
392 UNREFERENCED_1PARAMETER(dev_type);
394 /* Put the data in the MDI single read and write data register*/
395 IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data);
397 /* Setup and write the write command */
398 command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) |
399 (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
400 IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE |
401 IXGBE_MSCA_MDI_COMMAND;
403 IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
405 /* Check every 10 usec to see if the access completed.
406 * The MDI Command bit will clear when the operation is
409 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
412 command = IXGBE_READ_REG(hw, IXGBE_MSCA);
413 if (!(command & IXGBE_MSCA_MDI_COMMAND))
417 if (command & IXGBE_MSCA_MDI_COMMAND) {
418 ERROR_REPORT1(IXGBE_ERROR_POLLING,
419 "PHY write cmd didn't complete\n");
420 return IXGBE_ERR_PHY;
423 return IXGBE_SUCCESS;
427 * ixgbe_identify_phy_x550em - Get PHY type based on device id
428 * @hw: pointer to hardware structure
432 STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
434 hw->mac.ops.set_lan_id(hw);
436 ixgbe_read_mng_if_sel_x550em(hw);
438 switch (hw->device_id) {
439 case IXGBE_DEV_ID_X550EM_A_SFP:
440 return ixgbe_identify_module_generic(hw);
441 case IXGBE_DEV_ID_X550EM_X_SFP:
442 /* set up for CS4227 usage */
443 ixgbe_setup_mux_ctl(hw);
444 ixgbe_check_cs4227(hw);
447 case IXGBE_DEV_ID_X550EM_A_SFP_N:
448 return ixgbe_identify_module_generic(hw);
450 case IXGBE_DEV_ID_X550EM_X_KX4:
451 hw->phy.type = ixgbe_phy_x550em_kx4;
453 case IXGBE_DEV_ID_X550EM_X_KR:
454 case IXGBE_DEV_ID_X550EM_A_KR:
455 case IXGBE_DEV_ID_X550EM_A_KR_L:
456 hw->phy.type = ixgbe_phy_x550em_kr;
458 case IXGBE_DEV_ID_X550EM_A_10G_T:
459 case IXGBE_DEV_ID_X550EM_A_1G_T:
460 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
461 case IXGBE_DEV_ID_X550EM_X_1G_T:
462 case IXGBE_DEV_ID_X550EM_X_10G_T:
463 return ixgbe_identify_phy_generic(hw);
467 return IXGBE_SUCCESS;
471 * ixgbe_fw_phy_activity - Perform an activity on a PHY
472 * @hw: pointer to hardware structure
473 * @activity: activity to perform
474 * @data: Pointer to 4 32-bit words of data
476 s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
477 u32 (*data)[FW_PHY_ACT_DATA_COUNT])
480 struct ixgbe_hic_phy_activity_req cmd;
481 struct ixgbe_hic_phy_activity_resp rsp;
483 u16 retries = FW_PHY_ACT_RETRIES;
488 memset(&hic, 0, sizeof(hic));
489 hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
490 hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
491 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
492 hic.cmd.port_number = hw->bus.lan_id;
493 hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
494 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
495 hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
497 rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
499 IXGBE_HI_COMMAND_TIMEOUT,
501 if (rc != IXGBE_SUCCESS)
503 if (hic.rsp.hdr.cmd_or_resp.ret_status ==
504 FW_CEM_RESP_STATUS_SUCCESS) {
505 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
506 (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
507 return IXGBE_SUCCESS;
511 } while (retries > 0);
513 return IXGBE_ERR_HOST_INTERFACE_COMMAND;
516 static const struct {
518 ixgbe_link_speed phy_speed;
520 { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
521 { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
522 { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
523 { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
524 { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
525 { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
529 * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
530 * @hw: pointer to hardware structure
534 static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
536 u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
542 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
546 hw->phy.speeds_supported = 0;
547 phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
548 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
549 if (phy_speeds & ixgbe_fw_map[i].fw_speed)
550 hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
552 if (!hw->phy.autoneg_advertised)
553 hw->phy.autoneg_advertised = hw->phy.speeds_supported;
555 hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
556 phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
557 hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
558 hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
559 if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
560 return IXGBE_ERR_PHY_ADDR_INVALID;
561 return IXGBE_SUCCESS;
565 * ixgbe_identify_phy_fw - Get PHY type based on firmware command
566 * @hw: pointer to hardware structure
570 static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
573 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
575 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
577 hw->phy.type = ixgbe_phy_m88;
578 hw->phy.ops.read_reg = NULL;
579 hw->phy.ops.write_reg = NULL;
580 return ixgbe_get_phy_id_fw(hw);
584 * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
585 * @hw: pointer to hardware structure
589 s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
591 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
593 setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
594 return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
597 STATIC s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
598 u32 device_type, u16 *phy_data)
600 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
601 return IXGBE_NOT_IMPLEMENTED;
604 STATIC s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
605 u32 device_type, u16 phy_data)
607 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
608 return IXGBE_NOT_IMPLEMENTED;
612 * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
613 * @hw: pointer to the hardware structure
614 * @addr: I2C bus address to read from
615 * @reg: I2C device register to read from
616 * @val: pointer to location to receive read value
618 * Returns an error code on error.
620 STATIC s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
623 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true);
627 * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
628 * @hw: pointer to the hardware structure
629 * @addr: I2C bus address to read from
630 * @reg: I2C device register to read from
631 * @val: pointer to location to receive read value
633 * Returns an error code on error.
636 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
639 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false);
643 * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
644 * @hw: pointer to the hardware structure
645 * @addr: I2C bus address to write to
646 * @reg: I2C device register to write to
647 * @val: value to write
649 * Returns an error code on error.
651 STATIC s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
652 u8 addr, u16 reg, u16 val)
654 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true);
658 * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
659 * @hw: pointer to the hardware structure
660 * @addr: I2C bus address to write to
661 * @reg: I2C device register to write to
662 * @val: value to write
664 * Returns an error code on error.
667 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
668 u8 addr, u16 reg, u16 val)
670 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false);
674 * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
675 * @hw: pointer to hardware structure
677 * Initialize the function pointers and for MAC type X550EM.
678 * Does not touch the hardware.
680 s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
682 struct ixgbe_mac_info *mac = &hw->mac;
683 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
684 struct ixgbe_phy_info *phy = &hw->phy;
687 DEBUGFUNC("ixgbe_init_ops_X550EM");
689 /* Similar to X550 so start there. */
690 ret_val = ixgbe_init_ops_X550(hw);
692 /* Since this function eventually calls
693 * ixgbe_init_ops_540 by design, we are setting
694 * the pointers to NULL explicitly here to overwrite
695 * the values being set in the x540 function.
697 /* Thermal sensor not supported in x550EM */
698 mac->ops.get_thermal_sensor_data = NULL;
699 mac->ops.init_thermal_sensor_thresh = NULL;
700 mac->thermal_sensor_enabled = false;
702 /* FCOE not supported in x550EM */
703 mac->ops.get_san_mac_addr = NULL;
704 mac->ops.set_san_mac_addr = NULL;
705 mac->ops.get_wwn_prefix = NULL;
706 mac->ops.get_fcoe_boot_status = NULL;
708 /* IPsec not supported in x550EM */
709 mac->ops.disable_sec_rx_path = NULL;
710 mac->ops.enable_sec_rx_path = NULL;
712 /* AUTOC register is not present in x550EM. */
713 mac->ops.prot_autoc_read = NULL;
714 mac->ops.prot_autoc_write = NULL;
716 /* X550EM bus type is internal*/
717 hw->bus.type = ixgbe_bus_type_internal;
718 mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
721 mac->ops.get_media_type = ixgbe_get_media_type_X550em;
722 mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
723 mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
724 mac->ops.reset_hw = ixgbe_reset_hw_X550em;
725 mac->ops.get_supported_physical_layer =
726 ixgbe_get_supported_physical_layer_X550em;
728 if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
729 mac->ops.setup_fc = ixgbe_setup_fc_generic;
731 mac->ops.setup_fc = ixgbe_setup_fc_X550em;
734 phy->ops.init = ixgbe_init_phy_ops_X550em;
735 switch (hw->device_id) {
736 case IXGBE_DEV_ID_X550EM_A_1G_T:
737 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
738 mac->ops.setup_fc = NULL;
739 phy->ops.identify = ixgbe_identify_phy_fw;
740 phy->ops.set_phy_power = NULL;
741 phy->ops.get_firmware_version = NULL;
744 phy->ops.identify = ixgbe_identify_phy_x550em;
747 if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
748 phy->ops.set_phy_power = NULL;
752 eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
753 eeprom->ops.read = ixgbe_read_ee_hostif_X550;
754 eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
755 eeprom->ops.write = ixgbe_write_ee_hostif_X550;
756 eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
757 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
758 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
759 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
765 * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
766 * @hw: pointer to hardware structure
768 static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
770 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
774 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
777 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
778 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
779 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
780 return IXGBE_ERR_INVALID_LINK_SETTINGS;
783 switch (hw->fc.requested_mode) {
785 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
786 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
788 case ixgbe_fc_rx_pause:
789 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
790 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
792 case ixgbe_fc_tx_pause:
793 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
794 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
800 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
801 if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
802 setup[0] |= ixgbe_fw_map[i].fw_speed;
804 setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
806 if (hw->phy.eee_speeds_advertised)
807 setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
809 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
812 if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
813 return IXGBE_ERR_OVERTEMP;
814 return IXGBE_SUCCESS;
818 * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
819 * @hw: pointer to hardware structure
821 * Called at init time to set up flow control.
823 static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
825 if (hw->fc.requested_mode == ixgbe_fc_default)
826 hw->fc.requested_mode = ixgbe_fc_full;
828 return ixgbe_setup_fw_link(hw);
832 * ixgbe_setup_eee_fw - Enable/disable EEE support
833 * @hw: pointer to the HW structure
834 * @enable_eee: boolean flag to enable EEE
836 * Enable/disable EEE based on enable_eee flag.
837 * This function controls EEE for firmware-based PHY implementations.
839 static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
841 if (!!hw->phy.eee_speeds_advertised == enable_eee)
842 return IXGBE_SUCCESS;
844 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
846 hw->phy.eee_speeds_advertised = 0;
847 return hw->phy.ops.setup_link(hw);
851 * ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
852 * @hw: pointer to hardware structure
854 * Initialize the function pointers and for MAC type X550EM_a.
855 * Does not touch the hardware.
857 s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
859 struct ixgbe_mac_info *mac = &hw->mac;
862 DEBUGFUNC("ixgbe_init_ops_X550EM_a");
864 /* Start with generic X550EM init */
865 ret_val = ixgbe_init_ops_X550EM(hw);
867 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
868 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
869 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
870 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
872 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
873 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
875 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
876 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
878 switch (mac->ops.get_media_type(hw)) {
879 case ixgbe_media_type_fiber:
880 mac->ops.setup_fc = NULL;
881 mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
883 case ixgbe_media_type_backplane:
884 mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
885 mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
891 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T) ||
892 (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)) {
893 mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
894 mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
897 switch (hw->device_id) {
898 case IXGBE_DEV_ID_X550EM_A_KR:
899 case IXGBE_DEV_ID_X550EM_A_KR_L:
900 mac->ops.setup_eee = ixgbe_setup_eee_fw;
903 mac->ops.setup_eee = NULL;
910 * ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
911 * @hw: pointer to hardware structure
913 * Initialize the function pointers and for MAC type X550EM_x.
914 * Does not touch the hardware.
916 s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
918 struct ixgbe_mac_info *mac = &hw->mac;
919 struct ixgbe_link_info *link = &hw->link;
922 DEBUGFUNC("ixgbe_init_ops_X550EM_x");
924 /* Start with generic X550EM init */
925 ret_val = ixgbe_init_ops_X550EM(hw);
927 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
928 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
929 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
930 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
931 link->ops.read_link = ixgbe_read_i2c_combined_generic;
932 link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
933 link->ops.write_link = ixgbe_write_i2c_combined_generic;
934 link->ops.write_link_unlocked =
935 ixgbe_write_i2c_combined_generic_unlocked;
936 link->addr = IXGBE_CS4227;
942 * ixgbe_dmac_config_X550
943 * @hw: pointer to hardware structure
945 * Configure DMA coalescing. If enabling dmac, dmac is activated.
946 * When disabling dmac, dmac enable dmac bit is cleared.
948 s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
950 u32 reg, high_pri_tc;
952 DEBUGFUNC("ixgbe_dmac_config_X550");
954 /* Disable DMA coalescing before configuring */
955 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
956 reg &= ~IXGBE_DMACR_DMAC_EN;
957 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
959 /* Disable DMA Coalescing if the watchdog timer is 0 */
960 if (!hw->mac.dmac_config.watchdog_timer)
963 ixgbe_dmac_config_tcs_X550(hw);
965 /* Configure DMA Coalescing Control Register */
966 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
968 /* Set the watchdog timer in units of 40.96 usec */
969 reg &= ~IXGBE_DMACR_DMACWT_MASK;
970 reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
972 reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
973 /* If fcoe is enabled, set high priority traffic class */
974 if (hw->mac.dmac_config.fcoe_en) {
975 high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
976 reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
977 IXGBE_DMACR_HIGH_PRI_TC_MASK);
979 reg |= IXGBE_DMACR_EN_MNG_IND;
981 /* Enable DMA coalescing after configuration */
982 reg |= IXGBE_DMACR_DMAC_EN;
983 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
986 return IXGBE_SUCCESS;
990 * ixgbe_dmac_config_tcs_X550
991 * @hw: pointer to hardware structure
993 * Configure DMA coalescing threshold per TC. The dmac enable bit must
994 * be cleared before configuring.
996 s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
998 u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
1000 DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
1002 /* Configure DMA coalescing enabled */
1003 switch (hw->mac.dmac_config.link_speed) {
1004 case IXGBE_LINK_SPEED_10_FULL:
1005 case IXGBE_LINK_SPEED_100_FULL:
1006 pb_headroom = IXGBE_DMACRXT_100M;
1008 case IXGBE_LINK_SPEED_1GB_FULL:
1009 pb_headroom = IXGBE_DMACRXT_1G;
1012 pb_headroom = IXGBE_DMACRXT_10G;
1016 maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
1017 IXGBE_MHADD_MFS_SHIFT) / 1024);
1019 /* Set the per Rx packet buffer receive threshold */
1020 for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
1021 reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
1022 reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
1024 if (tc < hw->mac.dmac_config.num_tcs) {
1025 /* Get Rx PB size */
1026 rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
1027 rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
1028 IXGBE_RXPBSIZE_SHIFT;
1030 /* Calculate receive buffer threshold in kilobytes */
1031 if (rx_pb_size > pb_headroom)
1032 rx_pb_size = rx_pb_size - pb_headroom;
1036 /* Minimum of MFS shall be set for DMCTH */
1037 reg |= (rx_pb_size > maxframe_size_kb) ?
1038 rx_pb_size : maxframe_size_kb;
1040 IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
1042 return IXGBE_SUCCESS;
1046 * ixgbe_dmac_update_tcs_X550
1047 * @hw: pointer to hardware structure
1049 * Disables dmac, updates per TC settings, and then enables dmac.
1051 s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
1055 DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
1057 /* Disable DMA coalescing before configuring */
1058 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
1059 reg &= ~IXGBE_DMACR_DMAC_EN;
1060 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
1062 ixgbe_dmac_config_tcs_X550(hw);
1064 /* Enable DMA coalescing after configuration */
1065 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
1066 reg |= IXGBE_DMACR_DMAC_EN;
1067 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
1069 return IXGBE_SUCCESS;
1073 * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
1074 * @hw: pointer to hardware structure
1076 * Initializes the EEPROM parameters ixgbe_eeprom_info within the
1077 * ixgbe_hw struct in order to set up EEPROM access.
1079 s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
1081 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
1085 DEBUGFUNC("ixgbe_init_eeprom_params_X550");
1087 if (eeprom->type == ixgbe_eeprom_uninitialized) {
1088 eeprom->semaphore_delay = 10;
1089 eeprom->type = ixgbe_flash;
1091 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
1092 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
1093 IXGBE_EEC_SIZE_SHIFT);
1094 eeprom->word_size = 1 << (eeprom_size +
1095 IXGBE_EEPROM_WORD_SIZE_SHIFT);
1097 DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
1098 eeprom->type, eeprom->word_size);
1101 return IXGBE_SUCCESS;
1105 * ixgbe_enable_eee_x550 - Enable EEE support
1106 * @hw: pointer to hardware structure
1108 STATIC s32 ixgbe_enable_eee_x550(struct ixgbe_hw *hw)
1113 switch (hw->device_id) {
1114 case IXGBE_DEV_ID_X550EM_A_KR:
1115 case IXGBE_DEV_ID_X550EM_A_KR_L:
1116 status = hw->mac.ops.read_iosf_sb_reg(hw,
1117 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1118 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
1119 if (status != IXGBE_SUCCESS)
1122 link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
1123 IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX;
1125 /* Don't advertise FEC capability when EEE enabled. */
1126 link_reg &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
1128 status = hw->mac.ops.write_iosf_sb_reg(hw,
1129 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1130 IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
1131 if (status != IXGBE_SUCCESS)
1138 return IXGBE_SUCCESS;
1142 * ixgbe_disable_eee_x550 - Disable EEE support
1143 * @hw: pointer to hardware structure
1145 STATIC s32 ixgbe_disable_eee_x550(struct ixgbe_hw *hw)
1150 switch (hw->device_id) {
1151 case IXGBE_DEV_ID_X550EM_X_KR:
1152 case IXGBE_DEV_ID_X550EM_A_KR:
1153 case IXGBE_DEV_ID_X550EM_A_KR_L:
1154 status = hw->mac.ops.read_iosf_sb_reg(hw,
1155 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1156 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
1157 if (status != IXGBE_SUCCESS)
1160 link_reg &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
1161 IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX);
1163 /* Advertise FEC capability when EEE is disabled. */
1164 link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
1166 status = hw->mac.ops.write_iosf_sb_reg(hw,
1167 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1168 IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
1169 if (status != IXGBE_SUCCESS)
1176 return IXGBE_SUCCESS;
1180 * ixgbe_setup_eee_X550 - Enable/disable EEE support
1181 * @hw: pointer to the HW structure
1182 * @enable_eee: boolean flag to enable EEE
1184 * Enable/disable EEE based on enable_eee flag.
1185 * Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C
1189 s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee)
1194 DEBUGFUNC("ixgbe_setup_eee_X550");
1196 eeer = IXGBE_READ_REG(hw, IXGBE_EEER);
1197 /* Enable or disable EEE per flag */
1199 eeer |= (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
1201 status = ixgbe_enable_eee_x550(hw);
1205 eeer &= ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
1207 status = ixgbe_disable_eee_x550(hw);
1211 IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer);
1213 return IXGBE_SUCCESS;
1217 * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
1218 * @hw: pointer to hardware structure
1219 * @enable: enable or disable source address pruning
1220 * @pool: Rx pool to set source address pruning for
1222 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
1227 /* max rx pool is 63 */
1231 pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
1232 pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
1235 pfflp |= (1ULL << pool);
1237 pfflp &= ~(1ULL << pool);
1239 IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
1240 IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
1244 * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
1245 * @hw: pointer to hardware structure
1246 * @enable: enable or disable switch for Ethertype anti-spoofing
1247 * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
1250 void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
1251 bool enable, int vf)
1253 int vf_target_reg = vf >> 3;
1254 int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
1257 DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
1259 pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
1261 pfvfspoof |= (1 << vf_target_shift);
1263 pfvfspoof &= ~(1 << vf_target_shift);
1265 IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
1269 * ixgbe_iosf_wait - Wait for IOSF command completion
1270 * @hw: pointer to hardware structure
1271 * @ctrl: pointer to location to receive final IOSF control value
1273 * Returns failing status on timeout
1275 * Note: ctrl can be NULL if the IOSF control register value is not needed
1277 STATIC s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
1281 /* Check every 10 usec to see if the address cycle completed.
1282 * The SB IOSF BUSY bit will clear when the operation is
1285 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
1286 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
1287 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
1293 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
1294 ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
1295 return IXGBE_ERR_PHY;
1298 return IXGBE_SUCCESS;
1302 * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
1303 * of the IOSF device
1304 * @hw: pointer to hardware structure
1305 * @reg_addr: 32 bit PHY register to write
1306 * @device_type: 3 bit device type
1307 * @data: Data to write to the register
1309 s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1310 u32 device_type, u32 data)
1312 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1316 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1317 if (ret != IXGBE_SUCCESS)
1320 ret = ixgbe_iosf_wait(hw, NULL);
1321 if (ret != IXGBE_SUCCESS)
1324 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1325 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1327 /* Write IOSF control register */
1328 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1330 /* Write IOSF data register */
1331 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
1333 ret = ixgbe_iosf_wait(hw, &command);
1335 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1336 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1337 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1338 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1339 "Failed to write, error %x\n", error);
1340 ret = IXGBE_ERR_PHY;
1344 ixgbe_release_swfw_semaphore(hw, gssr);
1349 * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
1350 * @hw: pointer to hardware structure
1351 * @reg_addr: 32 bit PHY register to write
1352 * @device_type: 3 bit device type
1353 * @data: Pointer to read data from the register
1355 s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1356 u32 device_type, u32 *data)
1358 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1362 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1363 if (ret != IXGBE_SUCCESS)
1366 ret = ixgbe_iosf_wait(hw, NULL);
1367 if (ret != IXGBE_SUCCESS)
1370 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1371 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1373 /* Write IOSF control register */
1374 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1376 ret = ixgbe_iosf_wait(hw, &command);
1378 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1379 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1380 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1381 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1382 "Failed to read, error %x\n", error);
1383 ret = IXGBE_ERR_PHY;
1386 if (ret == IXGBE_SUCCESS)
1387 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
1390 ixgbe_release_swfw_semaphore(hw, gssr);
1395 * ixgbe_get_phy_token - Get the token for shared phy access
1396 * @hw: Pointer to hardware structure
1399 s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
1401 struct ixgbe_hic_phy_token_req token_cmd;
1404 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1405 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1406 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1407 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1408 token_cmd.port_number = hw->bus.lan_id;
1409 token_cmd.command_type = FW_PHY_TOKEN_REQ;
1411 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1413 IXGBE_HI_COMMAND_TIMEOUT,
1417 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1418 return IXGBE_SUCCESS;
1419 if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY)
1420 return IXGBE_ERR_FW_RESP_INVALID;
1422 return IXGBE_ERR_TOKEN_RETRY;
1426 * ixgbe_put_phy_token - Put the token for shared phy access
1427 * @hw: Pointer to hardware structure
1430 s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
1432 struct ixgbe_hic_phy_token_req token_cmd;
1435 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1436 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1437 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1438 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1439 token_cmd.port_number = hw->bus.lan_id;
1440 token_cmd.command_type = FW_PHY_TOKEN_REL;
1442 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1444 IXGBE_HI_COMMAND_TIMEOUT,
1448 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1449 return IXGBE_SUCCESS;
1451 DEBUGOUT("Put PHY Token host interface command failed");
1452 return IXGBE_ERR_FW_RESP_INVALID;
1456 * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
1457 * of the IOSF device
1458 * @hw: pointer to hardware structure
1459 * @reg_addr: 32 bit PHY register to write
1460 * @device_type: 3 bit device type
1461 * @data: Data to write to the register
1463 s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1464 u32 device_type, u32 data)
1466 struct ixgbe_hic_internal_phy_req write_cmd;
1468 UNREFERENCED_1PARAMETER(device_type);
1470 memset(&write_cmd, 0, sizeof(write_cmd));
1471 write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1472 write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1473 write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1474 write_cmd.port_number = hw->bus.lan_id;
1475 write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
1476 write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1477 write_cmd.write_data = IXGBE_CPU_TO_BE32(data);
1479 status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd,
1481 IXGBE_HI_COMMAND_TIMEOUT, false);
1487 * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
1488 * @hw: pointer to hardware structure
1489 * @reg_addr: 32 bit PHY register to write
1490 * @device_type: 3 bit device type
1491 * @data: Pointer to read data from the register
1493 s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1494 u32 device_type, u32 *data)
1497 struct ixgbe_hic_internal_phy_req cmd;
1498 struct ixgbe_hic_internal_phy_resp rsp;
1501 UNREFERENCED_1PARAMETER(device_type);
1503 memset(&hic, 0, sizeof(hic));
1504 hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1505 hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1506 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1507 hic.cmd.port_number = hw->bus.lan_id;
1508 hic.cmd.command_type = FW_INT_PHY_REQ_READ;
1509 hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1511 status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
1513 IXGBE_HI_COMMAND_TIMEOUT, true);
1515 /* Extract the register value from the response. */
1516 *data = IXGBE_BE32_TO_CPU(hic.rsp.read_data);
1522 * ixgbe_disable_mdd_X550
1523 * @hw: pointer to hardware structure
1525 * Disable malicious driver detection
1527 void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
1531 DEBUGFUNC("ixgbe_disable_mdd_X550");
1533 /* Disable MDD for TX DMA and interrupt */
1534 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1535 reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1536 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1538 /* Disable MDD for RX and interrupt */
1539 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1540 reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1541 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1545 * ixgbe_enable_mdd_X550
1546 * @hw: pointer to hardware structure
1548 * Enable malicious driver detection
1550 void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
1554 DEBUGFUNC("ixgbe_enable_mdd_X550");
1556 /* Enable MDD for TX DMA and interrupt */
1557 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1558 reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1559 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1561 /* Enable MDD for RX and interrupt */
1562 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1563 reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1564 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1568 * ixgbe_restore_mdd_vf_X550
1569 * @hw: pointer to hardware structure
1572 * Restore VF that was disabled during malicious driver detection event
1574 void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
1576 u32 idx, reg, num_qs, start_q, bitmask;
1578 DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
1580 /* Map VF to queues */
1581 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1582 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1583 case IXGBE_MRQC_VMDQRT8TCEN:
1584 num_qs = 8; /* 16 VFs / pools */
1585 bitmask = 0x000000FF;
1587 case IXGBE_MRQC_VMDQRSS32EN:
1588 case IXGBE_MRQC_VMDQRT4TCEN:
1589 num_qs = 4; /* 32 VFs / pools */
1590 bitmask = 0x0000000F;
1592 default: /* 64 VFs / pools */
1594 bitmask = 0x00000003;
1597 start_q = vf * num_qs;
1599 /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
1602 reg |= (bitmask << (start_q % 32));
1603 IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
1604 IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
1608 * ixgbe_mdd_event_X550
1609 * @hw: pointer to hardware structure
1610 * @vf_bitmap: vf bitmap of malicious vfs
1612 * Handle malicious driver detection event.
1614 void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
1617 u32 i, j, reg, q, shift, vf, idx;
1619 DEBUGFUNC("ixgbe_mdd_event_X550");
1621 /* figure out pool size for mapping to vf's */
1622 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1623 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1624 case IXGBE_MRQC_VMDQRT8TCEN:
1625 shift = 3; /* 16 VFs / pools */
1627 case IXGBE_MRQC_VMDQRSS32EN:
1628 case IXGBE_MRQC_VMDQRT4TCEN:
1629 shift = 2; /* 32 VFs / pools */
1632 shift = 1; /* 64 VFs / pools */
1636 /* Read WQBR_TX and WQBR_RX and check for malicious queues */
1637 for (i = 0; i < 4; i++) {
1638 wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
1639 wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
1644 /* Get malicious queue */
1645 for (j = 0; j < 32 && wqbr; j++) {
1647 if (!(wqbr & (1 << j)))
1650 /* Get queue from bitmask */
1653 /* Map queue to vf */
1656 /* Set vf bit in vf_bitmap */
1658 vf_bitmap[idx] |= (1 << (vf % 32));
1665 * ixgbe_get_media_type_X550em - Get media type
1666 * @hw: pointer to hardware structure
1668 * Returns the media type (fiber, copper, backplane)
1670 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
1672 enum ixgbe_media_type media_type;
1674 DEBUGFUNC("ixgbe_get_media_type_X550em");
1676 /* Detect if there is a copper PHY attached. */
1677 switch (hw->device_id) {
1678 case IXGBE_DEV_ID_X550EM_X_KR:
1679 case IXGBE_DEV_ID_X550EM_X_KX4:
1680 case IXGBE_DEV_ID_X550EM_A_KR:
1681 case IXGBE_DEV_ID_X550EM_A_KR_L:
1682 media_type = ixgbe_media_type_backplane;
1684 case IXGBE_DEV_ID_X550EM_X_SFP:
1685 case IXGBE_DEV_ID_X550EM_A_SFP:
1686 case IXGBE_DEV_ID_X550EM_A_SFP_N:
1687 case IXGBE_DEV_ID_X550EM_A_QSFP:
1688 case IXGBE_DEV_ID_X550EM_A_QSFP_N:
1689 media_type = ixgbe_media_type_fiber;
1691 case IXGBE_DEV_ID_X550EM_X_1G_T:
1692 case IXGBE_DEV_ID_X550EM_X_10G_T:
1693 case IXGBE_DEV_ID_X550EM_A_10G_T:
1694 media_type = ixgbe_media_type_copper;
1696 case IXGBE_DEV_ID_X550EM_A_SGMII:
1697 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
1698 media_type = ixgbe_media_type_backplane;
1699 hw->phy.type = ixgbe_phy_sgmii;
1701 case IXGBE_DEV_ID_X550EM_A_1G_T:
1702 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
1703 media_type = ixgbe_media_type_copper;
1706 media_type = ixgbe_media_type_unknown;
1713 * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1714 * @hw: pointer to hardware structure
1715 * @linear: true if SFP module is linear
1717 STATIC s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1719 DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
1721 switch (hw->phy.sfp_type) {
1722 case ixgbe_sfp_type_not_present:
1723 return IXGBE_ERR_SFP_NOT_PRESENT;
1724 case ixgbe_sfp_type_da_cu_core0:
1725 case ixgbe_sfp_type_da_cu_core1:
1728 case ixgbe_sfp_type_srlr_core0:
1729 case ixgbe_sfp_type_srlr_core1:
1730 case ixgbe_sfp_type_da_act_lmt_core0:
1731 case ixgbe_sfp_type_da_act_lmt_core1:
1732 case ixgbe_sfp_type_1g_sx_core0:
1733 case ixgbe_sfp_type_1g_sx_core1:
1734 case ixgbe_sfp_type_1g_lx_core0:
1735 case ixgbe_sfp_type_1g_lx_core1:
1738 case ixgbe_sfp_type_unknown:
1739 case ixgbe_sfp_type_1g_cu_core0:
1740 case ixgbe_sfp_type_1g_cu_core1:
1742 return IXGBE_ERR_SFP_NOT_SUPPORTED;
1745 return IXGBE_SUCCESS;
1749 * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
1750 * @hw: pointer to hardware structure
1752 * Searches for and identifies the SFP module and assigns appropriate PHY type.
1754 s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
1759 DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
1761 status = ixgbe_identify_module_generic(hw);
1763 if (status != IXGBE_SUCCESS)
1766 /* Check if SFP module is supported */
1767 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1773 * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
1774 * @hw: pointer to hardware structure
1776 s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1781 DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
1783 /* Check if SFP module is supported */
1784 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1786 if (status != IXGBE_SUCCESS)
1789 ixgbe_init_mac_link_ops_X550em(hw);
1790 hw->phy.ops.reset = NULL;
1792 return IXGBE_SUCCESS;
1796 * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
1798 * @hw: pointer to hardware structure
1800 STATIC s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
1805 /* Restart auto-negotiation. */
1806 status = hw->mac.ops.read_iosf_sb_reg(hw,
1807 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1808 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
1811 DEBUGOUT("Auto-negotiation did not complete\n");
1815 link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1816 status = hw->mac.ops.write_iosf_sb_reg(hw,
1817 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1818 IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
1820 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1823 /* Indicate to FW that AN restart has been asserted */
1824 status = hw->mac.ops.read_iosf_sb_reg(hw,
1825 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1826 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
1829 DEBUGOUT("Auto-negotiation did not complete\n");
1833 flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
1834 status = hw->mac.ops.write_iosf_sb_reg(hw,
1835 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1836 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
1843 * ixgbe_setup_sgmii - Set up link for sgmii
1844 * @hw: pointer to hardware structure
1846 STATIC s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1849 struct ixgbe_mac_info *mac = &hw->mac;
1850 u32 lval, sval, flx_val;
1853 rc = mac->ops.read_iosf_sb_reg(hw,
1854 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1855 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1859 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1860 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1861 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1862 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1863 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1864 rc = mac->ops.write_iosf_sb_reg(hw,
1865 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1866 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1870 rc = mac->ops.read_iosf_sb_reg(hw,
1871 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1872 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1876 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1877 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1878 rc = mac->ops.write_iosf_sb_reg(hw,
1879 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1880 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1884 rc = mac->ops.read_iosf_sb_reg(hw,
1885 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1886 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1890 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1891 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1892 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1893 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1894 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1896 rc = mac->ops.write_iosf_sb_reg(hw,
1897 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1898 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1902 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1906 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1910 * ixgbe_setup_sgmii_m88 - Set up link for sgmii with Marvell PHYs
1911 * @hw: pointer to hardware structure
1913 STATIC s32 ixgbe_setup_sgmii_m88(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1916 struct ixgbe_mac_info *mac = &hw->mac;
1917 u32 lval, sval, flx_val;
1920 rc = mac->ops.read_iosf_sb_reg(hw,
1921 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1922 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1926 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1927 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1928 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1929 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1930 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1931 rc = mac->ops.write_iosf_sb_reg(hw,
1932 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1933 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1937 rc = mac->ops.read_iosf_sb_reg(hw,
1938 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1939 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1943 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1944 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1945 rc = mac->ops.write_iosf_sb_reg(hw,
1946 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1947 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1951 rc = mac->ops.write_iosf_sb_reg(hw,
1952 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1953 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1957 rc = mac->ops.read_iosf_sb_reg(hw,
1958 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1959 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1963 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1964 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
1965 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1966 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1967 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1969 rc = mac->ops.write_iosf_sb_reg(hw,
1970 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1971 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1975 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1977 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1981 * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1982 * @hw: pointer to hardware structure
1984 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1986 struct ixgbe_mac_info *mac = &hw->mac;
1988 DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
1990 switch (hw->mac.ops.get_media_type(hw)) {
1991 case ixgbe_media_type_fiber:
1992 /* CS4227 does not support autoneg, so disable the laser control
1993 * functions for SFP+ fiber
1995 mac->ops.disable_tx_laser = NULL;
1996 mac->ops.enable_tx_laser = NULL;
1997 mac->ops.flap_tx_laser = NULL;
1998 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
1999 mac->ops.set_rate_select_speed =
2000 ixgbe_set_soft_rate_select_speed;
2002 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
2003 (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
2004 mac->ops.setup_mac_link =
2005 ixgbe_setup_mac_link_sfp_x550a;
2007 mac->ops.setup_mac_link =
2008 ixgbe_setup_mac_link_sfp_x550em;
2010 case ixgbe_media_type_copper:
2011 if (hw->mac.type == ixgbe_mac_X550EM_a) {
2012 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
2013 hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
2014 mac->ops.setup_link = ixgbe_setup_sgmii_m88;
2016 mac->ops.setup_link =
2017 ixgbe_setup_mac_link_t_X550em;
2020 mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
2021 mac->ops.check_link = ixgbe_check_link_t_X550em;
2024 case ixgbe_media_type_backplane:
2025 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
2026 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
2027 mac->ops.setup_link = ixgbe_setup_sgmii;
2035 * ixgbe_get_link_capabilities_x550em - Determines link capabilities
2036 * @hw: pointer to hardware structure
2037 * @speed: pointer to link speed
2038 * @autoneg: true when autoneg or autotry is enabled
2040 s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
2041 ixgbe_link_speed *speed,
2044 DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
2048 if (hw->phy.media_type == ixgbe_media_type_fiber) {
2050 /* CS4227 SFP must not enable auto-negotiation */
2053 /* Check if 1G SFP module. */
2054 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
2055 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
2056 || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
2057 hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
2058 *speed = IXGBE_LINK_SPEED_1GB_FULL;
2059 return IXGBE_SUCCESS;
2062 /* Link capabilities are based on SFP */
2063 if (hw->phy.multispeed_fiber)
2064 *speed = IXGBE_LINK_SPEED_10GB_FULL |
2065 IXGBE_LINK_SPEED_1GB_FULL;
2067 *speed = IXGBE_LINK_SPEED_10GB_FULL;
2069 switch (hw->phy.type) {
2071 *speed = IXGBE_LINK_SPEED_1GB_FULL |
2072 IXGBE_LINK_SPEED_100_FULL |
2073 IXGBE_LINK_SPEED_10_FULL;
2075 case ixgbe_phy_sgmii:
2076 *speed = IXGBE_LINK_SPEED_1GB_FULL;
2078 case ixgbe_phy_x550em_kr:
2079 if (hw->mac.type == ixgbe_mac_X550EM_a) {
2080 /* check different backplane modes */
2081 if (hw->phy.nw_mng_if_sel &
2082 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
2083 *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
2085 } else if (hw->device_id ==
2086 IXGBE_DEV_ID_X550EM_A_KR_L) {
2087 *speed = IXGBE_LINK_SPEED_1GB_FULL;
2093 *speed = IXGBE_LINK_SPEED_10GB_FULL |
2094 IXGBE_LINK_SPEED_1GB_FULL;
2100 return IXGBE_SUCCESS;
2104 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
2105 * @hw: pointer to hardware structure
2106 * @lsc: pointer to boolean flag which indicates whether external Base T
2107 * PHY interrupt is lsc
2109 * Determime if external Base T PHY interrupt cause is high temperature
2110 * failure alarm or link status change.
2112 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
2113 * failure alarm, else return PHY access status.
2115 STATIC s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
2122 /* Vendor alarm triggered */
2123 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2124 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2127 if (status != IXGBE_SUCCESS ||
2128 !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
2131 /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
2132 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
2133 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2136 if (status != IXGBE_SUCCESS ||
2137 !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2138 IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
2141 /* Global alarm triggered */
2142 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
2143 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2146 if (status != IXGBE_SUCCESS)
2149 /* If high temperature failure, then return over temp error and exit */
2150 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
2151 /* power down the PHY in case the PHY FW didn't already */
2152 ixgbe_set_copper_phy_power(hw, false);
2153 return IXGBE_ERR_OVERTEMP;
2154 } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
2155 /* device fault alarm triggered */
2156 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
2157 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2160 if (status != IXGBE_SUCCESS)
2163 /* if device fault was due to high temp alarm handle and exit */
2164 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
2165 /* power down the PHY in case the PHY FW didn't */
2166 ixgbe_set_copper_phy_power(hw, false);
2167 return IXGBE_ERR_OVERTEMP;
2171 /* Vendor alarm 2 triggered */
2172 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2173 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2175 if (status != IXGBE_SUCCESS ||
2176 !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
2179 /* link connect/disconnect event occurred */
2180 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
2181 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2183 if (status != IXGBE_SUCCESS)
2187 if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
2190 return IXGBE_SUCCESS;
2194 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
2195 * @hw: pointer to hardware structure
2197 * Enable link status change and temperature failure alarm for the external
2200 * Returns PHY access status
2202 STATIC s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
2208 /* Clear interrupt flags */
2209 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
2211 /* Enable link status change alarm */
2213 /* Enable the LASI interrupts on X552 devices to receive notifications
2214 * of the link configurations of the external PHY and correspondingly
2215 * support the configuration of the internal iXFI link, since iXFI does
2216 * not support auto-negotiation. This is not required for X553 devices
2217 * having KR support, which performs auto-negotiations and which is used
2218 * as the internal link to the external PHY. Hence adding a check here
2219 * to avoid enabling LASI interrupts for X553 devices.
2221 if (hw->mac.type != ixgbe_mac_X550EM_a) {
2222 status = hw->phy.ops.read_reg(hw,
2223 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2224 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, ®);
2226 if (status != IXGBE_SUCCESS)
2229 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
2231 status = hw->phy.ops.write_reg(hw,
2232 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2233 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
2235 if (status != IXGBE_SUCCESS)
2239 /* Enable high temperature failure and global fault alarms */
2240 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2241 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2244 if (status != IXGBE_SUCCESS)
2247 reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
2248 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
2250 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2251 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2254 if (status != IXGBE_SUCCESS)
2257 /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
2258 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2259 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2262 if (status != IXGBE_SUCCESS)
2265 reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2266 IXGBE_MDIO_GLOBAL_ALARM_1_INT);
2268 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2269 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2272 if (status != IXGBE_SUCCESS)
2275 /* Enable chip-wide vendor alarm */
2276 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2277 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2280 if (status != IXGBE_SUCCESS)
2283 reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
2285 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2286 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2293 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
2294 * @hw: pointer to hardware structure
2295 * @speed: link speed
2297 * Configures the integrated KR PHY.
2299 STATIC s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
2300 ixgbe_link_speed speed)
2305 status = hw->mac.ops.read_iosf_sb_reg(hw,
2306 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2307 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2311 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2312 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
2313 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
2315 /* Advertise 10G support. */
2316 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
2317 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
2319 /* Advertise 1G support. */
2320 if (speed & IXGBE_LINK_SPEED_1GB_FULL)
2321 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
2323 status = hw->mac.ops.write_iosf_sb_reg(hw,
2324 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2325 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2327 if (hw->mac.type == ixgbe_mac_X550EM_a) {
2328 /* Set lane mode to KR auto negotiation */
2329 status = hw->mac.ops.read_iosf_sb_reg(hw,
2330 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2331 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
2336 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2337 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2338 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2339 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2340 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2342 status = hw->mac.ops.write_iosf_sb_reg(hw,
2343 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2344 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2347 return ixgbe_restart_an_internal_phy_x550em(hw);
2351 * ixgbe_setup_m88 - setup m88 PHY
2352 * @hw: pointer to hardware structure
2354 STATIC s32 ixgbe_setup_m88(struct ixgbe_hw *hw)
2356 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
2360 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
2361 return IXGBE_SUCCESS;
2363 rc = hw->mac.ops.acquire_swfw_sync(hw, mask);
2367 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, ®);
2370 if (reg & IXGBE_M88E1500_COPPER_CTRL_POWER_DOWN) {
2371 reg &= ~IXGBE_M88E1500_COPPER_CTRL_POWER_DOWN;
2372 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0,
2376 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_MAC_CTRL_1, 0, ®);
2379 if (reg & IXGBE_M88E1500_MAC_CTRL_1_POWER_DOWN) {
2380 reg &= ~IXGBE_M88E1500_MAC_CTRL_1_POWER_DOWN;
2381 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_MAC_CTRL_1, 0,
2385 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 2);
2389 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_MAC_SPEC_CTRL, 0,
2393 if (reg & IXGBE_M88E1500_MAC_SPEC_CTRL_POWER_DOWN) {
2394 reg &= ~IXGBE_M88E1500_MAC_SPEC_CTRL_POWER_DOWN;
2395 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_MAC_SPEC_CTRL, 0,
2397 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0,
2401 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0,
2405 reg |= IXGBE_M88E1500_COPPER_CTRL_RESET;
2406 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0,
2410 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0,
2416 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, ®);
2420 if (!(reg & IXGBE_M88E1500_COPPER_CTRL_AN_EN)) {
2421 reg |= IXGBE_M88E1500_COPPER_CTRL_AN_EN;
2422 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0,
2426 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_1000T_CTRL, 0, ®);
2429 reg &= ~IXGBE_M88E1500_1000T_CTRL_HALF_DUPLEX;
2430 reg &= ~IXGBE_M88E1500_1000T_CTRL_FULL_DUPLEX;
2431 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
2432 reg |= IXGBE_M88E1500_1000T_CTRL_FULL_DUPLEX;
2433 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_1000T_CTRL, 0, reg);
2435 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_AN, 0, ®);
2438 reg &= ~IXGBE_M88E1500_COPPER_AN_T4;
2439 reg &= ~IXGBE_M88E1500_COPPER_AN_100TX_FD;
2440 reg &= ~IXGBE_M88E1500_COPPER_AN_100TX_HD;
2441 reg &= ~IXGBE_M88E1500_COPPER_AN_10TX_FD;
2442 reg &= ~IXGBE_M88E1500_COPPER_AN_10TX_HD;
2444 /* Flow control auto negotiation configuration was moved from here to
2445 * the function ixgbe_setup_fc_sgmii_x550em_a()
2448 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
2449 reg |= IXGBE_M88E1500_COPPER_AN_100TX_FD;
2450 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL)
2451 reg |= IXGBE_M88E1500_COPPER_AN_10TX_FD;
2452 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_AN, 0, reg);
2454 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, ®);
2457 reg |= IXGBE_M88E1500_COPPER_CTRL_RESTART_AN;
2458 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, reg);
2461 hw->mac.ops.release_swfw_sync(hw, mask);
2465 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0);
2466 hw->mac.ops.release_swfw_sync(hw, mask);
2471 * ixgbe_reset_phy_m88e1500 - Reset m88e1500 PHY
2472 * @hw: pointer to hardware structure
2474 * The PHY token must be held when calling this function.
2476 static s32 ixgbe_reset_phy_m88e1500(struct ixgbe_hw *hw)
2481 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0);
2485 rc = hw->phy.ops.read_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, ®);
2489 reg |= IXGBE_M88E1500_COPPER_CTRL_RESET;
2490 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, reg);
2498 * ixgbe_reset_phy_m88e1543 - Reset m88e1543 PHY
2499 * @hw: pointer to hardware structure
2501 * The PHY token must be held when calling this function.
2503 static s32 ixgbe_reset_phy_m88e1543(struct ixgbe_hw *hw)
2505 return hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0);
2509 * ixgbe_reset_phy_m88 - Reset m88 PHY
2510 * @hw: pointer to hardware structure
2512 STATIC s32 ixgbe_reset_phy_m88(struct ixgbe_hw *hw)
2514 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
2518 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
2519 return IXGBE_SUCCESS;
2521 rc = hw->mac.ops.acquire_swfw_sync(hw, mask);
2525 switch (hw->phy.id) {
2526 case IXGBE_M88E1500_E_PHY_ID:
2527 rc = ixgbe_reset_phy_m88e1500(hw);
2529 case IXGBE_M88E1543_E_PHY_ID:
2530 rc = ixgbe_reset_phy_m88e1543(hw);
2537 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 1);
2541 reg = IXGBE_M88E1500_FIBER_CTRL_RESET |
2542 IXGBE_M88E1500_FIBER_CTRL_DUPLEX_FULL |
2543 IXGBE_M88E1500_FIBER_CTRL_SPEED_MSB;
2544 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_FIBER_CTRL, 0, reg);
2548 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 18);
2552 reg = IXGBE_M88E1500_GEN_CTRL_RESET |
2553 IXGBE_M88E1500_GEN_CTRL_MODE_SGMII_COPPER;
2554 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_GEN_CTRL, 0, reg);
2558 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 1);
2562 reg = IXGBE_M88E1500_FIBER_CTRL_RESET |
2563 IXGBE_M88E1500_FIBER_CTRL_AN_EN |
2564 IXGBE_M88E1500_FIBER_CTRL_DUPLEX_FULL |
2565 IXGBE_M88E1500_FIBER_CTRL_SPEED_MSB;
2566 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_FIBER_CTRL, 0, reg);
2570 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0);
2574 reg = (IXGBE_M88E1500_MAC_CTRL_1_DWN_4X <<
2575 IXGBE_M88E1500_MAC_CTRL_1_DWN_SHIFT) |
2576 (IXGBE_M88E1500_MAC_CTRL_1_ED_TM <<
2577 IXGBE_M88E1500_MAC_CTRL_1_ED_SHIFT) |
2578 (IXGBE_M88E1500_MAC_CTRL_1_MDIX_AUTO <<
2579 IXGBE_M88E1500_MAC_CTRL_1_MDIX_SHIFT);
2580 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_MAC_CTRL_1, 0, reg);
2584 reg = IXGBE_M88E1500_COPPER_CTRL_RESET |
2585 IXGBE_M88E1500_COPPER_CTRL_AN_EN |
2586 IXGBE_M88E1500_COPPER_CTRL_RESTART_AN |
2587 IXGBE_M88E1500_COPPER_CTRL_FULL_DUPLEX |
2588 IXGBE_M88E1500_COPPER_CTRL_SPEED_MSB;
2589 rc = hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_COPPER_CTRL, 0, reg);
2593 hw->mac.ops.release_swfw_sync(hw, mask);
2595 /* In case of first reset set advertised speeds to default value */
2596 if (!hw->phy.autoneg_advertised)
2597 hw->phy.autoneg_advertised = IXGBE_LINK_SPEED_1GB_FULL |
2598 IXGBE_LINK_SPEED_100_FULL |
2599 IXGBE_LINK_SPEED_10_FULL;
2601 return ixgbe_setup_m88(hw);
2604 hw->phy.ops.write_reg_mdi(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0);
2605 hw->mac.ops.release_swfw_sync(hw, mask);
2610 * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
2611 * @hw: pointer to hardware structure
2613 * Read NW_MNG_IF_SEL register and save field values, and check for valid field
2616 STATIC s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
2618 /* Save NW management interface connected on board. This is used
2619 * to determine internal PHY mode.
2621 hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
2623 /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
2624 * PHY address. This register field was has only been used for X552.
2626 if (hw->mac.type == ixgbe_mac_X550EM_a &&
2627 hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
2628 hw->phy.addr = (hw->phy.nw_mng_if_sel &
2629 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
2630 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
2633 return IXGBE_SUCCESS;
2637 * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
2638 * @hw: pointer to hardware structure
2640 * Initialize any function pointers that were not able to be
2641 * set during init_shared_code because the PHY/SFP type was
2642 * not known. Perform the SFP init if necessary.
2644 s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
2646 struct ixgbe_phy_info *phy = &hw->phy;
2649 DEBUGFUNC("ixgbe_init_phy_ops_X550em");
2651 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
2652 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2653 ixgbe_setup_mux_ctl(hw);
2654 phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
2657 switch (hw->device_id) {
2658 case IXGBE_DEV_ID_X550EM_A_1G_T:
2659 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2660 phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi_22;
2661 phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi_22;
2662 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
2663 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
2665 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2667 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2670 case IXGBE_DEV_ID_X550EM_A_10G_T:
2671 case IXGBE_DEV_ID_X550EM_A_SFP:
2672 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
2673 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
2675 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2677 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2679 case IXGBE_DEV_ID_X550EM_X_SFP:
2680 /* set up for CS4227 usage */
2681 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2687 /* Identify the PHY or SFP module */
2688 ret_val = phy->ops.identify(hw);
2689 if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
2692 /* Setup function pointers based on detected hardware */
2693 ixgbe_init_mac_link_ops_X550em(hw);
2694 if (phy->sfp_type != ixgbe_sfp_type_unknown)
2695 phy->ops.reset = NULL;
2697 /* Set functions pointers based on phy type */
2698 switch (hw->phy.type) {
2699 case ixgbe_phy_x550em_kx4:
2700 phy->ops.setup_link = NULL;
2701 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2702 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2704 case ixgbe_phy_x550em_kr:
2705 phy->ops.setup_link = ixgbe_setup_kr_x550em;
2706 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2707 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2709 case ixgbe_phy_x550em_ext_t:
2710 /* If internal link mode is XFI, then setup iXFI internal link,
2711 * else setup KR now.
2713 phy->ops.setup_internal_link =
2714 ixgbe_setup_internal_phy_t_x550em;
2716 /* setup SW LPLU only for first revision of X550EM_x */
2717 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
2718 !(IXGBE_FUSES0_REV_MASK &
2719 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
2720 phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2722 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
2723 phy->ops.reset = ixgbe_reset_phy_t_X550em;
2725 case ixgbe_phy_sgmii:
2726 phy->ops.setup_link = NULL;
2729 phy->ops.setup_link = ixgbe_setup_m88;
2730 phy->ops.reset = ixgbe_reset_phy_m88;
2739 * ixgbe_set_mdio_speed - Set MDIO clock speed
2740 * @hw: pointer to hardware structure
2742 STATIC void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
2746 switch (hw->device_id) {
2747 case IXGBE_DEV_ID_X550EM_X_10G_T:
2748 case IXGBE_DEV_ID_X550EM_A_SGMII:
2749 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
2750 case IXGBE_DEV_ID_X550EM_A_10G_T:
2751 case IXGBE_DEV_ID_X550EM_A_SFP:
2752 case IXGBE_DEV_ID_X550EM_A_QSFP:
2753 /* Config MDIO clock speed before the first MDIO PHY access */
2754 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2755 hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2756 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2758 case IXGBE_DEV_ID_X550EM_A_1G_T:
2759 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2760 /* Select fast MDIO clock speed for these devices */
2761 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2762 hlreg0 |= IXGBE_HLREG0_MDCSPD;
2763 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2771 * ixgbe_reset_hw_X550em - Perform hardware reset
2772 * @hw: pointer to hardware structure
2774 * Resets the hardware by resetting the transmit and receive units, masks
2775 * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2778 s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
2780 ixgbe_link_speed link_speed;
2784 bool link_up = false;
2786 DEBUGFUNC("ixgbe_reset_hw_X550em");
2788 /* Call adapter stop to disable Tx/Rx and clear interrupts */
2789 status = hw->mac.ops.stop_adapter(hw);
2790 if (status != IXGBE_SUCCESS)
2793 /* flush pending Tx transactions */
2794 ixgbe_clear_tx_pending(hw);
2796 ixgbe_set_mdio_speed(hw);
2798 /* PHY ops must be identified and initialized prior to reset */
2799 status = hw->phy.ops.init(hw);
2801 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
2804 /* start the external PHY */
2805 if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2806 status = ixgbe_init_ext_t_x550em(hw);
2811 /* Setup SFP module if there is one present. */
2812 if (hw->phy.sfp_setup_needed) {
2813 status = hw->mac.ops.setup_sfp(hw);
2814 hw->phy.sfp_setup_needed = false;
2817 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
2821 if (!hw->phy.reset_disable && hw->phy.ops.reset)
2822 hw->phy.ops.reset(hw);
2825 /* Issue global reset to the MAC. Needs to be SW reset if link is up.
2826 * If link reset is used when link is up, it might reset the PHY when
2827 * mng is using it. If link is down or the flag to force full link
2828 * reset is set, then perform link reset.
2830 ctrl = IXGBE_CTRL_LNK_RST;
2831 if (!hw->force_full_reset) {
2832 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
2834 ctrl = IXGBE_CTRL_RST;
2837 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2838 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2839 IXGBE_WRITE_FLUSH(hw);
2841 /* Poll for reset bit to self-clear meaning reset is complete */
2842 for (i = 0; i < 10; i++) {
2844 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2845 if (!(ctrl & IXGBE_CTRL_RST_MASK))
2849 if (ctrl & IXGBE_CTRL_RST_MASK) {
2850 status = IXGBE_ERR_RESET_FAILED;
2851 DEBUGOUT("Reset polling failed to complete.\n");
2856 /* Double resets are required for recovery from certain error
2857 * conditions. Between resets, it is necessary to stall to
2858 * allow time for any pending HW events to complete.
2860 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2861 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2865 /* Store the permanent mac address */
2866 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2868 /* Store MAC address from RAR0, clear receive address registers, and
2869 * clear the multicast table. Also reset num_rar_entries to 128,
2870 * since we modify this value when programming the SAN MAC address.
2872 hw->mac.num_rar_entries = 128;
2873 hw->mac.ops.init_rx_addrs(hw);
2875 ixgbe_set_mdio_speed(hw);
2877 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2878 ixgbe_setup_mux_ctl(hw);
2884 * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2885 * @hw: pointer to hardware structure
2887 s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
2892 status = hw->phy.ops.read_reg(hw,
2893 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
2894 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2897 if (status != IXGBE_SUCCESS)
2900 /* If PHY FW reset completed bit is set then this is the first
2901 * SW instance after a power on so the PHY FW must be un-stalled.
2903 if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2904 status = hw->phy.ops.read_reg(hw,
2905 IXGBE_MDIO_GLOBAL_RES_PR_10,
2906 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2909 if (status != IXGBE_SUCCESS)
2912 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
2914 status = hw->phy.ops.write_reg(hw,
2915 IXGBE_MDIO_GLOBAL_RES_PR_10,
2916 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2919 if (status != IXGBE_SUCCESS)
2927 * ixgbe_setup_kr_x550em - Configure the KR PHY.
2928 * @hw: pointer to hardware structure
2930 * Configures the integrated KR PHY for X550EM_x.
2932 s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
2934 if (hw->mac.type != ixgbe_mac_X550EM_x)
2935 return IXGBE_SUCCESS;
2937 return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
2941 * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
2942 * @hw: pointer to hardware structure
2944 * Configure the external PHY and the integrated KR PHY for SFP support.
2946 s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
2947 ixgbe_link_speed speed,
2948 bool autoneg_wait_to_complete)
2951 u16 reg_slice, reg_val;
2952 bool setup_linear = false;
2953 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
2955 /* Check if SFP module is supported and linear */
2956 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2958 /* If no SFP module present, then return success. Return success since
2959 * there is no reason to configure CS4227 and SFP not present error is
2960 * not excepted in the setup MAC link flow.
2962 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2963 return IXGBE_SUCCESS;
2965 if (ret_val != IXGBE_SUCCESS)
2968 if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
2969 /* Configure CS4227 LINE side to 10G SR. */
2970 reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB +
2971 (hw->bus.lan_id << 12);
2972 reg_val = IXGBE_CS4227_SPEED_10G;
2973 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2976 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
2977 (hw->bus.lan_id << 12);
2978 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2979 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2982 /* Configure CS4227 for HOST connection rate then type. */
2983 reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB +
2984 (hw->bus.lan_id << 12);
2985 reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ?
2986 IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
2987 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2990 reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB +
2991 (hw->bus.lan_id << 12);
2993 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2995 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2996 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2999 /* Setup XFI internal link. */
3000 ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
3002 /* Configure internal PHY for KR/KX. */
3003 ixgbe_setup_kr_speed_x550em(hw, speed);
3005 /* Configure CS4227 LINE side to proper mode. */
3006 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
3007 (hw->bus.lan_id << 12);
3009 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
3011 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
3012 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
3019 * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
3020 * @hw: pointer to hardware structure
3021 * @speed: the link speed to force
3023 * Configures the integrated PHY for native SFI mode. Used to connect the
3024 * internal PHY directly to an SFP cage, without autonegotiation.
3026 STATIC s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
3028 struct ixgbe_mac_info *mac = &hw->mac;
3032 /* Disable all AN and force speed to 10G Serial. */
3033 status = mac->ops.read_iosf_sb_reg(hw,
3034 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
3035 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3036 if (status != IXGBE_SUCCESS)
3039 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
3040 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
3041 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
3042 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
3044 /* Select forced link speed for internal PHY. */
3046 case IXGBE_LINK_SPEED_10GB_FULL:
3047 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
3049 case IXGBE_LINK_SPEED_1GB_FULL:
3050 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
3053 /* Other link speeds are not supported by internal PHY. */
3054 return IXGBE_ERR_LINK_SETUP;
3057 status = mac->ops.write_iosf_sb_reg(hw,
3058 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
3059 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3061 /* Toggle port SW reset by AN reset. */
3062 status = ixgbe_restart_an_internal_phy_x550em(hw);
3068 * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
3069 * @hw: pointer to hardware structure
3071 * Configure the the integrated PHY for SFP support.
3073 s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
3074 ixgbe_link_speed speed,
3075 bool autoneg_wait_to_complete)
3079 bool setup_linear = false;
3080 u32 reg_slice, reg_phy_int, slice_offset;
3082 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
3084 /* Check if SFP module is supported and linear */
3085 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
3087 /* If no SFP module present, then return success. Return success since
3088 * SFP not present error is not excepted in the setup MAC link flow.
3090 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
3091 return IXGBE_SUCCESS;
3093 if (ret_val != IXGBE_SUCCESS)
3096 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
3097 /* Configure internal PHY for native SFI based on module type */
3098 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
3099 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
3100 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int);
3102 if (ret_val != IXGBE_SUCCESS)
3105 reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
3107 reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
3109 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
3110 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
3111 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
3113 if (ret_val != IXGBE_SUCCESS)
3116 /* Setup SFI internal link. */
3117 ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
3119 /* Configure internal PHY for KR/KX. */
3120 ixgbe_setup_kr_speed_x550em(hw, speed);
3122 if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
3124 DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
3125 return IXGBE_ERR_PHY_ADDR_INVALID;
3128 /* Get external PHY SKU id */
3129 ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
3130 IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
3132 if (ret_val != IXGBE_SUCCESS)
3135 /* When configuring quad port CS4223, the MAC instance is part
3136 * of the slice offset.
3138 if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
3139 slice_offset = (hw->bus.lan_id +
3140 (hw->bus.instance_id << 1)) << 12;
3142 slice_offset = hw->bus.lan_id << 12;
3144 /* Configure CS4227/CS4223 LINE side to proper mode. */
3145 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
3147 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
3149 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
3150 ret_val = hw->phy.ops.write_reg(hw, reg_slice,
3151 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
3157 * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
3158 * @hw: pointer to hardware structure
3160 * iXfI configuration needed for ixgbe_mac_X550EM_x devices.
3162 STATIC s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
3164 struct ixgbe_mac_info *mac = &hw->mac;
3168 /* Disable training protocol FSM. */
3169 status = mac->ops.read_iosf_sb_reg(hw,
3170 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3171 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3172 if (status != IXGBE_SUCCESS)
3174 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
3175 status = mac->ops.write_iosf_sb_reg(hw,
3176 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3177 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3178 if (status != IXGBE_SUCCESS)
3181 /* Disable Flex from training TXFFE. */
3182 status = mac->ops.read_iosf_sb_reg(hw,
3183 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
3184 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3185 if (status != IXGBE_SUCCESS)
3187 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
3188 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
3189 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
3190 status = mac->ops.write_iosf_sb_reg(hw,
3191 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
3192 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3193 if (status != IXGBE_SUCCESS)
3195 status = mac->ops.read_iosf_sb_reg(hw,
3196 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
3197 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3198 if (status != IXGBE_SUCCESS)
3200 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
3201 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
3202 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
3203 status = mac->ops.write_iosf_sb_reg(hw,
3204 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
3205 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3206 if (status != IXGBE_SUCCESS)
3209 /* Enable override for coefficients. */
3210 status = mac->ops.read_iosf_sb_reg(hw,
3211 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
3212 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3213 if (status != IXGBE_SUCCESS)
3215 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
3216 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
3217 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
3218 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
3219 status = mac->ops.write_iosf_sb_reg(hw,
3220 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
3221 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3226 * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
3227 * @hw: pointer to hardware structure
3228 * @speed: the link speed to force
3230 * Configures the integrated KR PHY to use iXFI mode. Used to connect an
3231 * internal and external PHY at a specific speed, without autonegotiation.
3233 STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
3235 struct ixgbe_mac_info *mac = &hw->mac;
3239 /* iXFI is only supported with X552 */
3240 if (mac->type != ixgbe_mac_X550EM_x)
3241 return IXGBE_ERR_LINK_SETUP;
3243 /* Disable AN and force speed to 10G Serial. */
3244 status = mac->ops.read_iosf_sb_reg(hw,
3245 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3246 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3247 if (status != IXGBE_SUCCESS)
3250 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
3251 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
3253 /* Select forced link speed for internal PHY. */
3255 case IXGBE_LINK_SPEED_10GB_FULL:
3256 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
3258 case IXGBE_LINK_SPEED_1GB_FULL:
3259 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
3262 /* Other link speeds are not supported by internal KR PHY. */
3263 return IXGBE_ERR_LINK_SETUP;
3266 status = mac->ops.write_iosf_sb_reg(hw,
3267 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3268 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3269 if (status != IXGBE_SUCCESS)
3272 /* Additional configuration needed for x550em_x */
3273 if (hw->mac.type == ixgbe_mac_X550EM_x) {
3274 status = ixgbe_setup_ixfi_x550em_x(hw);
3275 if (status != IXGBE_SUCCESS)
3279 /* Toggle port SW reset by AN reset. */
3280 status = ixgbe_restart_an_internal_phy_x550em(hw);
3286 * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
3287 * @hw: address of hardware structure
3288 * @link_up: address of boolean to indicate link status
3290 * Returns error code if unable to get link status.
3292 STATIC s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
3299 /* read this twice back to back to indicate current status */
3300 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
3301 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3303 if (ret != IXGBE_SUCCESS)
3306 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
3307 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3309 if (ret != IXGBE_SUCCESS)
3312 *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
3314 return IXGBE_SUCCESS;
3318 * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
3319 * @hw: point to hardware structure
3321 * Configures the link between the integrated KR PHY and the external X557 PHY
3322 * The driver will call this function when it gets a link status change
3323 * interrupt from the X557 PHY. This function configures the link speed
3324 * between the PHYs to match the link speed of the BASE-T link.
3326 * A return of a non-zero value indicates an error, and the base driver should
3327 * not report link up.
3329 s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
3331 ixgbe_link_speed force_speed;
3336 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
3337 return IXGBE_ERR_CONFIG;
3339 if (hw->mac.type == ixgbe_mac_X550EM_x &&
3340 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
3341 /* If link is down, there is no setup necessary so return */
3342 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3343 if (status != IXGBE_SUCCESS)
3347 return IXGBE_SUCCESS;
3349 status = hw->phy.ops.read_reg(hw,
3350 IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
3351 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3353 if (status != IXGBE_SUCCESS)
3356 /* If link is still down - no setup is required so return */
3357 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3358 if (status != IXGBE_SUCCESS)
3361 return IXGBE_SUCCESS;
3363 /* clear everything but the speed and duplex bits */
3364 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
3367 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
3368 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
3370 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
3371 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
3374 /* Internal PHY does not support anything else */
3375 return IXGBE_ERR_INVALID_LINK_SETTINGS;
3378 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
3380 speed = IXGBE_LINK_SPEED_10GB_FULL |
3381 IXGBE_LINK_SPEED_1GB_FULL;
3382 return ixgbe_setup_kr_speed_x550em(hw, speed);
3387 * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
3388 * @hw: pointer to hardware structure
3390 * Configures the integrated KR PHY to use internal loopback mode.
3392 s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
3397 /* Disable AN and force speed to 10G Serial. */
3398 status = hw->mac.ops.read_iosf_sb_reg(hw,
3399 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3400 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3401 if (status != IXGBE_SUCCESS)
3403 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
3404 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
3405 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
3406 status = hw->mac.ops.write_iosf_sb_reg(hw,
3407 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3408 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3409 if (status != IXGBE_SUCCESS)
3412 /* Set near-end loopback clocks. */
3413 status = hw->mac.ops.read_iosf_sb_reg(hw,
3414 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3415 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3416 if (status != IXGBE_SUCCESS)
3418 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
3419 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
3420 status = hw->mac.ops.write_iosf_sb_reg(hw,
3421 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3422 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3423 if (status != IXGBE_SUCCESS)
3426 /* Set loopback enable. */
3427 status = hw->mac.ops.read_iosf_sb_reg(hw,
3428 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3429 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3430 if (status != IXGBE_SUCCESS)
3432 reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
3433 status = hw->mac.ops.write_iosf_sb_reg(hw,
3434 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3435 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3436 if (status != IXGBE_SUCCESS)
3439 /* Training bypass. */
3440 status = hw->mac.ops.read_iosf_sb_reg(hw,
3441 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3442 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
3443 if (status != IXGBE_SUCCESS)
3445 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
3446 status = hw->mac.ops.write_iosf_sb_reg(hw,
3447 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3448 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3454 * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
3455 * assuming that the semaphore is already obtained.
3456 * @hw: pointer to hardware structure
3457 * @offset: offset of word in the EEPROM to read
3458 * @data: word read from the EEPROM
3460 * Reads a 16 bit word from the EEPROM using the hostif.
3462 s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
3464 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3465 struct ixgbe_hic_read_shadow_ram buffer;
3468 DEBUGFUNC("ixgbe_read_ee_hostif_X550");
3469 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3470 buffer.hdr.req.buf_lenh = 0;
3471 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3472 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3474 /* convert offset from words to bytes */
3475 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3477 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3479 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3483 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3484 IXGBE_HI_COMMAND_TIMEOUT);
3486 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
3487 FW_NVM_DATA_OFFSET);
3490 hw->mac.ops.release_swfw_sync(hw, mask);
3495 * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
3496 * @hw: pointer to hardware structure
3497 * @offset: offset of word in the EEPROM to read
3498 * @words: number of words
3499 * @data: word(s) read from the EEPROM
3501 * Reads a 16 bit word(s) from the EEPROM using the hostif.
3503 s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3504 u16 offset, u16 words, u16 *data)
3506 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3507 struct ixgbe_hic_read_shadow_ram buffer;
3508 u32 current_word = 0;
3513 DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
3515 /* Take semaphore for the entire operation. */
3516 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3518 DEBUGOUT("EEPROM read buffer - semaphore failed\n");
3523 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
3524 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
3526 words_to_read = words;
3528 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3529 buffer.hdr.req.buf_lenh = 0;
3530 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3531 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3533 /* convert offset from words to bytes */
3534 buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
3535 buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
3537 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3538 IXGBE_HI_COMMAND_TIMEOUT);
3541 DEBUGOUT("Host interface command failed\n");
3545 for (i = 0; i < words_to_read; i++) {
3546 u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
3548 u32 value = IXGBE_READ_REG(hw, reg);
3550 data[current_word] = (u16)(value & 0xffff);
3553 if (i < words_to_read) {
3555 data[current_word] = (u16)(value & 0xffff);
3559 words -= words_to_read;
3563 hw->mac.ops.release_swfw_sync(hw, mask);
3568 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3569 * @hw: pointer to hardware structure
3570 * @offset: offset of word in the EEPROM to write
3571 * @data: word write to the EEPROM
3573 * Write a 16 bit word to the EEPROM using the hostif.
3575 s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
3579 struct ixgbe_hic_write_shadow_ram buffer;
3581 DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
3583 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
3584 buffer.hdr.req.buf_lenh = 0;
3585 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
3586 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3589 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3591 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3593 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3595 IXGBE_HI_COMMAND_TIMEOUT, false);
3601 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3602 * @hw: pointer to hardware structure
3603 * @offset: offset of word in the EEPROM to write
3604 * @data: word write to the EEPROM
3606 * Write a 16 bit word to the EEPROM using the hostif.
3608 s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
3611 s32 status = IXGBE_SUCCESS;
3613 DEBUGFUNC("ixgbe_write_ee_hostif_X550");
3615 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
3617 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
3618 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3620 DEBUGOUT("write ee hostif failed to get semaphore");
3621 status = IXGBE_ERR_SWFW_SYNC;
3628 * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
3629 * @hw: pointer to hardware structure
3630 * @offset: offset of word in the EEPROM to write
3631 * @words: number of words
3632 * @data: word(s) write to the EEPROM
3634 * Write a 16 bit word(s) to the EEPROM using the hostif.
3636 s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3637 u16 offset, u16 words, u16 *data)
3639 s32 status = IXGBE_SUCCESS;
3642 DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
3644 /* Take semaphore for the entire operation. */
3645 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3646 if (status != IXGBE_SUCCESS) {
3647 DEBUGOUT("EEPROM write buffer - semaphore failed\n");
3651 for (i = 0; i < words; i++) {
3652 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
3655 if (status != IXGBE_SUCCESS) {
3656 DEBUGOUT("Eeprom buffered write failed\n");
3661 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3668 * ixgbe_checksum_ptr_x550 - Checksum one pointer region
3669 * @hw: pointer to hardware structure
3670 * @ptr: pointer offset in eeprom
3671 * @size: size of section pointed by ptr, if 0 first word will be used as size
3672 * @csum: address of checksum to update
3674 * Returns error status for any failure
3676 STATIC s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
3677 u16 size, u16 *csum, u16 *buffer,
3682 u16 length, bufsz, i, start;
3685 bufsz = sizeof(buf) / sizeof(buf[0]);
3687 /* Read a chunk at the pointer location */
3689 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
3691 DEBUGOUT("Failed to read EEPROM image\n");
3696 if (buffer_size < ptr)
3697 return IXGBE_ERR_PARAM;
3698 local_buffer = &buffer[ptr];
3706 length = local_buffer[0];
3708 /* Skip pointer section if length is invalid. */
3709 if (length == 0xFFFF || length == 0 ||
3710 (ptr + length) >= hw->eeprom.word_size)
3711 return IXGBE_SUCCESS;
3714 if (buffer && ((u32)start + (u32)length > buffer_size))
3715 return IXGBE_ERR_PARAM;
3717 for (i = start; length; i++, length--) {
3718 if (i == bufsz && !buffer) {
3724 /* Read a chunk at the pointer location */
3725 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
3728 DEBUGOUT("Failed to read EEPROM image\n");
3732 *csum += local_buffer[i];
3734 return IXGBE_SUCCESS;
3738 * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
3739 * @hw: pointer to hardware structure
3740 * @buffer: pointer to buffer containing calculated checksum
3741 * @buffer_size: size of buffer
3743 * Returns a negative error code on error, or the 16-bit checksum
3745 s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
3747 u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
3751 u16 pointer, i, size;
3753 DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
3755 hw->eeprom.ops.init_params(hw);
3758 /* Read pointer area */
3759 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
3760 IXGBE_EEPROM_LAST_WORD + 1,
3763 DEBUGOUT("Failed to read EEPROM image\n");
3766 local_buffer = eeprom_ptrs;
3768 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
3769 return IXGBE_ERR_PARAM;
3770 local_buffer = buffer;
3774 * For X550 hardware include 0x0-0x41 in the checksum, skip the
3775 * checksum word itself
3777 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
3778 if (i != IXGBE_EEPROM_CHECKSUM)
3779 checksum += local_buffer[i];
3782 * Include all data from pointers 0x3, 0x6-0xE. This excludes the
3783 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
3785 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
3786 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
3789 pointer = local_buffer[i];
3791 /* Skip pointer section if the pointer is invalid. */
3792 if (pointer == 0xFFFF || pointer == 0 ||
3793 pointer >= hw->eeprom.word_size)
3797 case IXGBE_PCIE_GENERAL_PTR:
3798 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
3800 case IXGBE_PCIE_CONFIG0_PTR:
3801 case IXGBE_PCIE_CONFIG1_PTR:
3802 size = IXGBE_PCIE_CONFIG_SIZE;
3809 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
3810 buffer, buffer_size);
3815 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
3817 return (s32)checksum;
3821 * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
3822 * @hw: pointer to hardware structure
3824 * Returns a negative error code on error, or the 16-bit checksum
3826 s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
3828 return ixgbe_calc_checksum_X550(hw, NULL, 0);
3832 * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
3833 * @hw: pointer to hardware structure
3834 * @checksum_val: calculated checksum
3836 * Performs checksum calculation and validates the EEPROM checksum. If the
3837 * caller does not need checksum_val, the value can be NULL.
3839 s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
3843 u16 read_checksum = 0;
3845 DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
3847 /* Read the first word from the EEPROM. If this times out or fails, do
3848 * not continue or we could be in for a very long wait while every
3851 status = hw->eeprom.ops.read(hw, 0, &checksum);
3853 DEBUGOUT("EEPROM read failed\n");
3857 status = hw->eeprom.ops.calc_checksum(hw);
3861 checksum = (u16)(status & 0xffff);
3863 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3868 /* Verify read checksum from EEPROM is the same as
3869 * calculated checksum
3871 if (read_checksum != checksum) {
3872 status = IXGBE_ERR_EEPROM_CHECKSUM;
3873 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
3874 "Invalid EEPROM checksum");
3877 /* If the user cares, return the calculated checksum */
3879 *checksum_val = checksum;
3885 * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
3886 * @hw: pointer to hardware structure
3888 * After writing EEPROM to shadow RAM using EEWR register, software calculates
3889 * checksum and updates the EEPROM and instructs the hardware to update
3892 s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
3897 DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
3899 /* Read the first word from the EEPROM. If this times out or fails, do
3900 * not continue or we could be in for a very long wait while every
3903 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
3905 DEBUGOUT("EEPROM read failed\n");
3909 status = ixgbe_calc_eeprom_checksum_X550(hw);
3913 checksum = (u16)(status & 0xffff);
3915 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3920 status = ixgbe_update_flash_X550(hw);
3926 * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
3927 * @hw: pointer to hardware structure
3929 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
3931 s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
3933 s32 status = IXGBE_SUCCESS;
3934 union ixgbe_hic_hdr2 buffer;
3936 DEBUGFUNC("ixgbe_update_flash_X550");
3938 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
3939 buffer.req.buf_lenh = 0;
3940 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
3941 buffer.req.checksum = FW_DEFAULT_CHECKSUM;
3943 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3945 IXGBE_HI_COMMAND_TIMEOUT, false);
3951 * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
3952 * @hw: pointer to hardware structure
3954 * Determines physical layer capabilities of the current configuration.
3956 u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
3958 u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
3959 u16 ext_ability = 0;
3961 DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
3963 hw->phy.ops.identify(hw);
3965 switch (hw->phy.type) {
3966 case ixgbe_phy_x550em_kr:
3967 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
3968 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3970 case ixgbe_phy_x550em_kx4:
3971 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
3972 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3974 case ixgbe_phy_x550em_ext_t:
3975 hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
3976 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
3978 if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
3979 physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
3980 if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
3981 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3984 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
3989 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
3990 physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
3992 return physical_layer;
3996 * ixgbe_get_bus_info_x550em - Set PCI bus info
3997 * @hw: pointer to hardware structure
3999 * Sets bus link width and speed to unknown because X550em is
4002 s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
4005 DEBUGFUNC("ixgbe_get_bus_info_x550em");
4007 hw->bus.width = ixgbe_bus_width_unknown;
4008 hw->bus.speed = ixgbe_bus_speed_unknown;
4010 hw->mac.ops.set_lan_id(hw);
4012 return IXGBE_SUCCESS;
4016 * ixgbe_disable_rx_x550 - Disable RX unit
4018 * Enables the Rx DMA unit for x550
4020 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
4022 u32 rxctrl, pfdtxgswc;
4024 struct ixgbe_hic_disable_rxen fw_cmd;
4026 DEBUGFUNC("ixgbe_enable_rx_dma_x550");
4028 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
4029 if (rxctrl & IXGBE_RXCTRL_RXEN) {
4030 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
4031 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
4032 pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
4033 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
4034 hw->mac.set_lben = true;
4036 hw->mac.set_lben = false;
4039 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
4040 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
4041 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
4042 fw_cmd.port_number = (u8)hw->bus.lan_id;
4044 status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
4045 sizeof(struct ixgbe_hic_disable_rxen),
4046 IXGBE_HI_COMMAND_TIMEOUT, true);
4048 /* If we fail - disable RX using register write */
4050 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
4051 if (rxctrl & IXGBE_RXCTRL_RXEN) {
4052 rxctrl &= ~IXGBE_RXCTRL_RXEN;
4053 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
4060 * ixgbe_enter_lplu_x550em - Transition to low power states
4061 * @hw: pointer to hardware structure
4063 * Configures Low Power Link Up on transition to low power states
4064 * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
4065 * X557 PHY immediately prior to entering LPLU.
4067 s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
4069 u16 an_10g_cntl_reg, autoneg_reg, speed;
4071 ixgbe_link_speed lcd_speed;
4075 /* SW LPLU not required on later HW revisions. */
4076 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
4077 (IXGBE_FUSES0_REV_MASK &
4078 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
4079 return IXGBE_SUCCESS;
4081 /* If blocked by MNG FW, then don't restart AN */
4082 if (ixgbe_check_reset_blocked(hw))
4083 return IXGBE_SUCCESS;
4085 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
4086 if (status != IXGBE_SUCCESS)
4089 status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
4091 if (status != IXGBE_SUCCESS)
4094 /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
4095 * disabled, then force link down by entering low power mode.
4097 if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
4098 !(hw->wol_enabled || ixgbe_mng_present(hw)))
4099 return ixgbe_set_copper_phy_power(hw, FALSE);
4102 status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
4104 if (status != IXGBE_SUCCESS)
4107 /* If no valid LCD link speed, then force link down and exit. */
4108 if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
4109 return ixgbe_set_copper_phy_power(hw, FALSE);
4111 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
4112 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4115 if (status != IXGBE_SUCCESS)
4118 /* If no link now, speed is invalid so take link down */
4119 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
4120 if (status != IXGBE_SUCCESS)
4121 return ixgbe_set_copper_phy_power(hw, false);
4123 /* clear everything but the speed bits */
4124 speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
4126 /* If current speed is already LCD, then exit. */
4127 if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
4128 (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
4129 ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
4130 (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
4133 /* Clear AN completed indication */
4134 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
4135 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4138 if (status != IXGBE_SUCCESS)
4141 status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
4142 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4145 if (status != IXGBE_SUCCESS)
4148 status = hw->phy.ops.read_reg(hw,
4149 IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
4150 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4153 if (status != IXGBE_SUCCESS)
4156 save_autoneg = hw->phy.autoneg_advertised;
4158 /* Setup link at least common link speed */
4159 status = hw->mac.ops.setup_link(hw, lcd_speed, false);
4161 /* restore autoneg from before setting lplu speed */
4162 hw->phy.autoneg_advertised = save_autoneg;
4168 * ixgbe_get_lcd_x550em - Determine lowest common denominator
4169 * @hw: pointer to hardware structure
4170 * @lcd_speed: pointer to lowest common link speed
4172 * Determine lowest common link speed with link partner.
4174 s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
4178 u16 word = hw->eeprom.ctrl_word_3;
4180 *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
4182 status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
4183 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4186 if (status != IXGBE_SUCCESS)
4189 /* If link partner advertised 1G, return 1G */
4190 if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
4191 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
4195 /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
4196 if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
4197 (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
4200 /* Link partner not capable of lower speeds, return 10G */
4201 *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
4206 * ixgbe_setup_fc_X550em - Set up flow control
4207 * @hw: pointer to hardware structure
4209 * Called at init time to set up flow control.
4211 s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
4213 s32 ret_val = IXGBE_SUCCESS;
4214 u32 pause, asm_dir, reg_val;
4216 DEBUGFUNC("ixgbe_setup_fc_X550em");
4218 /* Validate the requested mode */
4219 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
4220 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4221 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
4222 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
4226 /* 10gig parts do not have a word in the EEPROM to determine the
4227 * default flow control setting, so we explicitly set it to full.
4229 if (hw->fc.requested_mode == ixgbe_fc_default)
4230 hw->fc.requested_mode = ixgbe_fc_full;
4232 /* Determine PAUSE and ASM_DIR bits. */
4233 switch (hw->fc.requested_mode) {
4238 case ixgbe_fc_tx_pause:
4242 case ixgbe_fc_rx_pause:
4243 /* Rx Flow control is enabled and Tx Flow control is
4244 * disabled by software override. Since there really
4245 * isn't a way to advertise that we are capable of RX
4246 * Pause ONLY, we will advertise that we support both
4247 * symmetric and asymmetric Rx PAUSE, as such we fall
4248 * through to the fc_full statement. Later, we will
4249 * disable the adapter's ability to send PAUSE frames.
4256 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
4257 "Flow control param set incorrectly\n");
4258 ret_val = IXGBE_ERR_CONFIG;
4262 switch (hw->device_id) {
4263 case IXGBE_DEV_ID_X550EM_X_KR:
4264 case IXGBE_DEV_ID_X550EM_A_KR:
4265 case IXGBE_DEV_ID_X550EM_A_KR_L:
4266 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
4267 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4268 IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
4269 if (ret_val != IXGBE_SUCCESS)
4271 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4272 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
4274 reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
4276 reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4277 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
4278 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4279 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
4281 /* This device does not fully support AN. */
4282 hw->fc.disable_fc_autoneg = true;
4293 * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
4294 * @hw: pointer to hardware structure
4296 * Enable flow control according to IEEE clause 37.
4298 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
4300 u32 link_s1, lp_an_page_low, an_cntl_1;
4301 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4302 ixgbe_link_speed speed;
4305 /* AN should have completed when the cable was plugged in.
4306 * Look for reasons to bail out. Bail out if:
4307 * - FC autoneg is disabled, or if
4310 if (hw->fc.disable_fc_autoneg) {
4311 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4312 "Flow control autoneg is disabled");
4316 hw->mac.ops.check_link(hw, &speed, &link_up, false);
4318 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4322 /* Check at auto-negotiation has completed */
4323 status = hw->mac.ops.read_iosf_sb_reg(hw,
4324 IXGBE_KRM_LINK_S1(hw->bus.lan_id),
4325 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
4327 if (status != IXGBE_SUCCESS ||
4328 (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
4329 DEBUGOUT("Auto-Negotiation did not complete\n");
4330 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4334 /* Read the 10g AN autoc and LP ability registers and resolve
4335 * local flow control settings accordingly
4337 status = hw->mac.ops.read_iosf_sb_reg(hw,
4338 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4339 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
4341 if (status != IXGBE_SUCCESS) {
4342 DEBUGOUT("Auto-Negotiation did not complete\n");
4346 status = hw->mac.ops.read_iosf_sb_reg(hw,
4347 IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
4348 IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
4350 if (status != IXGBE_SUCCESS) {
4351 DEBUGOUT("Auto-Negotiation did not complete\n");
4355 status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
4356 IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
4357 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
4358 IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
4359 IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
4362 if (status == IXGBE_SUCCESS) {
4363 hw->fc.fc_was_autonegged = true;
4365 hw->fc.fc_was_autonegged = false;
4366 hw->fc.current_mode = hw->fc.requested_mode;
4371 * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
4372 * @hw: pointer to hardware structure
4375 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
4377 hw->fc.fc_was_autonegged = false;
4378 hw->fc.current_mode = hw->fc.requested_mode;
4382 * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
4383 * @hw: pointer to hardware structure
4385 * Enable flow control according to IEEE clause 37.
4387 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
4389 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4390 u16 reg, pcs_an_lp, pcs_an;
4391 ixgbe_link_speed speed;
4394 /* AN should have completed when the cable was plugged in.
4395 * Look for reasons to bail out. Bail out if:
4396 * - FC autoneg is disabled, or if
4399 if (hw->fc.disable_fc_autoneg) {
4400 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4401 "Flow control autoneg is disabled");
4405 hw->mac.ops.check_link(hw, &speed, &link_up, false);
4407 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4411 /* Check if auto-negotiation has completed */
4412 status = hw->phy.ops.read_reg(hw, IXGBE_M88E1500_COPPER_STATUS,
4413 IXGBE_MDIO_ZERO_DEV_TYPE, ®);
4414 if (status != IXGBE_SUCCESS ||
4415 (reg & IXGBE_M88E1500_COPPER_STATUS_AN_DONE) == 0) {
4416 DEBUGOUT("Auto-Negotiation did not complete\n");
4417 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4421 /* Get the advertized flow control */
4422 status = hw->phy.ops.read_reg(hw, IXGBE_M88E1500_COPPER_AN,
4423 IXGBE_MDIO_ZERO_DEV_TYPE, &pcs_an);
4424 if (status != IXGBE_SUCCESS)
4427 /* Get link partner's flow control */
4428 status = hw->phy.ops.read_reg(hw,
4429 IXGBE_M88E1500_COPPER_AN_LP_ABILITY,
4430 IXGBE_MDIO_ZERO_DEV_TYPE, &pcs_an_lp);
4431 if (status != IXGBE_SUCCESS)
4434 /* Negotiate the flow control */
4435 status = ixgbe_negotiate_fc(hw, (u32)pcs_an, (u32)pcs_an_lp,
4436 IXGBE_M88E1500_COPPER_AN_PAUSE,
4437 IXGBE_M88E1500_COPPER_AN_AS_PAUSE,
4438 IXGBE_M88E1500_COPPER_AN_LP_PAUSE,
4439 IXGBE_M88E1500_COPPER_AN_LP_AS_PAUSE);
4442 if (status == IXGBE_SUCCESS) {
4443 hw->fc.fc_was_autonegged = true;
4445 hw->fc.fc_was_autonegged = false;
4446 hw->fc.current_mode = hw->fc.requested_mode;
4451 * ixgbe_setup_fc_sgmii_x550em_a - Set up flow control
4452 * @hw: pointer to hardware structure
4454 * Called at init time to set up flow control.
4456 s32 ixgbe_setup_fc_sgmii_x550em_a(struct ixgbe_hw *hw)
4461 /* Validate the requested mode */
4462 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
4463 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4464 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
4465 return IXGBE_ERR_INVALID_LINK_SETTINGS;
4468 if (hw->fc.requested_mode == ixgbe_fc_default)
4469 hw->fc.requested_mode = ixgbe_fc_full;
4471 /* Read contents of the Auto-Negotiation register, page 0 reg 4 */
4472 rc = hw->phy.ops.read_reg(hw, IXGBE_M88E1500_COPPER_AN,
4473 IXGBE_MDIO_ZERO_DEV_TYPE, ®);
4477 /* Disable all the settings related to Flow control Auto-negotiation */
4478 reg &= ~IXGBE_M88E1500_COPPER_AN_AS_PAUSE;
4479 reg &= ~IXGBE_M88E1500_COPPER_AN_PAUSE;
4481 /* Configure the Asymmetric and symmetric pause according to the user
4484 switch (hw->fc.requested_mode) {
4486 reg |= IXGBE_M88E1500_COPPER_AN_PAUSE;
4487 reg |= IXGBE_M88E1500_COPPER_AN_AS_PAUSE;
4489 case ixgbe_fc_rx_pause:
4490 reg |= IXGBE_M88E1500_COPPER_AN_PAUSE;
4491 reg |= IXGBE_M88E1500_COPPER_AN_AS_PAUSE;
4493 case ixgbe_fc_tx_pause:
4494 reg |= IXGBE_M88E1500_COPPER_AN_AS_PAUSE;
4500 /* Write back to the Auto-Negotiation register with newly configured
4503 hw->phy.ops.write_reg(hw, IXGBE_M88E1500_COPPER_AN,
4504 IXGBE_MDIO_ZERO_DEV_TYPE, reg);
4506 /* In this section of the code we restart Auto-negotiation */
4508 /* Read the CONTROL register, Page 0 reg 0 */
4509 rc = hw->phy.ops.read_reg(hw, IXGBE_M88E1500_COPPER_CTRL,
4510 IXGBE_MDIO_ZERO_DEV_TYPE, ®);
4514 /* Set the bit to restart Auto-Neg. The bit to enable Auto-neg is ON
4517 reg |= IXGBE_M88E1500_COPPER_CTRL_RESTART_AN;
4519 /* write the new values to the register to restart Auto-Negotiation */
4520 hw->phy.ops.write_reg(hw, IXGBE_M88E1500_COPPER_CTRL,
4521 IXGBE_MDIO_ZERO_DEV_TYPE, reg);
4528 * ixgbe_setup_fc_backplane_x550em_a - Set up flow control
4529 * @hw: pointer to hardware structure
4531 * Called at init time to set up flow control.
4533 s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
4535 s32 status = IXGBE_SUCCESS;
4538 DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
4540 /* Validate the requested mode */
4541 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
4542 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4543 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
4544 return IXGBE_ERR_INVALID_LINK_SETTINGS;
4547 if (hw->fc.requested_mode == ixgbe_fc_default)
4548 hw->fc.requested_mode = ixgbe_fc_full;
4550 /* Set up the 1G and 10G flow control advertisement registers so the
4551 * HW will be able to do FC autoneg once the cable is plugged in. If
4552 * we link at 10G, the 1G advertisement is harmless and vice versa.
4554 status = hw->mac.ops.read_iosf_sb_reg(hw,
4555 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4556 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
4558 if (status != IXGBE_SUCCESS) {
4559 DEBUGOUT("Auto-Negotiation did not complete\n");
4563 /* The possible values of fc.requested_mode are:
4564 * 0: Flow control is completely disabled
4565 * 1: Rx flow control is enabled (we can receive pause frames,
4566 * but not send pause frames).
4567 * 2: Tx flow control is enabled (we can send pause frames but
4568 * we do not support receiving pause frames).
4569 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4572 switch (hw->fc.requested_mode) {
4574 /* Flow control completely disabled by software override. */
4575 an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4576 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
4578 case ixgbe_fc_tx_pause:
4579 /* Tx Flow control is enabled, and Rx Flow control is
4580 * disabled by software override.
4582 an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4583 an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
4585 case ixgbe_fc_rx_pause:
4586 /* Rx Flow control is enabled and Tx Flow control is
4587 * disabled by software override. Since there really
4588 * isn't a way to advertise that we are capable of RX
4589 * Pause ONLY, we will advertise that we support both
4590 * symmetric and asymmetric Rx PAUSE, as such we fall
4591 * through to the fc_full statement. Later, we will
4592 * disable the adapter's ability to send PAUSE frames.
4595 /* Flow control (both Rx and Tx) is enabled by SW override. */
4596 an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4597 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4600 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
4601 "Flow control param set incorrectly\n");
4602 return IXGBE_ERR_CONFIG;
4605 status = hw->mac.ops.write_iosf_sb_reg(hw,
4606 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4607 IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
4609 /* Restart auto-negotiation. */
4610 status = ixgbe_restart_an_internal_phy_x550em(hw);
4616 * ixgbe_set_mux - Set mux for port 1 access with CS4227
4617 * @hw: pointer to hardware structure
4618 * @state: set mux if 1, clear if 0
4620 STATIC void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
4624 if (!hw->bus.lan_id)
4626 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4628 esdp |= IXGBE_ESDP_SDP1;
4630 esdp &= ~IXGBE_ESDP_SDP1;
4631 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4632 IXGBE_WRITE_FLUSH(hw);
4636 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
4637 * @hw: pointer to hardware structure
4638 * @mask: Mask to specify which semaphore to acquire
4640 * Acquires the SWFW semaphore and sets the I2C MUX
4642 s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4646 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
4648 status = ixgbe_acquire_swfw_sync_X540(hw, mask);
4652 if (mask & IXGBE_GSSR_I2C_MASK)
4653 ixgbe_set_mux(hw, 1);
4655 return IXGBE_SUCCESS;
4659 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
4660 * @hw: pointer to hardware structure
4661 * @mask: Mask to specify which semaphore to release
4663 * Releases the SWFW semaphore and sets the I2C MUX
4665 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4667 DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
4669 if (mask & IXGBE_GSSR_I2C_MASK)
4670 ixgbe_set_mux(hw, 0);
4672 ixgbe_release_swfw_sync_X540(hw, mask);
4676 * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
4677 * @hw: pointer to hardware structure
4678 * @mask: Mask to specify which semaphore to acquire
4680 * Acquires the SWFW semaphore and get the shared phy token as needed
4682 STATIC s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4684 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4685 int retries = FW_PHY_TOKEN_RETRIES;
4686 s32 status = IXGBE_SUCCESS;
4688 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
4691 status = IXGBE_SUCCESS;
4693 status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
4696 if (!(mask & IXGBE_GSSR_TOKEN_SM))
4697 return IXGBE_SUCCESS;
4699 status = ixgbe_get_phy_token(hw);
4700 if (status == IXGBE_SUCCESS)
4701 return IXGBE_SUCCESS;
4704 ixgbe_release_swfw_sync_X540(hw, hmask);
4705 if (status != IXGBE_ERR_TOKEN_RETRY)
4713 * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
4714 * @hw: pointer to hardware structure
4715 * @mask: Mask to specify which semaphore to release
4717 * Releases the SWFW semaphore and puts the shared phy token as needed
4719 STATIC void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4721 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4723 DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
4725 if (mask & IXGBE_GSSR_TOKEN_SM)
4726 ixgbe_put_phy_token(hw);
4729 ixgbe_release_swfw_sync_X540(hw, hmask);
4733 * ixgbe_read_phy_reg_x550a - Reads specified PHY register
4734 * @hw: pointer to hardware structure
4735 * @reg_addr: 32 bit address of PHY register to read
4736 * @phy_data: Pointer to read data from PHY register
4738 * Reads a value from a specified PHY register using the SWFW lock and PHY
4739 * Token. The PHY Token is needed since the MDIO is shared between to MAC
4742 s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4743 u32 device_type, u16 *phy_data)
4746 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4748 DEBUGFUNC("ixgbe_read_phy_reg_x550a");
4750 if (hw->mac.ops.acquire_swfw_sync(hw, mask))
4751 return IXGBE_ERR_SWFW_SYNC;
4753 status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
4755 hw->mac.ops.release_swfw_sync(hw, mask);
4761 * ixgbe_write_phy_reg_x550a - Writes specified PHY register
4762 * @hw: pointer to hardware structure
4763 * @reg_addr: 32 bit PHY register to write
4764 * @device_type: 5 bit device type
4765 * @phy_data: Data to write to the PHY register
4767 * Writes a value to specified PHY register using the SWFW lock and PHY Token.
4768 * The PHY Token is needed since the MDIO is shared between to MAC instances.
4770 s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4771 u32 device_type, u16 phy_data)
4774 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4776 DEBUGFUNC("ixgbe_write_phy_reg_x550a");
4778 if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) {
4779 status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
4781 hw->mac.ops.release_swfw_sync(hw, mask);
4783 status = IXGBE_ERR_SWFW_SYNC;
4790 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
4791 * @hw: pointer to hardware structure
4793 * Handle external Base T PHY interrupt. If high temperature
4794 * failure alarm then return error, else if link status change
4795 * then setup internal/external PHY link
4797 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
4798 * failure alarm, else return PHY access status.
4800 s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
4805 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
4807 if (status != IXGBE_SUCCESS)
4811 return ixgbe_setup_internal_phy(hw);
4813 return IXGBE_SUCCESS;
4817 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
4818 * @hw: pointer to hardware structure
4819 * @speed: new link speed
4820 * @autoneg_wait_to_complete: true when waiting for completion is needed
4822 * Setup internal/external PHY link speed based on link speed, then set
4823 * external PHY auto advertised link speed.
4825 * Returns error status for any failure
4827 s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
4828 ixgbe_link_speed speed,
4829 bool autoneg_wait_to_complete)
4832 ixgbe_link_speed force_speed;
4834 DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
4836 /* Setup internal/external PHY link speed to iXFI (10G), unless
4837 * only 1G is auto advertised then setup KX link.
4839 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
4840 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
4842 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
4844 /* If X552 and internal link mode is XFI, then setup XFI internal link.
4846 if (hw->mac.type == ixgbe_mac_X550EM_x &&
4847 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
4848 status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
4850 if (status != IXGBE_SUCCESS)
4854 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
4858 * ixgbe_check_link_t_X550em - Determine link and speed status
4859 * @hw: pointer to hardware structure
4860 * @speed: pointer to link speed
4861 * @link_up: true when link is up
4862 * @link_up_wait_to_complete: bool used to wait for link up or not
4864 * Check that both the MAC and X557 external PHY have link.
4866 s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
4867 bool *link_up, bool link_up_wait_to_complete)
4870 u16 i, autoneg_status = 0;
4872 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
4873 return IXGBE_ERR_CONFIG;
4875 status = ixgbe_check_mac_link_generic(hw, speed, link_up,
4876 link_up_wait_to_complete);
4878 /* If check link fails or MAC link is not up, then return */
4879 if (status != IXGBE_SUCCESS || !(*link_up))
4882 /* MAC link is up, so check external PHY link.
4883 * X557 PHY. Link status is latching low, and can only be used to detect
4884 * link drop, and not the current status of the link without performing
4885 * back-to-back reads.
4887 for (i = 0; i < 2; i++) {
4888 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
4889 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4892 if (status != IXGBE_SUCCESS)
4896 /* If external PHY link is not up, then indicate link not up */
4897 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
4900 return IXGBE_SUCCESS;
4904 * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
4905 * @hw: pointer to hardware structure
4907 s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
4911 status = ixgbe_reset_phy_generic(hw);
4913 if (status != IXGBE_SUCCESS)
4916 /* Configure Link Status Alarm and Temperature Threshold interrupts */
4917 return ixgbe_enable_lasi_ext_t_x550em(hw);
4921 * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
4922 * @hw: pointer to hardware structure
4923 * @led_idx: led number to turn on
4925 s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4929 DEBUGFUNC("ixgbe_led_on_t_X550em");
4931 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4932 return IXGBE_ERR_PARAM;
4934 /* To turn on the LED, set mode to ON. */
4935 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4936 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4937 phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
4938 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4939 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4941 return IXGBE_SUCCESS;
4945 * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
4946 * @hw: pointer to hardware structure
4947 * @led_idx: led number to turn off
4949 s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4953 DEBUGFUNC("ixgbe_led_off_t_X550em");
4955 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4956 return IXGBE_ERR_PARAM;
4958 /* To turn on the LED, set mode to ON. */
4959 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4960 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4961 phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
4962 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4963 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4965 return IXGBE_SUCCESS;
4969 * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
4970 * @hw: pointer to the HW structure
4971 * @maj: driver version major number
4972 * @min: driver version minor number
4973 * @build: driver version build number
4974 * @sub: driver version sub build number
4975 * @len: length of driver_ver string
4976 * @driver_ver: driver string
4978 * Sends driver version number to firmware through the manageability
4979 * block. On success return IXGBE_SUCCESS
4980 * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
4981 * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
4983 s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
4984 u8 build, u8 sub, u16 len, const char *driver_ver)
4986 struct ixgbe_hic_drv_info2 fw_cmd;
4987 s32 ret_val = IXGBE_SUCCESS;
4990 DEBUGFUNC("ixgbe_set_fw_drv_ver_x550");
4992 if ((len == 0) || (driver_ver == NULL) ||
4993 (len > sizeof(fw_cmd.driver_string)))
4994 return IXGBE_ERR_INVALID_ARGUMENT;
4996 fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
4997 fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
4998 fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
4999 fw_cmd.port_num = (u8)hw->bus.func;
5000 fw_cmd.ver_maj = maj;
5001 fw_cmd.ver_min = min;
5002 fw_cmd.ver_build = build;
5003 fw_cmd.ver_sub = sub;
5004 fw_cmd.hdr.checksum = 0;
5005 memcpy(fw_cmd.driver_string, driver_ver, len);
5006 fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
5007 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
5009 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
5010 ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
5012 IXGBE_HI_COMMAND_TIMEOUT,
5014 if (ret_val != IXGBE_SUCCESS)
5017 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
5018 FW_CEM_RESP_STATUS_SUCCESS)
5019 ret_val = IXGBE_SUCCESS;
5021 ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;