syscons - Fix NULL pointer access in 0d7c8a4d1cafae68239
[dragonfly.git] / sys / dev / netif / ix / ixgbe_x550.c
blob3b87589e947ae201d0e36fb053d457a9d897ad8d
1 /******************************************************************************
3 Copyright (c) 2001-2017, Intel Corporation
4 All rights reserved.
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 ******************************************************************************/
33 /*$FreeBSD$*/
35 #include "ixgbe_x550.h"
36 #include "ixgbe_x540.h"
37 #include "ixgbe_type.h"
38 #include "ixgbe_api.h"
39 #include "ixgbe_common.h"
40 #include "ixgbe_phy.h"
42 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
43 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
44 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
45 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
47 /**
48 * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
49 * @hw: pointer to hardware structure
51 * Initialize the function pointers and assign the MAC type for X550.
52 * Does not touch the hardware.
53 **/
54 s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
56 struct ixgbe_mac_info *mac = &hw->mac;
57 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
58 s32 ret_val;
60 DEBUGFUNC("ixgbe_init_ops_X550");
62 ret_val = ixgbe_init_ops_X540(hw);
63 mac->ops.dmac_config = ixgbe_dmac_config_X550;
64 mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
65 mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
66 mac->ops.setup_eee = NULL;
67 mac->ops.set_source_address_pruning =
68 ixgbe_set_source_address_pruning_X550;
69 mac->ops.set_ethertype_anti_spoofing =
70 ixgbe_set_ethertype_anti_spoofing_X550;
72 mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
73 eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
74 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
75 eeprom->ops.read = ixgbe_read_ee_hostif_X550;
76 eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
77 eeprom->ops.write = ixgbe_write_ee_hostif_X550;
78 eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
79 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
80 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
82 mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
83 mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
84 mac->ops.mdd_event = ixgbe_mdd_event_X550;
85 mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
86 mac->ops.disable_rx = ixgbe_disable_rx_x550;
87 /* Manageability interface */
88 mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550;
89 switch (hw->device_id) {
90 case IXGBE_DEV_ID_X550EM_X_1G_T:
91 hw->mac.ops.led_on = NULL;
92 hw->mac.ops.led_off = NULL;
93 break;
94 case IXGBE_DEV_ID_X550EM_X_10G_T:
95 case IXGBE_DEV_ID_X550EM_A_10G_T:
96 hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
97 hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
98 break;
99 default:
100 break;
102 return ret_val;
106 * ixgbe_read_cs4227 - Read CS4227 register
107 * @hw: pointer to hardware structure
108 * @reg: register number to write
109 * @value: pointer to receive value read
111 * Returns status code
113 static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
115 return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
119 * ixgbe_write_cs4227 - Write CS4227 register
120 * @hw: pointer to hardware structure
121 * @reg: register number to write
122 * @value: value to write to register
124 * Returns status code
126 static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
128 return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
132 * ixgbe_read_pe - Read register from port expander
133 * @hw: pointer to hardware structure
134 * @reg: register number to read
135 * @value: pointer to receive read value
137 * Returns status code
139 static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
141 s32 status;
143 status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
144 if (status != IXGBE_SUCCESS)
145 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
146 "port expander access failed with %d\n", status);
147 return status;
151 * ixgbe_write_pe - Write register to port expander
152 * @hw: pointer to hardware structure
153 * @reg: register number to write
154 * @value: value to write
156 * Returns status code
158 static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
160 s32 status;
162 status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
163 if (status != IXGBE_SUCCESS)
164 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
165 "port expander access failed with %d\n", status);
166 return status;
170 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
171 * @hw: pointer to hardware structure
173 * This function assumes that the caller has acquired the proper semaphore.
174 * Returns error code
176 static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
178 s32 status;
179 u32 retry;
180 u16 value;
181 u8 reg;
183 /* Trigger hard reset. */
184 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
185 if (status != IXGBE_SUCCESS)
186 return status;
187 reg |= IXGBE_PE_BIT1;
188 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
189 if (status != IXGBE_SUCCESS)
190 return status;
192 status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
193 if (status != IXGBE_SUCCESS)
194 return status;
195 reg &= ~IXGBE_PE_BIT1;
196 status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
197 if (status != IXGBE_SUCCESS)
198 return status;
200 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
201 if (status != IXGBE_SUCCESS)
202 return status;
203 reg &= ~IXGBE_PE_BIT1;
204 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
205 if (status != IXGBE_SUCCESS)
206 return status;
208 usec_delay(IXGBE_CS4227_RESET_HOLD);
210 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
211 if (status != IXGBE_SUCCESS)
212 return status;
213 reg |= IXGBE_PE_BIT1;
214 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
215 if (status != IXGBE_SUCCESS)
216 return status;
218 /* Wait for the reset to complete. */
219 msec_delay(IXGBE_CS4227_RESET_DELAY);
220 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
221 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
222 &value);
223 if (status == IXGBE_SUCCESS &&
224 value == IXGBE_CS4227_EEPROM_LOAD_OK)
225 break;
226 msec_delay(IXGBE_CS4227_CHECK_DELAY);
228 if (retry == IXGBE_CS4227_RETRIES) {
229 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
230 "CS4227 reset did not complete.");
231 return IXGBE_ERR_PHY;
234 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
235 if (status != IXGBE_SUCCESS ||
236 !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
237 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
238 "CS4227 EEPROM did not load successfully.");
239 return IXGBE_ERR_PHY;
242 return IXGBE_SUCCESS;
246 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
247 * @hw: pointer to hardware structure
249 static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
251 s32 status = IXGBE_SUCCESS;
252 u32 swfw_mask = hw->phy.phy_semaphore_mask;
253 u16 value = 0;
254 u8 retry;
256 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
257 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
258 if (status != IXGBE_SUCCESS) {
259 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
260 "semaphore failed with %d", status);
261 msec_delay(IXGBE_CS4227_CHECK_DELAY);
262 continue;
265 /* Get status of reset flow. */
266 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
268 if (status == IXGBE_SUCCESS &&
269 value == IXGBE_CS4227_RESET_COMPLETE)
270 goto out;
272 if (status != IXGBE_SUCCESS ||
273 value != IXGBE_CS4227_RESET_PENDING)
274 break;
276 /* Reset is pending. Wait and check again. */
277 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
278 msec_delay(IXGBE_CS4227_CHECK_DELAY);
281 /* If still pending, assume other instance failed. */
282 if (retry == IXGBE_CS4227_RETRIES) {
283 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
284 if (status != IXGBE_SUCCESS) {
285 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
286 "semaphore failed with %d", status);
287 return;
291 /* Reset the CS4227. */
292 status = ixgbe_reset_cs4227(hw);
293 if (status != IXGBE_SUCCESS) {
294 ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
295 "CS4227 reset failed: %d", status);
296 goto out;
299 /* Reset takes so long, temporarily release semaphore in case the
300 * other driver instance is waiting for the reset indication.
302 ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
303 IXGBE_CS4227_RESET_PENDING);
304 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
305 msec_delay(10);
306 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
307 if (status != IXGBE_SUCCESS) {
308 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
309 "semaphore failed with %d", status);
310 return;
313 /* Record completion for next time. */
314 status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
315 IXGBE_CS4227_RESET_COMPLETE);
317 out:
318 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
319 msec_delay(hw->eeprom.semaphore_delay);
323 * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
324 * @hw: pointer to hardware structure
326 static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
328 u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
330 if (hw->bus.lan_id) {
331 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
332 esdp |= IXGBE_ESDP_SDP1_DIR;
334 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
335 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
336 IXGBE_WRITE_FLUSH(hw);
340 * ixgbe_identify_phy_x550em - Get PHY type based on device id
341 * @hw: pointer to hardware structure
343 * Returns error code
345 static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
347 hw->mac.ops.set_lan_id(hw);
349 ixgbe_read_mng_if_sel_x550em(hw);
351 switch (hw->device_id) {
352 case IXGBE_DEV_ID_X550EM_A_SFP:
353 return ixgbe_identify_module_generic(hw);
354 case IXGBE_DEV_ID_X550EM_X_SFP:
355 /* set up for CS4227 usage */
356 ixgbe_setup_mux_ctl(hw);
357 ixgbe_check_cs4227(hw);
358 /* Fallthrough */
360 case IXGBE_DEV_ID_X550EM_A_SFP_N:
361 return ixgbe_identify_module_generic(hw);
362 break;
363 case IXGBE_DEV_ID_X550EM_X_KX4:
364 hw->phy.type = ixgbe_phy_x550em_kx4;
365 break;
366 case IXGBE_DEV_ID_X550EM_X_XFI:
367 hw->phy.type = ixgbe_phy_x550em_xfi;
368 break;
369 case IXGBE_DEV_ID_X550EM_X_KR:
370 case IXGBE_DEV_ID_X550EM_A_KR:
371 case IXGBE_DEV_ID_X550EM_A_KR_L:
372 hw->phy.type = ixgbe_phy_x550em_kr;
373 break;
374 case IXGBE_DEV_ID_X550EM_A_10G_T:
375 case IXGBE_DEV_ID_X550EM_X_10G_T:
376 return ixgbe_identify_phy_generic(hw);
377 case IXGBE_DEV_ID_X550EM_X_1G_T:
378 hw->phy.type = ixgbe_phy_ext_1g_t;
379 break;
380 case IXGBE_DEV_ID_X550EM_A_1G_T:
381 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
382 hw->phy.type = ixgbe_phy_fw;
383 if (hw->bus.lan_id)
384 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
385 else
386 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
387 break;
388 default:
389 break;
391 return IXGBE_SUCCESS;
395 * ixgbe_fw_phy_activity - Perform an activity on a PHY
396 * @hw: pointer to hardware structure
397 * @activity: activity to perform
398 * @data: Pointer to 4 32-bit words of data
400 s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
401 u32 (*data)[FW_PHY_ACT_DATA_COUNT])
403 union {
404 struct ixgbe_hic_phy_activity_req cmd;
405 struct ixgbe_hic_phy_activity_resp rsp;
406 } hic;
407 u16 retries = FW_PHY_ACT_RETRIES;
408 s32 rc;
409 u16 i;
411 do {
412 memset(&hic, 0, sizeof(hic));
413 hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
414 hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
415 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
416 hic.cmd.port_number = hw->bus.lan_id;
417 hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
418 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
419 hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
421 rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
422 sizeof(hic.cmd),
423 IXGBE_HI_COMMAND_TIMEOUT,
424 TRUE);
425 if (rc != IXGBE_SUCCESS)
426 return rc;
427 if (hic.rsp.hdr.cmd_or_resp.ret_status ==
428 FW_CEM_RESP_STATUS_SUCCESS) {
429 for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
430 (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
431 return IXGBE_SUCCESS;
433 usec_delay(20);
434 --retries;
435 } while (retries > 0);
437 return IXGBE_ERR_HOST_INTERFACE_COMMAND;
440 static const struct {
441 u16 fw_speed;
442 ixgbe_link_speed phy_speed;
443 } ixgbe_fw_map[] = {
444 { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
445 { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
446 { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
447 { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
448 { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
449 { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
453 * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
454 * @hw: pointer to hardware structure
456 * Returns error code
458 static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
460 u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
461 u16 phy_speeds;
462 u16 phy_id_lo;
463 s32 rc;
464 u16 i;
466 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
467 if (rc)
468 return rc;
470 hw->phy.speeds_supported = 0;
471 phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
472 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
473 if (phy_speeds & ixgbe_fw_map[i].fw_speed)
474 hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
476 if (!hw->phy.autoneg_advertised)
477 hw->phy.autoneg_advertised = hw->phy.speeds_supported;
479 hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
480 phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
481 hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
482 hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
483 if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
484 return IXGBE_ERR_PHY_ADDR_INVALID;
485 return IXGBE_SUCCESS;
489 * ixgbe_identify_phy_fw - Get PHY type based on firmware command
490 * @hw: pointer to hardware structure
492 * Returns error code
494 static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
496 if (hw->bus.lan_id)
497 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
498 else
499 hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
501 hw->phy.type = ixgbe_phy_fw;
502 hw->phy.ops.read_reg = NULL;
503 hw->phy.ops.write_reg = NULL;
504 return ixgbe_get_phy_id_fw(hw);
508 * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
509 * @hw: pointer to hardware structure
511 * Returns error code
513 s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
515 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
517 setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
518 return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
521 static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
522 u32 device_type, u16 *phy_data)
524 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
525 return IXGBE_NOT_IMPLEMENTED;
528 static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
529 u32 device_type, u16 phy_data)
531 UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
532 return IXGBE_NOT_IMPLEMENTED;
536 * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
537 * @hw: pointer to the hardware structure
538 * @addr: I2C bus address to read from
539 * @reg: I2C device register to read from
540 * @val: pointer to location to receive read value
542 * Returns an error code on error.
544 static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
545 u16 reg, u16 *val)
547 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
551 * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
552 * @hw: pointer to the hardware structure
553 * @addr: I2C bus address to read from
554 * @reg: I2C device register to read from
555 * @val: pointer to location to receive read value
557 * Returns an error code on error.
559 static s32
560 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
561 u16 reg, u16 *val)
563 return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
567 * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
568 * @hw: pointer to the hardware structure
569 * @addr: I2C bus address to write to
570 * @reg: I2C device register to write to
571 * @val: value to write
573 * Returns an error code on error.
575 static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
576 u8 addr, u16 reg, u16 val)
578 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
582 * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
583 * @hw: pointer to the hardware structure
584 * @addr: I2C bus address to write to
585 * @reg: I2C device register to write to
586 * @val: value to write
588 * Returns an error code on error.
590 static s32
591 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
592 u8 addr, u16 reg, u16 val)
594 return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
598 * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
599 * @hw: pointer to hardware structure
601 * Initialize the function pointers and for MAC type X550EM.
602 * Does not touch the hardware.
604 s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
606 struct ixgbe_mac_info *mac = &hw->mac;
607 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
608 struct ixgbe_phy_info *phy = &hw->phy;
609 s32 ret_val;
611 DEBUGFUNC("ixgbe_init_ops_X550EM");
613 /* Similar to X550 so start there. */
614 ret_val = ixgbe_init_ops_X550(hw);
616 /* Since this function eventually calls
617 * ixgbe_init_ops_540 by design, we are setting
618 * the pointers to NULL explicitly here to overwrite
619 * the values being set in the x540 function.
622 /* Bypass not supported in x550EM */
623 mac->ops.bypass_rw = NULL;
624 mac->ops.bypass_valid_rd = NULL;
625 mac->ops.bypass_set = NULL;
626 mac->ops.bypass_rd_eep = NULL;
628 /* FCOE not supported in x550EM */
629 mac->ops.get_san_mac_addr = NULL;
630 mac->ops.set_san_mac_addr = NULL;
631 mac->ops.get_wwn_prefix = NULL;
632 mac->ops.get_fcoe_boot_status = NULL;
634 /* IPsec not supported in x550EM */
635 mac->ops.disable_sec_rx_path = NULL;
636 mac->ops.enable_sec_rx_path = NULL;
638 /* AUTOC register is not present in x550EM. */
639 mac->ops.prot_autoc_read = NULL;
640 mac->ops.prot_autoc_write = NULL;
642 /* X550EM bus type is internal*/
643 hw->bus.type = ixgbe_bus_type_internal;
644 mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
647 mac->ops.get_media_type = ixgbe_get_media_type_X550em;
648 mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
649 mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
650 mac->ops.reset_hw = ixgbe_reset_hw_X550em;
651 mac->ops.get_supported_physical_layer =
652 ixgbe_get_supported_physical_layer_X550em;
654 if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
655 mac->ops.setup_fc = ixgbe_setup_fc_generic;
656 else
657 mac->ops.setup_fc = ixgbe_setup_fc_X550em;
659 /* PHY */
660 phy->ops.init = ixgbe_init_phy_ops_X550em;
661 switch (hw->device_id) {
662 case IXGBE_DEV_ID_X550EM_A_1G_T:
663 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
664 mac->ops.setup_fc = NULL;
665 phy->ops.identify = ixgbe_identify_phy_fw;
666 phy->ops.set_phy_power = NULL;
667 phy->ops.get_firmware_version = NULL;
668 break;
669 case IXGBE_DEV_ID_X550EM_X_1G_T:
670 mac->ops.setup_fc = NULL;
671 phy->ops.identify = ixgbe_identify_phy_x550em;
672 phy->ops.set_phy_power = NULL;
673 break;
674 default:
675 phy->ops.identify = ixgbe_identify_phy_x550em;
678 if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
679 phy->ops.set_phy_power = NULL;
682 /* EEPROM */
683 eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
684 eeprom->ops.read = ixgbe_read_ee_hostif_X550;
685 eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
686 eeprom->ops.write = ixgbe_write_ee_hostif_X550;
687 eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
688 eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
689 eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
690 eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
692 return ret_val;
696 * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
697 * @hw: pointer to hardware structure
699 static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
701 u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
702 s32 rc;
703 u16 i;
705 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
706 return 0;
708 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
709 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
710 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
711 return IXGBE_ERR_INVALID_LINK_SETTINGS;
714 switch (hw->fc.requested_mode) {
715 case ixgbe_fc_full:
716 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
717 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
718 break;
719 case ixgbe_fc_rx_pause:
720 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
721 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
722 break;
723 case ixgbe_fc_tx_pause:
724 setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
725 FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
726 break;
727 default:
728 break;
731 for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
732 if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
733 setup[0] |= ixgbe_fw_map[i].fw_speed;
735 setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
737 if (hw->phy.eee_speeds_advertised)
738 setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
740 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
741 if (rc)
742 return rc;
743 if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
744 return IXGBE_ERR_OVERTEMP;
745 return IXGBE_SUCCESS;
749 * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
750 * @hw: pointer to hardware structure
752 * Called at init time to set up flow control.
754 static s32 ixgbe_fc_autoneg_fw(struct ixgbe_hw *hw)
756 if (hw->fc.requested_mode == ixgbe_fc_default)
757 hw->fc.requested_mode = ixgbe_fc_full;
759 return ixgbe_setup_fw_link(hw);
763 * ixgbe_setup_eee_fw - Enable/disable EEE support
764 * @hw: pointer to the HW structure
765 * @enable_eee: boolean flag to enable EEE
767 * Enable/disable EEE based on enable_eee flag.
768 * This function controls EEE for firmware-based PHY implementations.
770 static s32 ixgbe_setup_eee_fw(struct ixgbe_hw *hw, bool enable_eee)
772 if (!!hw->phy.eee_speeds_advertised == enable_eee)
773 return IXGBE_SUCCESS;
774 if (enable_eee)
775 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
776 else
777 hw->phy.eee_speeds_advertised = 0;
778 return hw->phy.ops.setup_link(hw);
782 * ixgbe_init_ops_X550EM_a - Inits func ptrs and MAC type
783 * @hw: pointer to hardware structure
785 * Initialize the function pointers and for MAC type X550EM_a.
786 * Does not touch the hardware.
788 s32 ixgbe_init_ops_X550EM_a(struct ixgbe_hw *hw)
790 struct ixgbe_mac_info *mac = &hw->mac;
791 s32 ret_val;
793 DEBUGFUNC("ixgbe_init_ops_X550EM_a");
795 /* Start with generic X550EM init */
796 ret_val = ixgbe_init_ops_X550EM(hw);
798 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
799 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L) {
800 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
801 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
802 } else {
803 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
804 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
806 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
807 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
809 switch (mac->ops.get_media_type(hw)) {
810 case ixgbe_media_type_fiber:
811 mac->ops.setup_fc = NULL;
812 mac->ops.fc_autoneg = ixgbe_fc_autoneg_fiber_x550em_a;
813 break;
814 case ixgbe_media_type_backplane:
815 mac->ops.fc_autoneg = ixgbe_fc_autoneg_backplane_x550em_a;
816 mac->ops.setup_fc = ixgbe_setup_fc_backplane_x550em_a;
817 break;
818 default:
819 break;
822 switch (hw->device_id) {
823 case IXGBE_DEV_ID_X550EM_A_1G_T:
824 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
825 mac->ops.fc_autoneg = ixgbe_fc_autoneg_sgmii_x550em_a;
826 mac->ops.setup_fc = ixgbe_fc_autoneg_fw;
827 mac->ops.setup_eee = ixgbe_setup_eee_fw;
828 hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL |
829 IXGBE_LINK_SPEED_1GB_FULL;
830 hw->phy.eee_speeds_advertised = hw->phy.eee_speeds_supported;
831 break;
832 default:
833 break;
836 return ret_val;
840 * ixgbe_init_ops_X550EM_x - Inits func ptrs and MAC type
841 * @hw: pointer to hardware structure
843 * Initialize the function pointers and for MAC type X550EM_x.
844 * Does not touch the hardware.
846 s32 ixgbe_init_ops_X550EM_x(struct ixgbe_hw *hw)
848 struct ixgbe_mac_info *mac = &hw->mac;
849 struct ixgbe_link_info *link = &hw->link;
850 s32 ret_val;
852 DEBUGFUNC("ixgbe_init_ops_X550EM_x");
854 /* Start with generic X550EM init */
855 ret_val = ixgbe_init_ops_X550EM(hw);
857 mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
858 mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
859 mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
860 mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
861 link->ops.read_link = ixgbe_read_i2c_combined_generic;
862 link->ops.read_link_unlocked = ixgbe_read_i2c_combined_generic_unlocked;
863 link->ops.write_link = ixgbe_write_i2c_combined_generic;
864 link->ops.write_link_unlocked =
865 ixgbe_write_i2c_combined_generic_unlocked;
866 link->addr = IXGBE_CS4227;
868 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T) {
869 mac->ops.setup_fc = NULL;
870 mac->ops.setup_eee = NULL;
871 mac->ops.init_led_link_act = NULL;
874 return ret_val;
878 * ixgbe_dmac_config_X550
879 * @hw: pointer to hardware structure
881 * Configure DMA coalescing. If enabling dmac, dmac is activated.
882 * When disabling dmac, dmac enable dmac bit is cleared.
884 s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
886 u32 reg, high_pri_tc;
888 DEBUGFUNC("ixgbe_dmac_config_X550");
890 /* Disable DMA coalescing before configuring */
891 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
892 reg &= ~IXGBE_DMACR_DMAC_EN;
893 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
895 /* Disable DMA Coalescing if the watchdog timer is 0 */
896 if (!hw->mac.dmac_config.watchdog_timer)
897 goto out;
899 ixgbe_dmac_config_tcs_X550(hw);
901 /* Configure DMA Coalescing Control Register */
902 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
904 /* Set the watchdog timer in units of 40.96 usec */
905 reg &= ~IXGBE_DMACR_DMACWT_MASK;
906 reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
908 reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
909 /* If fcoe is enabled, set high priority traffic class */
910 if (hw->mac.dmac_config.fcoe_en) {
911 high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
912 reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
913 IXGBE_DMACR_HIGH_PRI_TC_MASK);
915 reg |= IXGBE_DMACR_EN_MNG_IND;
917 /* Enable DMA coalescing after configuration */
918 reg |= IXGBE_DMACR_DMAC_EN;
919 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
921 out:
922 return IXGBE_SUCCESS;
926 * ixgbe_dmac_config_tcs_X550
927 * @hw: pointer to hardware structure
929 * Configure DMA coalescing threshold per TC. The dmac enable bit must
930 * be cleared before configuring.
932 s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
934 u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
936 DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
938 /* Configure DMA coalescing enabled */
939 switch (hw->mac.dmac_config.link_speed) {
940 case IXGBE_LINK_SPEED_10_FULL:
941 case IXGBE_LINK_SPEED_100_FULL:
942 pb_headroom = IXGBE_DMACRXT_100M;
943 break;
944 case IXGBE_LINK_SPEED_1GB_FULL:
945 pb_headroom = IXGBE_DMACRXT_1G;
946 break;
947 default:
948 pb_headroom = IXGBE_DMACRXT_10G;
949 break;
952 maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
953 IXGBE_MHADD_MFS_SHIFT) / 1024);
955 /* Set the per Rx packet buffer receive threshold */
956 for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
957 reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
958 reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
960 if (tc < hw->mac.dmac_config.num_tcs) {
961 /* Get Rx PB size */
962 rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
963 rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
964 IXGBE_RXPBSIZE_SHIFT;
966 /* Calculate receive buffer threshold in kilobytes */
967 if (rx_pb_size > pb_headroom)
968 rx_pb_size = rx_pb_size - pb_headroom;
969 else
970 rx_pb_size = 0;
972 /* Minimum of MFS shall be set for DMCTH */
973 reg |= (rx_pb_size > maxframe_size_kb) ?
974 rx_pb_size : maxframe_size_kb;
976 IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
978 return IXGBE_SUCCESS;
982 * ixgbe_dmac_update_tcs_X550
983 * @hw: pointer to hardware structure
985 * Disables dmac, updates per TC settings, and then enables dmac.
987 s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
989 u32 reg;
991 DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
993 /* Disable DMA coalescing before configuring */
994 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
995 reg &= ~IXGBE_DMACR_DMAC_EN;
996 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
998 ixgbe_dmac_config_tcs_X550(hw);
1000 /* Enable DMA coalescing after configuration */
1001 reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
1002 reg |= IXGBE_DMACR_DMAC_EN;
1003 IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
1005 return IXGBE_SUCCESS;
1009 * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
1010 * @hw: pointer to hardware structure
1012 * Initializes the EEPROM parameters ixgbe_eeprom_info within the
1013 * ixgbe_hw struct in order to set up EEPROM access.
1015 s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
1017 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
1018 u32 eec;
1019 u16 eeprom_size;
1021 DEBUGFUNC("ixgbe_init_eeprom_params_X550");
1023 if (eeprom->type == ixgbe_eeprom_uninitialized) {
1024 eeprom->semaphore_delay = 10;
1025 eeprom->type = ixgbe_flash;
1027 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
1028 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
1029 IXGBE_EEC_SIZE_SHIFT);
1030 eeprom->word_size = 1 << (eeprom_size +
1031 IXGBE_EEPROM_WORD_SIZE_SHIFT);
1033 DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
1034 eeprom->type, eeprom->word_size);
1037 return IXGBE_SUCCESS;
1041 * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
1042 * @hw: pointer to hardware structure
1043 * @enable: enable or disable source address pruning
1044 * @pool: Rx pool to set source address pruning for
1046 void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
1047 unsigned int pool)
1049 u64 pfflp;
1051 /* max rx pool is 63 */
1052 if (pool > 63)
1053 return;
1055 pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
1056 pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
1058 if (enable)
1059 pfflp |= (1ULL << pool);
1060 else
1061 pfflp &= ~(1ULL << pool);
1063 IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
1064 IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
1068 * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
1069 * @hw: pointer to hardware structure
1070 * @enable: enable or disable switch for Ethertype anti-spoofing
1071 * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
1074 void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
1075 bool enable, int vf)
1077 int vf_target_reg = vf >> 3;
1078 int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
1079 u32 pfvfspoof;
1081 DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
1083 pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
1084 if (enable)
1085 pfvfspoof |= (1 << vf_target_shift);
1086 else
1087 pfvfspoof &= ~(1 << vf_target_shift);
1089 IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
1093 * ixgbe_iosf_wait - Wait for IOSF command completion
1094 * @hw: pointer to hardware structure
1095 * @ctrl: pointer to location to receive final IOSF control value
1097 * Returns failing status on timeout
1099 * Note: ctrl can be NULL if the IOSF control register value is not needed
1101 static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
1103 u32 i, command = 0;
1105 /* Check every 10 usec to see if the address cycle completed.
1106 * The SB IOSF BUSY bit will clear when the operation is
1107 * complete
1109 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
1110 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
1111 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
1112 break;
1113 usec_delay(10);
1115 if (ctrl)
1116 *ctrl = command;
1117 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
1118 ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
1119 return IXGBE_ERR_PHY;
1122 return IXGBE_SUCCESS;
1126 * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register
1127 * of the IOSF device
1128 * @hw: pointer to hardware structure
1129 * @reg_addr: 32 bit PHY register to write
1130 * @device_type: 3 bit device type
1131 * @data: Data to write to the register
1133 s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1134 u32 device_type, u32 data)
1136 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1137 u32 command, error;
1138 s32 ret;
1140 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1141 if (ret != IXGBE_SUCCESS)
1142 return ret;
1144 ret = ixgbe_iosf_wait(hw, NULL);
1145 if (ret != IXGBE_SUCCESS)
1146 goto out;
1148 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1149 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1151 /* Write IOSF control register */
1152 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1154 /* Write IOSF data register */
1155 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
1157 ret = ixgbe_iosf_wait(hw, &command);
1159 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1160 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1161 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1162 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1163 "Failed to write, error %x\n", error);
1164 ret = IXGBE_ERR_PHY;
1167 out:
1168 ixgbe_release_swfw_semaphore(hw, gssr);
1169 return ret;
1173 * ixgbe_read_iosf_sb_reg_x550 - Reads specified register of the IOSF device
1174 * @hw: pointer to hardware structure
1175 * @reg_addr: 32 bit PHY register to write
1176 * @device_type: 3 bit device type
1177 * @data: Pointer to read data from the register
1179 s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
1180 u32 device_type, u32 *data)
1182 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
1183 u32 command, error;
1184 s32 ret;
1186 ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
1187 if (ret != IXGBE_SUCCESS)
1188 return ret;
1190 ret = ixgbe_iosf_wait(hw, NULL);
1191 if (ret != IXGBE_SUCCESS)
1192 goto out;
1194 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
1195 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
1197 /* Write IOSF control register */
1198 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
1200 ret = ixgbe_iosf_wait(hw, &command);
1202 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
1203 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
1204 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
1205 ERROR_REPORT2(IXGBE_ERROR_POLLING,
1206 "Failed to read, error %x\n", error);
1207 ret = IXGBE_ERR_PHY;
1210 if (ret == IXGBE_SUCCESS)
1211 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
1213 out:
1214 ixgbe_release_swfw_semaphore(hw, gssr);
1215 return ret;
1219 * ixgbe_get_phy_token - Get the token for shared phy access
1220 * @hw: Pointer to hardware structure
1223 s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
1225 struct ixgbe_hic_phy_token_req token_cmd;
1226 s32 status;
1228 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1229 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1230 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1231 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1232 token_cmd.port_number = hw->bus.lan_id;
1233 token_cmd.command_type = FW_PHY_TOKEN_REQ;
1234 token_cmd.pad = 0;
1235 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1236 sizeof(token_cmd),
1237 IXGBE_HI_COMMAND_TIMEOUT,
1238 TRUE);
1239 if (status) {
1240 DEBUGOUT1("Issuing host interface command failed with Status = %d\n",
1241 status);
1242 return status;
1244 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1245 return IXGBE_SUCCESS;
1246 if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) {
1247 DEBUGOUT1("Host interface command returned 0x%08x , returning IXGBE_ERR_FW_RESP_INVALID\n",
1248 token_cmd.hdr.cmd_or_resp.ret_status);
1249 return IXGBE_ERR_FW_RESP_INVALID;
1252 DEBUGOUT("Returning IXGBE_ERR_TOKEN_RETRY\n");
1253 return IXGBE_ERR_TOKEN_RETRY;
1257 * ixgbe_put_phy_token - Put the token for shared phy access
1258 * @hw: Pointer to hardware structure
1261 s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
1263 struct ixgbe_hic_phy_token_req token_cmd;
1264 s32 status;
1266 token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
1267 token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
1268 token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
1269 token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1270 token_cmd.port_number = hw->bus.lan_id;
1271 token_cmd.command_type = FW_PHY_TOKEN_REL;
1272 token_cmd.pad = 0;
1273 status = ixgbe_host_interface_command(hw, (u32 *)&token_cmd,
1274 sizeof(token_cmd),
1275 IXGBE_HI_COMMAND_TIMEOUT,
1276 TRUE);
1277 if (status)
1278 return status;
1279 if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
1280 return IXGBE_SUCCESS;
1282 DEBUGOUT("Put PHY Token host interface command failed");
1283 return IXGBE_ERR_FW_RESP_INVALID;
1287 * ixgbe_write_iosf_sb_reg_x550a - Writes a value to specified register
1288 * of the IOSF device
1289 * @hw: pointer to hardware structure
1290 * @reg_addr: 32 bit PHY register to write
1291 * @device_type: 3 bit device type
1292 * @data: Data to write to the register
1294 s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1295 u32 device_type, u32 data)
1297 struct ixgbe_hic_internal_phy_req write_cmd;
1298 s32 status;
1299 UNREFERENCED_1PARAMETER(device_type);
1301 memset(&write_cmd, 0, sizeof(write_cmd));
1302 write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1303 write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1304 write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1305 write_cmd.port_number = hw->bus.lan_id;
1306 write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
1307 write_cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1308 write_cmd.write_data = IXGBE_CPU_TO_BE32(data);
1310 status = ixgbe_host_interface_command(hw, (u32 *)&write_cmd,
1311 sizeof(write_cmd),
1312 IXGBE_HI_COMMAND_TIMEOUT, FALSE);
1314 return status;
1318 * ixgbe_read_iosf_sb_reg_x550a - Reads specified register of the IOSF device
1319 * @hw: pointer to hardware structure
1320 * @reg_addr: 32 bit PHY register to write
1321 * @device_type: 3 bit device type
1322 * @data: Pointer to read data from the register
1324 s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
1325 u32 device_type, u32 *data)
1327 union {
1328 struct ixgbe_hic_internal_phy_req cmd;
1329 struct ixgbe_hic_internal_phy_resp rsp;
1330 } hic;
1331 s32 status;
1332 UNREFERENCED_1PARAMETER(device_type);
1334 memset(&hic, 0, sizeof(hic));
1335 hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
1336 hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
1337 hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
1338 hic.cmd.port_number = hw->bus.lan_id;
1339 hic.cmd.command_type = FW_INT_PHY_REQ_READ;
1340 hic.cmd.address = IXGBE_CPU_TO_BE16(reg_addr);
1342 status = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
1343 sizeof(hic.cmd),
1344 IXGBE_HI_COMMAND_TIMEOUT, TRUE);
1346 /* Extract the register value from the response. */
1347 *data = IXGBE_BE32_TO_CPU(hic.rsp.read_data);
1349 return status;
1353 * ixgbe_disable_mdd_X550
1354 * @hw: pointer to hardware structure
1356 * Disable malicious driver detection
1358 void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
1360 u32 reg;
1362 DEBUGFUNC("ixgbe_disable_mdd_X550");
1364 /* Disable MDD for TX DMA and interrupt */
1365 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1366 reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1367 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1369 /* Disable MDD for RX and interrupt */
1370 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1371 reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1372 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1376 * ixgbe_enable_mdd_X550
1377 * @hw: pointer to hardware structure
1379 * Enable malicious driver detection
1381 void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
1383 u32 reg;
1385 DEBUGFUNC("ixgbe_enable_mdd_X550");
1387 /* Enable MDD for TX DMA and interrupt */
1388 reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
1389 reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
1390 IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
1392 /* Enable MDD for RX and interrupt */
1393 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
1394 reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
1395 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
1399 * ixgbe_restore_mdd_vf_X550
1400 * @hw: pointer to hardware structure
1401 * @vf: vf index
1403 * Restore VF that was disabled during malicious driver detection event
1405 void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
1407 u32 idx, reg, num_qs, start_q, bitmask;
1409 DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
1411 /* Map VF to queues */
1412 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1413 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1414 case IXGBE_MRQC_VMDQRT8TCEN:
1415 num_qs = 8; /* 16 VFs / pools */
1416 bitmask = 0x000000FF;
1417 break;
1418 case IXGBE_MRQC_VMDQRSS32EN:
1419 case IXGBE_MRQC_VMDQRT4TCEN:
1420 num_qs = 4; /* 32 VFs / pools */
1421 bitmask = 0x0000000F;
1422 break;
1423 default: /* 64 VFs / pools */
1424 num_qs = 2;
1425 bitmask = 0x00000003;
1426 break;
1428 start_q = vf * num_qs;
1430 /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
1431 idx = start_q / 32;
1432 reg = 0;
1433 reg |= (bitmask << (start_q % 32));
1434 IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
1435 IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
1439 * ixgbe_mdd_event_X550
1440 * @hw: pointer to hardware structure
1441 * @vf_bitmap: vf bitmap of malicious vfs
1443 * Handle malicious driver detection event.
1445 void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
1447 u32 wqbr;
1448 u32 i, j, reg, q, shift, vf, idx;
1450 DEBUGFUNC("ixgbe_mdd_event_X550");
1452 /* figure out pool size for mapping to vf's */
1453 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
1454 switch (reg & IXGBE_MRQC_MRQE_MASK) {
1455 case IXGBE_MRQC_VMDQRT8TCEN:
1456 shift = 3; /* 16 VFs / pools */
1457 break;
1458 case IXGBE_MRQC_VMDQRSS32EN:
1459 case IXGBE_MRQC_VMDQRT4TCEN:
1460 shift = 2; /* 32 VFs / pools */
1461 break;
1462 default:
1463 shift = 1; /* 64 VFs / pools */
1464 break;
1467 /* Read WQBR_TX and WQBR_RX and check for malicious queues */
1468 for (i = 0; i < 4; i++) {
1469 wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
1470 wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
1472 if (!wqbr)
1473 continue;
1475 /* Get malicious queue */
1476 for (j = 0; j < 32 && wqbr; j++) {
1478 if (!(wqbr & (1 << j)))
1479 continue;
1481 /* Get queue from bitmask */
1482 q = j + (i * 32);
1484 /* Map queue to vf */
1485 vf = (q >> shift);
1487 /* Set vf bit in vf_bitmap */
1488 idx = vf / 32;
1489 vf_bitmap[idx] |= (1 << (vf % 32));
1490 wqbr &= ~(1 << j);
1496 * ixgbe_get_media_type_X550em - Get media type
1497 * @hw: pointer to hardware structure
1499 * Returns the media type (fiber, copper, backplane)
1501 enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
1503 enum ixgbe_media_type media_type;
1505 DEBUGFUNC("ixgbe_get_media_type_X550em");
1507 /* Detect if there is a copper PHY attached. */
1508 switch (hw->device_id) {
1509 case IXGBE_DEV_ID_X550EM_X_KR:
1510 case IXGBE_DEV_ID_X550EM_X_KX4:
1511 case IXGBE_DEV_ID_X550EM_X_XFI:
1512 case IXGBE_DEV_ID_X550EM_A_KR:
1513 case IXGBE_DEV_ID_X550EM_A_KR_L:
1514 media_type = ixgbe_media_type_backplane;
1515 break;
1516 case IXGBE_DEV_ID_X550EM_X_SFP:
1517 case IXGBE_DEV_ID_X550EM_A_SFP:
1518 case IXGBE_DEV_ID_X550EM_A_SFP_N:
1519 case IXGBE_DEV_ID_X550EM_A_QSFP:
1520 case IXGBE_DEV_ID_X550EM_A_QSFP_N:
1521 media_type = ixgbe_media_type_fiber;
1522 break;
1523 case IXGBE_DEV_ID_X550EM_X_1G_T:
1524 case IXGBE_DEV_ID_X550EM_X_10G_T:
1525 case IXGBE_DEV_ID_X550EM_A_10G_T:
1526 media_type = ixgbe_media_type_copper;
1527 break;
1528 case IXGBE_DEV_ID_X550EM_A_SGMII:
1529 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
1530 media_type = ixgbe_media_type_backplane;
1531 hw->phy.type = ixgbe_phy_sgmii;
1532 break;
1533 case IXGBE_DEV_ID_X550EM_A_1G_T:
1534 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
1535 media_type = ixgbe_media_type_copper;
1536 break;
1537 default:
1538 media_type = ixgbe_media_type_unknown;
1539 break;
1541 return media_type;
1545 * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1546 * @hw: pointer to hardware structure
1547 * @linear: TRUE if SFP module is linear
1549 static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1551 DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
1553 switch (hw->phy.sfp_type) {
1554 case ixgbe_sfp_type_not_present:
1555 return IXGBE_ERR_SFP_NOT_PRESENT;
1556 case ixgbe_sfp_type_da_cu_core0:
1557 case ixgbe_sfp_type_da_cu_core1:
1558 *linear = TRUE;
1559 break;
1560 case ixgbe_sfp_type_srlr_core0:
1561 case ixgbe_sfp_type_srlr_core1:
1562 case ixgbe_sfp_type_da_act_lmt_core0:
1563 case ixgbe_sfp_type_da_act_lmt_core1:
1564 case ixgbe_sfp_type_1g_sx_core0:
1565 case ixgbe_sfp_type_1g_sx_core1:
1566 case ixgbe_sfp_type_1g_lx_core0:
1567 case ixgbe_sfp_type_1g_lx_core1:
1568 *linear = FALSE;
1569 break;
1570 case ixgbe_sfp_type_unknown:
1571 case ixgbe_sfp_type_1g_cu_core0:
1572 case ixgbe_sfp_type_1g_cu_core1:
1573 default:
1574 return IXGBE_ERR_SFP_NOT_SUPPORTED;
1577 return IXGBE_SUCCESS;
1581 * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
1582 * @hw: pointer to hardware structure
1584 * Searches for and identifies the SFP module and assigns appropriate PHY type.
1586 s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
1588 s32 status;
1589 bool linear;
1591 DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
1593 status = ixgbe_identify_module_generic(hw);
1595 if (status != IXGBE_SUCCESS)
1596 return status;
1598 /* Check if SFP module is supported */
1599 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1601 return status;
1605 * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
1606 * @hw: pointer to hardware structure
1608 s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1610 s32 status;
1611 bool linear;
1613 DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
1615 /* Check if SFP module is supported */
1616 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1618 if (status != IXGBE_SUCCESS)
1619 return status;
1621 ixgbe_init_mac_link_ops_X550em(hw);
1622 hw->phy.ops.reset = NULL;
1624 return IXGBE_SUCCESS;
1628 * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
1629 * internal PHY
1630 * @hw: pointer to hardware structure
1632 static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
1634 s32 status;
1635 u32 link_ctrl;
1637 /* Restart auto-negotiation. */
1638 status = hw->mac.ops.read_iosf_sb_reg(hw,
1639 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1640 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
1642 if (status) {
1643 DEBUGOUT("Auto-negotiation did not complete\n");
1644 return status;
1647 link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1648 status = hw->mac.ops.write_iosf_sb_reg(hw,
1649 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1650 IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
1652 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1653 u32 flx_mask_st20;
1655 /* Indicate to FW that AN restart has been asserted */
1656 status = hw->mac.ops.read_iosf_sb_reg(hw,
1657 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1658 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
1660 if (status) {
1661 DEBUGOUT("Auto-negotiation did not complete\n");
1662 return status;
1665 flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
1666 status = hw->mac.ops.write_iosf_sb_reg(hw,
1667 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1668 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
1671 return status;
1675 * ixgbe_setup_sgmii - Set up link for sgmii
1676 * @hw: pointer to hardware structure
1678 static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1679 bool autoneg_wait)
1681 struct ixgbe_mac_info *mac = &hw->mac;
1682 u32 lval, sval, flx_val;
1683 s32 rc;
1685 rc = mac->ops.read_iosf_sb_reg(hw,
1686 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1687 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1688 if (rc)
1689 return rc;
1691 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1692 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1693 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1694 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1695 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1696 rc = mac->ops.write_iosf_sb_reg(hw,
1697 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1698 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1699 if (rc)
1700 return rc;
1702 rc = mac->ops.read_iosf_sb_reg(hw,
1703 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1704 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1705 if (rc)
1706 return rc;
1708 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1709 sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1710 rc = mac->ops.write_iosf_sb_reg(hw,
1711 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1712 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1713 if (rc)
1714 return rc;
1716 rc = mac->ops.read_iosf_sb_reg(hw,
1717 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1718 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1719 if (rc)
1720 return rc;
1722 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1723 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
1724 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1725 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1726 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1728 rc = mac->ops.write_iosf_sb_reg(hw,
1729 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1730 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1731 if (rc)
1732 return rc;
1734 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1735 if (rc)
1736 return rc;
1738 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1742 * ixgbe_setup_sgmii_fw - Set up link for internal PHY SGMII auto-negotiation
1743 * @hw: pointer to hardware structure
1745 static s32 ixgbe_setup_sgmii_fw(struct ixgbe_hw *hw, ixgbe_link_speed speed,
1746 bool autoneg_wait)
1748 struct ixgbe_mac_info *mac = &hw->mac;
1749 u32 lval, sval, flx_val;
1750 s32 rc;
1752 rc = mac->ops.read_iosf_sb_reg(hw,
1753 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1754 IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
1755 if (rc)
1756 return rc;
1758 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1759 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1760 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
1761 lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
1762 lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1763 rc = mac->ops.write_iosf_sb_reg(hw,
1764 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1765 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1766 if (rc)
1767 return rc;
1769 rc = mac->ops.read_iosf_sb_reg(hw,
1770 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1771 IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
1772 if (rc)
1773 return rc;
1775 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
1776 sval &= ~IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
1777 rc = mac->ops.write_iosf_sb_reg(hw,
1778 IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
1779 IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
1780 if (rc)
1781 return rc;
1783 rc = mac->ops.write_iosf_sb_reg(hw,
1784 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1785 IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
1786 if (rc)
1787 return rc;
1789 rc = mac->ops.read_iosf_sb_reg(hw,
1790 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1791 IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
1792 if (rc)
1793 return rc;
1795 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
1796 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
1797 flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
1798 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
1799 flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
1801 rc = mac->ops.write_iosf_sb_reg(hw,
1802 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
1803 IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
1804 if (rc)
1805 return rc;
1807 rc = ixgbe_restart_an_internal_phy_x550em(hw);
1809 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1813 * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1814 * @hw: pointer to hardware structure
1816 void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1818 struct ixgbe_mac_info *mac = &hw->mac;
1820 DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
1822 switch (hw->mac.ops.get_media_type(hw)) {
1823 case ixgbe_media_type_fiber:
1824 /* CS4227 does not support autoneg, so disable the laser control
1825 * functions for SFP+ fiber
1827 mac->ops.disable_tx_laser = NULL;
1828 mac->ops.enable_tx_laser = NULL;
1829 mac->ops.flap_tx_laser = NULL;
1830 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
1831 mac->ops.set_rate_select_speed =
1832 ixgbe_set_soft_rate_select_speed;
1834 if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
1835 (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
1836 mac->ops.setup_mac_link =
1837 ixgbe_setup_mac_link_sfp_x550a;
1838 else
1839 mac->ops.setup_mac_link =
1840 ixgbe_setup_mac_link_sfp_x550em;
1841 break;
1842 case ixgbe_media_type_copper:
1843 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_1G_T)
1844 break;
1845 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1846 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
1847 hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
1848 mac->ops.setup_link = ixgbe_setup_sgmii_fw;
1849 mac->ops.check_link =
1850 ixgbe_check_mac_link_generic;
1851 } else {
1852 mac->ops.setup_link =
1853 ixgbe_setup_mac_link_t_X550em;
1855 } else {
1856 mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
1857 mac->ops.check_link = ixgbe_check_link_t_X550em;
1859 break;
1860 case ixgbe_media_type_backplane:
1861 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII ||
1862 hw->device_id == IXGBE_DEV_ID_X550EM_A_SGMII_L)
1863 mac->ops.setup_link = ixgbe_setup_sgmii;
1864 break;
1865 default:
1866 break;
1871 * ixgbe_get_link_capabilities_x550em - Determines link capabilities
1872 * @hw: pointer to hardware structure
1873 * @speed: pointer to link speed
1874 * @autoneg: TRUE when autoneg or autotry is enabled
1876 s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
1877 ixgbe_link_speed *speed,
1878 bool *autoneg)
1880 DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
1883 if (hw->phy.type == ixgbe_phy_fw) {
1884 *autoneg = TRUE;
1885 *speed = hw->phy.speeds_supported;
1886 return 0;
1889 /* SFP */
1890 if (hw->phy.media_type == ixgbe_media_type_fiber) {
1892 /* CS4227 SFP must not enable auto-negotiation */
1893 *autoneg = FALSE;
1895 /* Check if 1G SFP module. */
1896 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1897 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
1898 || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
1899 hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
1900 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1901 return IXGBE_SUCCESS;
1904 /* Link capabilities are based on SFP */
1905 if (hw->phy.multispeed_fiber)
1906 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1907 IXGBE_LINK_SPEED_1GB_FULL;
1908 else
1909 *speed = IXGBE_LINK_SPEED_10GB_FULL;
1910 } else {
1911 switch (hw->phy.type) {
1912 case ixgbe_phy_ext_1g_t:
1913 case ixgbe_phy_sgmii:
1914 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1915 break;
1916 case ixgbe_phy_x550em_kr:
1917 if (hw->mac.type == ixgbe_mac_X550EM_a) {
1918 /* check different backplane modes */
1919 if (hw->phy.nw_mng_if_sel &
1920 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
1921 *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
1922 break;
1923 } else if (hw->device_id ==
1924 IXGBE_DEV_ID_X550EM_A_KR_L) {
1925 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1926 break;
1929 /* fall through */
1930 default:
1931 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1932 IXGBE_LINK_SPEED_1GB_FULL;
1933 break;
1935 *autoneg = TRUE;
1938 return IXGBE_SUCCESS;
1942 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
1943 * @hw: pointer to hardware structure
1944 * @lsc: pointer to boolean flag which indicates whether external Base T
1945 * PHY interrupt is lsc
1947 * Determime if external Base T PHY interrupt cause is high temperature
1948 * failure alarm or link status change.
1950 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1951 * failure alarm, else return PHY access status.
1953 static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
1955 u32 status;
1956 u16 reg;
1958 *lsc = FALSE;
1960 /* Vendor alarm triggered */
1961 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1962 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1963 &reg);
1965 if (status != IXGBE_SUCCESS ||
1966 !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
1967 return status;
1969 /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
1970 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
1971 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1972 &reg);
1974 if (status != IXGBE_SUCCESS ||
1975 !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1976 IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
1977 return status;
1979 /* Global alarm triggered */
1980 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
1981 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1982 &reg);
1984 if (status != IXGBE_SUCCESS)
1985 return status;
1987 /* If high temperature failure, then return over temp error and exit */
1988 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
1989 /* power down the PHY in case the PHY FW didn't already */
1990 ixgbe_set_copper_phy_power(hw, FALSE);
1991 return IXGBE_ERR_OVERTEMP;
1992 } else if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
1993 /* device fault alarm triggered */
1994 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
1995 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1996 &reg);
1998 if (status != IXGBE_SUCCESS)
1999 return status;
2001 /* if device fault was due to high temp alarm handle and exit */
2002 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
2003 /* power down the PHY in case the PHY FW didn't */
2004 ixgbe_set_copper_phy_power(hw, FALSE);
2005 return IXGBE_ERR_OVERTEMP;
2009 /* Vendor alarm 2 triggered */
2010 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
2011 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
2013 if (status != IXGBE_SUCCESS ||
2014 !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
2015 return status;
2017 /* link connect/disconnect event occurred */
2018 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
2019 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
2021 if (status != IXGBE_SUCCESS)
2022 return status;
2024 /* Indicate LSC */
2025 if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
2026 *lsc = TRUE;
2028 return IXGBE_SUCCESS;
2032 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
2033 * @hw: pointer to hardware structure
2035 * Enable link status change and temperature failure alarm for the external
2036 * Base T PHY
2038 * Returns PHY access status
2040 static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
2042 u32 status;
2043 u16 reg;
2044 bool lsc;
2046 /* Clear interrupt flags */
2047 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
2049 /* Enable link status change alarm */
2051 /* Enable the LASI interrupts on X552 devices to receive notifications
2052 * of the link configurations of the external PHY and correspondingly
2053 * support the configuration of the internal iXFI link, since iXFI does
2054 * not support auto-negotiation. This is not required for X553 devices
2055 * having KR support, which performs auto-negotiations and which is used
2056 * as the internal link to the external PHY. Hence adding a check here
2057 * to avoid enabling LASI interrupts for X553 devices.
2059 if (hw->mac.type != ixgbe_mac_X550EM_a) {
2060 status = hw->phy.ops.read_reg(hw,
2061 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2062 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
2064 if (status != IXGBE_SUCCESS)
2065 return status;
2067 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
2069 status = hw->phy.ops.write_reg(hw,
2070 IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
2071 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
2073 if (status != IXGBE_SUCCESS)
2074 return status;
2077 /* Enable high temperature failure and global fault alarms */
2078 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2079 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2080 &reg);
2082 if (status != IXGBE_SUCCESS)
2083 return status;
2085 reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
2086 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
2088 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
2089 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2090 reg);
2092 if (status != IXGBE_SUCCESS)
2093 return status;
2095 /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
2096 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2097 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2098 &reg);
2100 if (status != IXGBE_SUCCESS)
2101 return status;
2103 reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
2104 IXGBE_MDIO_GLOBAL_ALARM_1_INT);
2106 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
2107 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2108 reg);
2110 if (status != IXGBE_SUCCESS)
2111 return status;
2113 /* Enable chip-wide vendor alarm */
2114 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2115 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2116 &reg);
2118 if (status != IXGBE_SUCCESS)
2119 return status;
2121 reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
2123 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
2124 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2125 reg);
2127 return status;
2131 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
2132 * @hw: pointer to hardware structure
2133 * @speed: link speed
2135 * Configures the integrated KR PHY.
2137 static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
2138 ixgbe_link_speed speed)
2140 s32 status;
2141 u32 reg_val;
2143 status = hw->mac.ops.read_iosf_sb_reg(hw,
2144 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2145 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2146 if (status)
2147 return status;
2149 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2150 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
2151 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
2153 /* Advertise 10G support. */
2154 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
2155 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
2157 /* Advertise 1G support. */
2158 if (speed & IXGBE_LINK_SPEED_1GB_FULL)
2159 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
2161 status = hw->mac.ops.write_iosf_sb_reg(hw,
2162 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2163 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2165 if (hw->mac.type == ixgbe_mac_X550EM_a) {
2166 /* Set lane mode to KR auto negotiation */
2167 status = hw->mac.ops.read_iosf_sb_reg(hw,
2168 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2169 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2171 if (status)
2172 return status;
2174 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2175 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
2176 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2177 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2178 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2180 status = hw->mac.ops.write_iosf_sb_reg(hw,
2181 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2182 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2185 return ixgbe_restart_an_internal_phy_x550em(hw);
2189 * ixgbe_reset_phy_fw - Reset firmware-controlled PHYs
2190 * @hw: pointer to hardware structure
2192 static s32 ixgbe_reset_phy_fw(struct ixgbe_hw *hw)
2194 u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2195 s32 rc;
2197 if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
2198 return IXGBE_SUCCESS;
2200 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_PHY_SW_RESET, &store);
2201 if (rc)
2202 return rc;
2203 memset(store, 0, sizeof(store));
2205 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_INIT_PHY, &store);
2206 if (rc)
2207 return rc;
2209 return ixgbe_setup_fw_link(hw);
2213 * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp
2214 * @hw: pointer to hardware structure
2216 static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw)
2218 u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 };
2219 s32 rc;
2221 rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store);
2222 if (rc)
2223 return rc;
2225 if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) {
2226 ixgbe_shutdown_fw_phy(hw);
2227 return IXGBE_ERR_OVERTEMP;
2229 return IXGBE_SUCCESS;
2233 * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register
2234 * @hw: pointer to hardware structure
2236 * Read NW_MNG_IF_SEL register and save field values, and check for valid field
2237 * values.
2239 static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw)
2241 /* Save NW management interface connected on board. This is used
2242 * to determine internal PHY mode.
2244 hw->phy.nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
2246 /* If X552 (X550EM_a) and MDIO is connected to external PHY, then set
2247 * PHY address. This register field was has only been used for X552.
2249 if (hw->mac.type == ixgbe_mac_X550EM_a &&
2250 hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_MDIO_ACT) {
2251 hw->phy.addr = (hw->phy.nw_mng_if_sel &
2252 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD) >>
2253 IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
2256 return IXGBE_SUCCESS;
2260 * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
2261 * @hw: pointer to hardware structure
2263 * Initialize any function pointers that were not able to be
2264 * set during init_shared_code because the PHY/SFP type was
2265 * not known. Perform the SFP init if necessary.
2267 s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
2269 struct ixgbe_phy_info *phy = &hw->phy;
2270 s32 ret_val;
2272 DEBUGFUNC("ixgbe_init_phy_ops_X550em");
2274 hw->mac.ops.set_lan_id(hw);
2275 ixgbe_read_mng_if_sel_x550em(hw);
2277 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
2278 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2279 ixgbe_setup_mux_ctl(hw);
2280 phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
2283 switch (hw->device_id) {
2284 case IXGBE_DEV_ID_X550EM_A_1G_T:
2285 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2286 phy->ops.read_reg_mdi = NULL;
2287 phy->ops.write_reg_mdi = NULL;
2288 hw->phy.ops.read_reg = NULL;
2289 hw->phy.ops.write_reg = NULL;
2290 phy->ops.check_overtemp = ixgbe_check_overtemp_fw;
2291 if (hw->bus.lan_id)
2292 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2293 else
2294 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2296 break;
2297 case IXGBE_DEV_ID_X550EM_A_10G_T:
2298 case IXGBE_DEV_ID_X550EM_A_SFP:
2299 hw->phy.ops.read_reg = ixgbe_read_phy_reg_x550a;
2300 hw->phy.ops.write_reg = ixgbe_write_phy_reg_x550a;
2301 if (hw->bus.lan_id)
2302 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
2303 else
2304 hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
2305 break;
2306 case IXGBE_DEV_ID_X550EM_X_SFP:
2307 /* set up for CS4227 usage */
2308 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
2309 break;
2310 case IXGBE_DEV_ID_X550EM_X_1G_T:
2311 phy->ops.read_reg_mdi = NULL;
2312 phy->ops.write_reg_mdi = NULL;
2313 default:
2314 break;
2317 /* Identify the PHY or SFP module */
2318 ret_val = phy->ops.identify(hw);
2319 if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2320 ret_val == IXGBE_ERR_PHY_ADDR_INVALID)
2321 return ret_val;
2323 /* Setup function pointers based on detected hardware */
2324 ixgbe_init_mac_link_ops_X550em(hw);
2325 if (phy->sfp_type != ixgbe_sfp_type_unknown)
2326 phy->ops.reset = NULL;
2328 /* Set functions pointers based on phy type */
2329 switch (hw->phy.type) {
2330 case ixgbe_phy_x550em_kx4:
2331 phy->ops.setup_link = NULL;
2332 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2333 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2334 break;
2335 case ixgbe_phy_x550em_kr:
2336 phy->ops.setup_link = ixgbe_setup_kr_x550em;
2337 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2338 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2339 break;
2340 case ixgbe_phy_ext_1g_t:
2341 /* link is managed by FW */
2342 phy->ops.setup_link = NULL;
2343 phy->ops.reset = NULL;
2344 break;
2345 case ixgbe_phy_x550em_xfi:
2346 /* link is managed by HW */
2347 phy->ops.setup_link = NULL;
2348 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2349 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2350 break;
2351 case ixgbe_phy_x550em_ext_t:
2352 /* If internal link mode is XFI, then setup iXFI internal link,
2353 * else setup KR now.
2355 phy->ops.setup_internal_link =
2356 ixgbe_setup_internal_phy_t_x550em;
2358 /* setup SW LPLU only for first revision of X550EM_x */
2359 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
2360 !(IXGBE_FUSES0_REV_MASK &
2361 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
2362 phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2364 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
2365 phy->ops.reset = ixgbe_reset_phy_t_X550em;
2366 break;
2367 case ixgbe_phy_sgmii:
2368 phy->ops.setup_link = NULL;
2369 break;
2370 case ixgbe_phy_fw:
2371 phy->ops.setup_link = ixgbe_setup_fw_link;
2372 phy->ops.reset = ixgbe_reset_phy_fw;
2373 break;
2374 default:
2375 break;
2377 return ret_val;
2381 * ixgbe_set_mdio_speed - Set MDIO clock speed
2382 * @hw: pointer to hardware structure
2384 static void ixgbe_set_mdio_speed(struct ixgbe_hw *hw)
2386 u32 hlreg0;
2388 switch (hw->device_id) {
2389 case IXGBE_DEV_ID_X550EM_X_10G_T:
2390 case IXGBE_DEV_ID_X550EM_A_SGMII:
2391 case IXGBE_DEV_ID_X550EM_A_SGMII_L:
2392 case IXGBE_DEV_ID_X550EM_A_10G_T:
2393 case IXGBE_DEV_ID_X550EM_A_SFP:
2394 case IXGBE_DEV_ID_X550EM_A_QSFP:
2395 /* Config MDIO clock speed before the first MDIO PHY access */
2396 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2397 hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2398 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2399 break;
2400 case IXGBE_DEV_ID_X550EM_A_1G_T:
2401 case IXGBE_DEV_ID_X550EM_A_1G_T_L:
2402 /* Select fast MDIO clock speed for these devices */
2403 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2404 hlreg0 |= IXGBE_HLREG0_MDCSPD;
2405 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2406 break;
2407 default:
2408 break;
2413 * ixgbe_reset_hw_X550em - Perform hardware reset
2414 * @hw: pointer to hardware structure
2416 * Resets the hardware by resetting the transmit and receive units, masks
2417 * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2418 * reset.
2420 s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
2422 ixgbe_link_speed link_speed;
2423 s32 status;
2424 u32 ctrl = 0;
2425 u32 i;
2426 bool link_up = FALSE;
2427 u32 swfw_mask = hw->phy.phy_semaphore_mask;
2429 DEBUGFUNC("ixgbe_reset_hw_X550em");
2431 /* Call adapter stop to disable Tx/Rx and clear interrupts */
2432 status = hw->mac.ops.stop_adapter(hw);
2433 if (status != IXGBE_SUCCESS) {
2434 DEBUGOUT1("Failed to stop adapter, STATUS = %d\n", status);
2435 return status;
2437 /* flush pending Tx transactions */
2438 ixgbe_clear_tx_pending(hw);
2440 ixgbe_set_mdio_speed(hw);
2442 /* PHY ops must be identified and initialized prior to reset */
2443 status = hw->phy.ops.init(hw);
2445 if (status)
2446 DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
2447 status);
2449 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
2450 status == IXGBE_ERR_PHY_ADDR_INVALID) {
2451 DEBUGOUT("Returning from reset HW due to PHY init failure\n");
2452 return status;
2455 /* start the external PHY */
2456 if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2457 status = ixgbe_init_ext_t_x550em(hw);
2458 if (status) {
2459 DEBUGOUT1("Failed to start the external PHY, STATUS = %d\n",
2460 status);
2461 return status;
2465 /* Setup SFP module if there is one present. */
2466 if (hw->phy.sfp_setup_needed) {
2467 status = hw->mac.ops.setup_sfp(hw);
2468 hw->phy.sfp_setup_needed = FALSE;
2471 if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
2472 return status;
2474 /* Reset PHY */
2475 if (!hw->phy.reset_disable && hw->phy.ops.reset) {
2476 if (hw->phy.ops.reset(hw) == IXGBE_ERR_OVERTEMP)
2477 return IXGBE_ERR_OVERTEMP;
2480 mac_reset_top:
2481 /* Issue global reset to the MAC. Needs to be SW reset if link is up.
2482 * If link reset is used when link is up, it might reset the PHY when
2483 * mng is using it. If link is down or the flag to force full link
2484 * reset is set, then perform link reset.
2486 ctrl = IXGBE_CTRL_LNK_RST;
2487 if (!hw->force_full_reset) {
2488 hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
2489 if (link_up)
2490 ctrl = IXGBE_CTRL_RST;
2493 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
2494 if (status != IXGBE_SUCCESS) {
2495 ERROR_REPORT2(IXGBE_ERROR_CAUTION,
2496 "semaphore failed with %d", status);
2497 return IXGBE_ERR_SWFW_SYNC;
2499 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2500 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2501 IXGBE_WRITE_FLUSH(hw);
2502 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
2504 /* Poll for reset bit to self-clear meaning reset is complete */
2505 for (i = 0; i < 10; i++) {
2506 usec_delay(1);
2507 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2508 if (!(ctrl & IXGBE_CTRL_RST_MASK))
2509 break;
2512 if (ctrl & IXGBE_CTRL_RST_MASK) {
2513 status = IXGBE_ERR_RESET_FAILED;
2514 DEBUGOUT("Reset polling failed to complete.\n");
2517 msec_delay(50);
2519 /* Double resets are required for recovery from certain error
2520 * conditions. Between resets, it is necessary to stall to
2521 * allow time for any pending HW events to complete.
2523 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2524 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2525 goto mac_reset_top;
2528 /* Store the permanent mac address */
2529 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2531 /* Store MAC address from RAR0, clear receive address registers, and
2532 * clear the multicast table. Also reset num_rar_entries to 128,
2533 * since we modify this value when programming the SAN MAC address.
2535 hw->mac.num_rar_entries = 128;
2536 hw->mac.ops.init_rx_addrs(hw);
2538 ixgbe_set_mdio_speed(hw);
2540 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2541 ixgbe_setup_mux_ctl(hw);
2543 if (status != IXGBE_SUCCESS)
2544 DEBUGOUT1("Reset HW failed, STATUS = %d\n", status);
2546 return status;
2550 * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2551 * @hw: pointer to hardware structure
2553 s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
2555 u32 status;
2556 u16 reg;
2558 status = hw->phy.ops.read_reg(hw,
2559 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
2560 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2561 &reg);
2563 if (status != IXGBE_SUCCESS)
2564 return status;
2566 /* If PHY FW reset completed bit is set then this is the first
2567 * SW instance after a power on so the PHY FW must be un-stalled.
2569 if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2570 status = hw->phy.ops.read_reg(hw,
2571 IXGBE_MDIO_GLOBAL_RES_PR_10,
2572 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2573 &reg);
2575 if (status != IXGBE_SUCCESS)
2576 return status;
2578 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
2580 status = hw->phy.ops.write_reg(hw,
2581 IXGBE_MDIO_GLOBAL_RES_PR_10,
2582 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2583 reg);
2585 if (status != IXGBE_SUCCESS)
2586 return status;
2589 return status;
2593 * ixgbe_setup_kr_x550em - Configure the KR PHY.
2594 * @hw: pointer to hardware structure
2596 s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
2598 /* leave link alone for 2.5G */
2599 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
2600 return IXGBE_SUCCESS;
2602 if (ixgbe_check_reset_blocked(hw))
2603 return 0;
2605 return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
2609 * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
2610 * @hw: pointer to hardware structure
2612 * Configure the external PHY and the integrated KR PHY for SFP support.
2614 s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
2615 ixgbe_link_speed speed,
2616 bool autoneg_wait_to_complete)
2618 s32 ret_val;
2619 u16 reg_slice, reg_val;
2620 bool setup_linear = FALSE;
2621 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
2623 /* Check if SFP module is supported and linear */
2624 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2626 /* If no SFP module present, then return success. Return success since
2627 * there is no reason to configure CS4227 and SFP not present error is
2628 * not excepted in the setup MAC link flow.
2630 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2631 return IXGBE_SUCCESS;
2633 if (ret_val != IXGBE_SUCCESS)
2634 return ret_val;
2636 /* Configure internal PHY for KR/KX. */
2637 ixgbe_setup_kr_speed_x550em(hw, speed);
2639 /* Configure CS4227 LINE side to proper mode. */
2640 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
2641 (hw->bus.lan_id << 12);
2642 if (setup_linear)
2643 reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2644 else
2645 reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2646 ret_val = hw->link.ops.write_link(hw, hw->link.addr, reg_slice,
2647 reg_val);
2648 return ret_val;
2652 * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
2653 * @hw: pointer to hardware structure
2654 * @speed: the link speed to force
2656 * Configures the integrated PHY for native SFI mode. Used to connect the
2657 * internal PHY directly to an SFP cage, without autonegotiation.
2659 static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2661 struct ixgbe_mac_info *mac = &hw->mac;
2662 s32 status;
2663 u32 reg_val;
2665 /* Disable all AN and force speed to 10G Serial. */
2666 status = mac->ops.read_iosf_sb_reg(hw,
2667 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2668 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2669 if (status != IXGBE_SUCCESS)
2670 return status;
2672 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
2673 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
2674 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
2675 reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
2677 /* Select forced link speed for internal PHY. */
2678 switch (*speed) {
2679 case IXGBE_LINK_SPEED_10GB_FULL:
2680 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
2681 break;
2682 case IXGBE_LINK_SPEED_1GB_FULL:
2683 reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
2684 break;
2685 default:
2686 /* Other link speeds are not supported by internal PHY. */
2687 return IXGBE_ERR_LINK_SETUP;
2690 status = mac->ops.write_iosf_sb_reg(hw,
2691 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2692 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2694 /* Toggle port SW reset by AN reset. */
2695 status = ixgbe_restart_an_internal_phy_x550em(hw);
2697 return status;
2701 * ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
2702 * @hw: pointer to hardware structure
2704 * Configure the the integrated PHY for SFP support.
2706 s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
2707 ixgbe_link_speed speed,
2708 bool autoneg_wait_to_complete)
2710 s32 ret_val;
2711 u16 reg_phy_ext;
2712 bool setup_linear = FALSE;
2713 u32 reg_slice, reg_phy_int, slice_offset;
2715 UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
2717 /* Check if SFP module is supported and linear */
2718 ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
2720 /* If no SFP module present, then return success. Return success since
2721 * SFP not present error is not excepted in the setup MAC link flow.
2723 if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
2724 return IXGBE_SUCCESS;
2726 if (ret_val != IXGBE_SUCCESS)
2727 return ret_val;
2729 if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
2730 /* Configure internal PHY for native SFI based on module type */
2731 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
2732 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2733 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
2735 if (ret_val != IXGBE_SUCCESS)
2736 return ret_val;
2738 reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
2739 if (!setup_linear)
2740 reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
2742 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
2743 IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
2744 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
2746 if (ret_val != IXGBE_SUCCESS)
2747 return ret_val;
2749 /* Setup SFI internal link. */
2750 ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
2751 } else {
2752 /* Configure internal PHY for KR/KX. */
2753 ixgbe_setup_kr_speed_x550em(hw, speed);
2755 if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
2756 /* Find Address */
2757 DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
2758 return IXGBE_ERR_PHY_ADDR_INVALID;
2761 /* Get external PHY SKU id */
2762 ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU,
2763 IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2765 if (ret_val != IXGBE_SUCCESS)
2766 return ret_val;
2768 /* When configuring quad port CS4223, the MAC instance is part
2769 * of the slice offset.
2771 if (reg_phy_ext == IXGBE_CS4223_SKU_ID)
2772 slice_offset = (hw->bus.lan_id +
2773 (hw->bus.instance_id << 1)) << 12;
2774 else
2775 slice_offset = hw->bus.lan_id << 12;
2777 /* Configure CS4227/CS4223 LINE side to proper mode. */
2778 reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
2780 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2781 IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2783 if (ret_val != IXGBE_SUCCESS)
2784 return ret_val;
2786 reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
2787 (IXGBE_CS4227_EDC_MODE_SR << 1));
2789 if (setup_linear)
2790 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
2791 else
2792 reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
2793 ret_val = hw->phy.ops.write_reg(hw, reg_slice,
2794 IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
2796 /* Flush previous write with a read */
2797 ret_val = hw->phy.ops.read_reg(hw, reg_slice,
2798 IXGBE_MDIO_ZERO_DEV_TYPE, &reg_phy_ext);
2800 return ret_val;
2804 * ixgbe_setup_ixfi_x550em_x - MAC specific iXFI configuration
2805 * @hw: pointer to hardware structure
2807 * iXfI configuration needed for ixgbe_mac_X550EM_x devices.
2809 static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
2811 struct ixgbe_mac_info *mac = &hw->mac;
2812 s32 status;
2813 u32 reg_val;
2815 /* Disable training protocol FSM. */
2816 status = mac->ops.read_iosf_sb_reg(hw,
2817 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2818 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2819 if (status != IXGBE_SUCCESS)
2820 return status;
2821 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
2822 status = mac->ops.write_iosf_sb_reg(hw,
2823 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
2824 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2825 if (status != IXGBE_SUCCESS)
2826 return status;
2828 /* Disable Flex from training TXFFE. */
2829 status = mac->ops.read_iosf_sb_reg(hw,
2830 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2831 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2832 if (status != IXGBE_SUCCESS)
2833 return status;
2834 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2835 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2836 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2837 status = mac->ops.write_iosf_sb_reg(hw,
2838 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
2839 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2840 if (status != IXGBE_SUCCESS)
2841 return status;
2842 status = mac->ops.read_iosf_sb_reg(hw,
2843 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2844 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2845 if (status != IXGBE_SUCCESS)
2846 return status;
2847 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
2848 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
2849 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
2850 status = mac->ops.write_iosf_sb_reg(hw,
2851 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
2852 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2853 if (status != IXGBE_SUCCESS)
2854 return status;
2856 /* Enable override for coefficients. */
2857 status = mac->ops.read_iosf_sb_reg(hw,
2858 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2859 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2860 if (status != IXGBE_SUCCESS)
2861 return status;
2862 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
2863 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
2864 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
2865 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
2866 status = mac->ops.write_iosf_sb_reg(hw,
2867 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
2868 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2869 return status;
2873 * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
2874 * @hw: pointer to hardware structure
2875 * @speed: the link speed to force
2877 * Configures the integrated KR PHY to use iXFI mode. Used to connect an
2878 * internal and external PHY at a specific speed, without autonegotiation.
2880 static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
2882 struct ixgbe_mac_info *mac = &hw->mac;
2883 s32 status;
2884 u32 reg_val;
2886 /* iXFI is only supported with X552 */
2887 if (mac->type != ixgbe_mac_X550EM_x)
2888 return IXGBE_ERR_LINK_SETUP;
2890 /* Disable AN and force speed to 10G Serial. */
2891 status = mac->ops.read_iosf_sb_reg(hw,
2892 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2893 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
2894 if (status != IXGBE_SUCCESS)
2895 return status;
2897 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
2898 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
2900 /* Select forced link speed for internal PHY. */
2901 switch (*speed) {
2902 case IXGBE_LINK_SPEED_10GB_FULL:
2903 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
2904 break;
2905 case IXGBE_LINK_SPEED_1GB_FULL:
2906 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
2907 break;
2908 default:
2909 /* Other link speeds are not supported by internal KR PHY. */
2910 return IXGBE_ERR_LINK_SETUP;
2913 status = mac->ops.write_iosf_sb_reg(hw,
2914 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
2915 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
2916 if (status != IXGBE_SUCCESS)
2917 return status;
2919 /* Additional configuration needed for x550em_x */
2920 if (hw->mac.type == ixgbe_mac_X550EM_x) {
2921 status = ixgbe_setup_ixfi_x550em_x(hw);
2922 if (status != IXGBE_SUCCESS)
2923 return status;
2926 /* Toggle port SW reset by AN reset. */
2927 status = ixgbe_restart_an_internal_phy_x550em(hw);
2929 return status;
2933 * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
2934 * @hw: address of hardware structure
2935 * @link_up: address of boolean to indicate link status
2937 * Returns error code if unable to get link status.
2939 static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
2941 u32 ret;
2942 u16 autoneg_status;
2944 *link_up = FALSE;
2946 /* read this twice back to back to indicate current status */
2947 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2948 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2949 &autoneg_status);
2950 if (ret != IXGBE_SUCCESS)
2951 return ret;
2953 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
2954 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2955 &autoneg_status);
2956 if (ret != IXGBE_SUCCESS)
2957 return ret;
2959 *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
2961 return IXGBE_SUCCESS;
2965 * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
2966 * @hw: point to hardware structure
2968 * Configures the link between the integrated KR PHY and the external X557 PHY
2969 * The driver will call this function when it gets a link status change
2970 * interrupt from the X557 PHY. This function configures the link speed
2971 * between the PHYs to match the link speed of the BASE-T link.
2973 * A return of a non-zero value indicates an error, and the base driver should
2974 * not report link up.
2976 s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
2978 ixgbe_link_speed force_speed;
2979 bool link_up;
2980 u32 status;
2981 u16 speed;
2983 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
2984 return IXGBE_ERR_CONFIG;
2986 if (hw->mac.type == ixgbe_mac_X550EM_x &&
2987 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
2988 /* If link is down, there is no setup necessary so return */
2989 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
2990 if (status != IXGBE_SUCCESS)
2991 return status;
2993 if (!link_up)
2994 return IXGBE_SUCCESS;
2996 status = hw->phy.ops.read_reg(hw,
2997 IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
2998 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2999 &speed);
3000 if (status != IXGBE_SUCCESS)
3001 return status;
3003 /* If link is still down - no setup is required so return */
3004 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3005 if (status != IXGBE_SUCCESS)
3006 return status;
3007 if (!link_up)
3008 return IXGBE_SUCCESS;
3010 /* clear everything but the speed and duplex bits */
3011 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
3013 switch (speed) {
3014 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
3015 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
3016 break;
3017 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
3018 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
3019 break;
3020 default:
3021 /* Internal PHY does not support anything else */
3022 return IXGBE_ERR_INVALID_LINK_SETTINGS;
3025 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
3026 } else {
3027 speed = IXGBE_LINK_SPEED_10GB_FULL |
3028 IXGBE_LINK_SPEED_1GB_FULL;
3029 return ixgbe_setup_kr_speed_x550em(hw, speed);
3034 * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
3035 * @hw: pointer to hardware structure
3037 * Configures the integrated KR PHY to use internal loopback mode.
3039 s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
3041 s32 status;
3042 u32 reg_val;
3044 /* Disable AN and force speed to 10G Serial. */
3045 status = hw->mac.ops.read_iosf_sb_reg(hw,
3046 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3047 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3048 if (status != IXGBE_SUCCESS)
3049 return status;
3050 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
3051 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
3052 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
3053 status = hw->mac.ops.write_iosf_sb_reg(hw,
3054 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
3055 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3056 if (status != IXGBE_SUCCESS)
3057 return status;
3059 /* Set near-end loopback clocks. */
3060 status = hw->mac.ops.read_iosf_sb_reg(hw,
3061 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3062 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3063 if (status != IXGBE_SUCCESS)
3064 return status;
3065 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
3066 reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
3067 status = hw->mac.ops.write_iosf_sb_reg(hw,
3068 IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
3069 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3070 if (status != IXGBE_SUCCESS)
3071 return status;
3073 /* Set loopback enable. */
3074 status = hw->mac.ops.read_iosf_sb_reg(hw,
3075 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3076 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3077 if (status != IXGBE_SUCCESS)
3078 return status;
3079 reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
3080 status = hw->mac.ops.write_iosf_sb_reg(hw,
3081 IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
3082 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3083 if (status != IXGBE_SUCCESS)
3084 return status;
3086 /* Training bypass. */
3087 status = hw->mac.ops.read_iosf_sb_reg(hw,
3088 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3089 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3090 if (status != IXGBE_SUCCESS)
3091 return status;
3092 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
3093 status = hw->mac.ops.write_iosf_sb_reg(hw,
3094 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
3095 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3097 return status;
3101 * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
3102 * assuming that the semaphore is already obtained.
3103 * @hw: pointer to hardware structure
3104 * @offset: offset of word in the EEPROM to read
3105 * @data: word read from the EEPROM
3107 * Reads a 16 bit word from the EEPROM using the hostif.
3109 s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
3111 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3112 struct ixgbe_hic_read_shadow_ram buffer;
3113 s32 status;
3115 DEBUGFUNC("ixgbe_read_ee_hostif_X550");
3116 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3117 buffer.hdr.req.buf_lenh = 0;
3118 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3119 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3121 /* convert offset from words to bytes */
3122 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3123 /* one word */
3124 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3125 buffer.pad2 = 0;
3126 buffer.pad3 = 0;
3128 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3129 if (status)
3130 return status;
3132 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3133 IXGBE_HI_COMMAND_TIMEOUT);
3134 if (!status) {
3135 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
3136 FW_NVM_DATA_OFFSET);
3139 hw->mac.ops.release_swfw_sync(hw, mask);
3140 return status;
3144 * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
3145 * @hw: pointer to hardware structure
3146 * @offset: offset of word in the EEPROM to read
3147 * @words: number of words
3148 * @data: word(s) read from the EEPROM
3150 * Reads a 16 bit word(s) from the EEPROM using the hostif.
3152 s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3153 u16 offset, u16 words, u16 *data)
3155 const u32 mask = IXGBE_GSSR_SW_MNG_SM | IXGBE_GSSR_EEP_SM;
3156 struct ixgbe_hic_read_shadow_ram buffer;
3157 u32 current_word = 0;
3158 u16 words_to_read;
3159 s32 status;
3160 u32 i;
3162 DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
3164 /* Take semaphore for the entire operation. */
3165 status = hw->mac.ops.acquire_swfw_sync(hw, mask);
3166 if (status) {
3167 DEBUGOUT("EEPROM read buffer - semaphore failed\n");
3168 return status;
3171 while (words) {
3172 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
3173 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
3174 else
3175 words_to_read = words;
3177 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
3178 buffer.hdr.req.buf_lenh = 0;
3179 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
3180 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3182 /* convert offset from words to bytes */
3183 buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
3184 buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
3185 buffer.pad2 = 0;
3186 buffer.pad3 = 0;
3188 status = ixgbe_hic_unlocked(hw, (u32 *)&buffer, sizeof(buffer),
3189 IXGBE_HI_COMMAND_TIMEOUT);
3191 if (status) {
3192 DEBUGOUT("Host interface command failed\n");
3193 goto out;
3196 for (i = 0; i < words_to_read; i++) {
3197 u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
3198 2 * i;
3199 u32 value = IXGBE_READ_REG(hw, reg);
3201 data[current_word] = (u16)(value & 0xffff);
3202 current_word++;
3203 i++;
3204 if (i < words_to_read) {
3205 value >>= 16;
3206 data[current_word] = (u16)(value & 0xffff);
3207 current_word++;
3210 words -= words_to_read;
3213 out:
3214 hw->mac.ops.release_swfw_sync(hw, mask);
3215 return status;
3219 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3220 * @hw: pointer to hardware structure
3221 * @offset: offset of word in the EEPROM to write
3222 * @data: word write to the EEPROM
3224 * Write a 16 bit word to the EEPROM using the hostif.
3226 s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
3227 u16 data)
3229 s32 status;
3230 struct ixgbe_hic_write_shadow_ram buffer;
3232 DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
3234 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
3235 buffer.hdr.req.buf_lenh = 0;
3236 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
3237 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
3239 /* one word */
3240 buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
3241 buffer.data = data;
3242 buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
3244 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3245 sizeof(buffer),
3246 IXGBE_HI_COMMAND_TIMEOUT, FALSE);
3248 return status;
3252 * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
3253 * @hw: pointer to hardware structure
3254 * @offset: offset of word in the EEPROM to write
3255 * @data: word write to the EEPROM
3257 * Write a 16 bit word to the EEPROM using the hostif.
3259 s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
3260 u16 data)
3262 s32 status = IXGBE_SUCCESS;
3264 DEBUGFUNC("ixgbe_write_ee_hostif_X550");
3266 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
3267 IXGBE_SUCCESS) {
3268 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
3269 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3270 } else {
3271 DEBUGOUT("write ee hostif failed to get semaphore");
3272 status = IXGBE_ERR_SWFW_SYNC;
3275 return status;
3279 * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
3280 * @hw: pointer to hardware structure
3281 * @offset: offset of word in the EEPROM to write
3282 * @words: number of words
3283 * @data: word(s) write to the EEPROM
3285 * Write a 16 bit word(s) to the EEPROM using the hostif.
3287 s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
3288 u16 offset, u16 words, u16 *data)
3290 s32 status = IXGBE_SUCCESS;
3291 u32 i = 0;
3293 DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
3295 /* Take semaphore for the entire operation. */
3296 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3297 if (status != IXGBE_SUCCESS) {
3298 DEBUGOUT("EEPROM write buffer - semaphore failed\n");
3299 goto out;
3302 for (i = 0; i < words; i++) {
3303 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
3304 data[i]);
3306 if (status != IXGBE_SUCCESS) {
3307 DEBUGOUT("Eeprom buffered write failed\n");
3308 break;
3312 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
3313 out:
3315 return status;
3319 * ixgbe_checksum_ptr_x550 - Checksum one pointer region
3320 * @hw: pointer to hardware structure
3321 * @ptr: pointer offset in eeprom
3322 * @size: size of section pointed by ptr, if 0 first word will be used as size
3323 * @csum: address of checksum to update
3325 * Returns error status for any failure
3327 static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
3328 u16 size, u16 *csum, u16 *buffer,
3329 u32 buffer_size)
3331 u16 buf[256];
3332 s32 status;
3333 u16 length, bufsz, i, start;
3334 u16 *local_buffer;
3336 bufsz = sizeof(buf) / sizeof(buf[0]);
3338 /* Read a chunk at the pointer location */
3339 if (!buffer) {
3340 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
3341 if (status) {
3342 DEBUGOUT("Failed to read EEPROM image\n");
3343 return status;
3345 local_buffer = buf;
3346 } else {
3347 if (buffer_size < ptr)
3348 return IXGBE_ERR_PARAM;
3349 local_buffer = &buffer[ptr];
3352 if (size) {
3353 start = 0;
3354 length = size;
3355 } else {
3356 start = 1;
3357 length = local_buffer[0];
3359 /* Skip pointer section if length is invalid. */
3360 if (length == 0xFFFF || length == 0 ||
3361 (ptr + length) >= hw->eeprom.word_size)
3362 return IXGBE_SUCCESS;
3365 if (buffer && ((u32)start + (u32)length > buffer_size))
3366 return IXGBE_ERR_PARAM;
3368 for (i = start; length; i++, length--) {
3369 if (i == bufsz && !buffer) {
3370 ptr += bufsz;
3371 i = 0;
3372 if (length < bufsz)
3373 bufsz = length;
3375 /* Read a chunk at the pointer location */
3376 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
3377 bufsz, buf);
3378 if (status) {
3379 DEBUGOUT("Failed to read EEPROM image\n");
3380 return status;
3383 *csum += local_buffer[i];
3385 return IXGBE_SUCCESS;
3389 * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
3390 * @hw: pointer to hardware structure
3391 * @buffer: pointer to buffer containing calculated checksum
3392 * @buffer_size: size of buffer
3394 * Returns a negative error code on error, or the 16-bit checksum
3396 s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
3398 u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
3399 u16 *local_buffer;
3400 s32 status;
3401 u16 checksum = 0;
3402 u16 pointer, i, size;
3404 DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
3406 hw->eeprom.ops.init_params(hw);
3408 if (!buffer) {
3409 /* Read pointer area */
3410 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
3411 IXGBE_EEPROM_LAST_WORD + 1,
3412 eeprom_ptrs);
3413 if (status) {
3414 DEBUGOUT("Failed to read EEPROM image\n");
3415 return status;
3417 local_buffer = eeprom_ptrs;
3418 } else {
3419 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
3420 return IXGBE_ERR_PARAM;
3421 local_buffer = buffer;
3425 * For X550 hardware include 0x0-0x41 in the checksum, skip the
3426 * checksum word itself
3428 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
3429 if (i != IXGBE_EEPROM_CHECKSUM)
3430 checksum += local_buffer[i];
3433 * Include all data from pointers 0x3, 0x6-0xE. This excludes the
3434 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
3436 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
3437 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
3438 continue;
3440 pointer = local_buffer[i];
3442 /* Skip pointer section if the pointer is invalid. */
3443 if (pointer == 0xFFFF || pointer == 0 ||
3444 pointer >= hw->eeprom.word_size)
3445 continue;
3447 switch (i) {
3448 case IXGBE_PCIE_GENERAL_PTR:
3449 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
3450 break;
3451 case IXGBE_PCIE_CONFIG0_PTR:
3452 case IXGBE_PCIE_CONFIG1_PTR:
3453 size = IXGBE_PCIE_CONFIG_SIZE;
3454 break;
3455 default:
3456 size = 0;
3457 break;
3460 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
3461 buffer, buffer_size);
3462 if (status)
3463 return status;
3466 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
3468 return (s32)checksum;
3472 * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
3473 * @hw: pointer to hardware structure
3475 * Returns a negative error code on error, or the 16-bit checksum
3477 s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
3479 return ixgbe_calc_checksum_X550(hw, NULL, 0);
3483 * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
3484 * @hw: pointer to hardware structure
3485 * @checksum_val: calculated checksum
3487 * Performs checksum calculation and validates the EEPROM checksum. If the
3488 * caller does not need checksum_val, the value can be NULL.
3490 s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
3492 s32 status;
3493 u16 checksum;
3494 u16 read_checksum = 0;
3496 DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
3498 /* Read the first word from the EEPROM. If this times out or fails, do
3499 * not continue or we could be in for a very long wait while every
3500 * EEPROM read fails
3502 status = hw->eeprom.ops.read(hw, 0, &checksum);
3503 if (status) {
3504 DEBUGOUT("EEPROM read failed\n");
3505 return status;
3508 status = hw->eeprom.ops.calc_checksum(hw);
3509 if (status < 0)
3510 return status;
3512 checksum = (u16)(status & 0xffff);
3514 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3515 &read_checksum);
3516 if (status)
3517 return status;
3519 /* Verify read checksum from EEPROM is the same as
3520 * calculated checksum
3522 if (read_checksum != checksum) {
3523 status = IXGBE_ERR_EEPROM_CHECKSUM;
3524 ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
3525 "Invalid EEPROM checksum");
3528 /* If the user cares, return the calculated checksum */
3529 if (checksum_val)
3530 *checksum_val = checksum;
3532 return status;
3536 * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
3537 * @hw: pointer to hardware structure
3539 * After writing EEPROM to shadow RAM using EEWR register, software calculates
3540 * checksum and updates the EEPROM and instructs the hardware to update
3541 * the flash.
3543 s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
3545 s32 status;
3546 u16 checksum = 0;
3548 DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
3550 /* Read the first word from the EEPROM. If this times out or fails, do
3551 * not continue or we could be in for a very long wait while every
3552 * EEPROM read fails
3554 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
3555 if (status) {
3556 DEBUGOUT("EEPROM read failed\n");
3557 return status;
3560 status = ixgbe_calc_eeprom_checksum_X550(hw);
3561 if (status < 0)
3562 return status;
3564 checksum = (u16)(status & 0xffff);
3566 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
3567 checksum);
3568 if (status)
3569 return status;
3571 status = ixgbe_update_flash_X550(hw);
3573 return status;
3577 * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
3578 * @hw: pointer to hardware structure
3580 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
3582 s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
3584 s32 status = IXGBE_SUCCESS;
3585 union ixgbe_hic_hdr2 buffer;
3587 DEBUGFUNC("ixgbe_update_flash_X550");
3589 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
3590 buffer.req.buf_lenh = 0;
3591 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
3592 buffer.req.checksum = FW_DEFAULT_CHECKSUM;
3594 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
3595 sizeof(buffer),
3596 IXGBE_HI_COMMAND_TIMEOUT, FALSE);
3598 return status;
3602 * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
3603 * @hw: pointer to hardware structure
3605 * Determines physical layer capabilities of the current configuration.
3607 u64 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
3609 u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
3610 u16 ext_ability = 0;
3612 DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
3614 hw->phy.ops.identify(hw);
3616 switch (hw->phy.type) {
3617 case ixgbe_phy_x550em_kr:
3618 if (hw->mac.type == ixgbe_mac_X550EM_a) {
3619 if (hw->phy.nw_mng_if_sel &
3620 IXGBE_NW_MNG_IF_SEL_PHY_SPEED_2_5G) {
3621 physical_layer =
3622 IXGBE_PHYSICAL_LAYER_2500BASE_KX;
3623 break;
3624 } else if (hw->device_id ==
3625 IXGBE_DEV_ID_X550EM_A_KR_L) {
3626 physical_layer =
3627 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3628 break;
3631 /* fall through */
3632 case ixgbe_phy_x550em_xfi:
3633 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
3634 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3635 break;
3636 case ixgbe_phy_x550em_kx4:
3637 physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
3638 IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3639 break;
3640 case ixgbe_phy_x550em_ext_t:
3641 hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
3642 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
3643 &ext_ability);
3644 if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
3645 physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
3646 if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
3647 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3648 break;
3649 case ixgbe_phy_fw:
3650 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_1GB_FULL)
3651 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3652 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_100_FULL)
3653 physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
3654 if (hw->phy.speeds_supported & IXGBE_LINK_SPEED_10_FULL)
3655 physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
3656 break;
3657 case ixgbe_phy_sgmii:
3658 physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3659 break;
3660 case ixgbe_phy_ext_1g_t:
3661 physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3662 break;
3663 default:
3664 break;
3667 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
3668 physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
3670 return physical_layer;
3674 * ixgbe_get_bus_info_x550em - Set PCI bus info
3675 * @hw: pointer to hardware structure
3677 * Sets bus link width and speed to unknown because X550em is
3678 * not a PCI device.
3680 s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
3683 DEBUGFUNC("ixgbe_get_bus_info_x550em");
3685 hw->bus.width = ixgbe_bus_width_unknown;
3686 hw->bus.speed = ixgbe_bus_speed_unknown;
3688 hw->mac.ops.set_lan_id(hw);
3690 return IXGBE_SUCCESS;
3694 * ixgbe_disable_rx_x550 - Disable RX unit
3696 * Enables the Rx DMA unit for x550
3698 void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
3700 u32 rxctrl, pfdtxgswc;
3701 s32 status;
3702 struct ixgbe_hic_disable_rxen fw_cmd;
3704 DEBUGFUNC("ixgbe_enable_rx_dma_x550");
3706 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3707 if (rxctrl & IXGBE_RXCTRL_RXEN) {
3708 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
3709 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
3710 pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
3711 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
3712 hw->mac.set_lben = TRUE;
3713 } else {
3714 hw->mac.set_lben = FALSE;
3717 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
3718 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
3719 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
3720 fw_cmd.port_number = (u8)hw->bus.lan_id;
3722 status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
3723 sizeof(struct ixgbe_hic_disable_rxen),
3724 IXGBE_HI_COMMAND_TIMEOUT, TRUE);
3726 /* If we fail - disable RX using register write */
3727 if (status) {
3728 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
3729 if (rxctrl & IXGBE_RXCTRL_RXEN) {
3730 rxctrl &= ~IXGBE_RXCTRL_RXEN;
3731 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
3738 * ixgbe_enter_lplu_x550em - Transition to low power states
3739 * @hw: pointer to hardware structure
3741 * Configures Low Power Link Up on transition to low power states
3742 * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
3743 * X557 PHY immediately prior to entering LPLU.
3745 s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
3747 u16 an_10g_cntl_reg, autoneg_reg, speed;
3748 s32 status;
3749 ixgbe_link_speed lcd_speed;
3750 u32 save_autoneg;
3751 bool link_up;
3753 /* SW LPLU not required on later HW revisions. */
3754 if ((hw->mac.type == ixgbe_mac_X550EM_x) &&
3755 (IXGBE_FUSES0_REV_MASK &
3756 IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0))))
3757 return IXGBE_SUCCESS;
3759 /* If blocked by MNG FW, then don't restart AN */
3760 if (ixgbe_check_reset_blocked(hw))
3761 return IXGBE_SUCCESS;
3763 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3764 if (status != IXGBE_SUCCESS)
3765 return status;
3767 status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
3769 if (status != IXGBE_SUCCESS)
3770 return status;
3772 /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
3773 * disabled, then force link down by entering low power mode.
3775 if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
3776 !(hw->wol_enabled || ixgbe_mng_present(hw)))
3777 return ixgbe_set_copper_phy_power(hw, FALSE);
3779 /* Determine LCD */
3780 status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
3782 if (status != IXGBE_SUCCESS)
3783 return status;
3785 /* If no valid LCD link speed, then force link down and exit. */
3786 if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
3787 return ixgbe_set_copper_phy_power(hw, FALSE);
3789 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
3790 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3791 &speed);
3793 if (status != IXGBE_SUCCESS)
3794 return status;
3796 /* If no link now, speed is invalid so take link down */
3797 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
3798 if (status != IXGBE_SUCCESS)
3799 return ixgbe_set_copper_phy_power(hw, FALSE);
3801 /* clear everything but the speed bits */
3802 speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
3804 /* If current speed is already LCD, then exit. */
3805 if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
3806 (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
3807 ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
3808 (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
3809 return status;
3811 /* Clear AN completed indication */
3812 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
3813 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3814 &autoneg_reg);
3816 if (status != IXGBE_SUCCESS)
3817 return status;
3819 status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
3820 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3821 &an_10g_cntl_reg);
3823 if (status != IXGBE_SUCCESS)
3824 return status;
3826 status = hw->phy.ops.read_reg(hw,
3827 IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
3828 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3829 &autoneg_reg);
3831 if (status != IXGBE_SUCCESS)
3832 return status;
3834 save_autoneg = hw->phy.autoneg_advertised;
3836 /* Setup link at least common link speed */
3837 status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
3839 /* restore autoneg from before setting lplu speed */
3840 hw->phy.autoneg_advertised = save_autoneg;
3842 return status;
3846 * ixgbe_get_lcd_x550em - Determine lowest common denominator
3847 * @hw: pointer to hardware structure
3848 * @lcd_speed: pointer to lowest common link speed
3850 * Determine lowest common link speed with link partner.
3852 s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
3854 u16 an_lp_status;
3855 s32 status;
3856 u16 word = hw->eeprom.ctrl_word_3;
3858 *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
3860 status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
3861 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
3862 &an_lp_status);
3864 if (status != IXGBE_SUCCESS)
3865 return status;
3867 /* If link partner advertised 1G, return 1G */
3868 if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
3869 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
3870 return status;
3873 /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
3874 if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
3875 (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
3876 return status;
3878 /* Link partner not capable of lower speeds, return 10G */
3879 *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
3880 return status;
3884 * ixgbe_setup_fc_X550em - Set up flow control
3885 * @hw: pointer to hardware structure
3887 * Called at init time to set up flow control.
3889 s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
3891 s32 ret_val = IXGBE_SUCCESS;
3892 u32 pause, asm_dir, reg_val;
3894 DEBUGFUNC("ixgbe_setup_fc_X550em");
3896 /* Validate the requested mode */
3897 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
3898 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3899 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
3900 ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
3901 goto out;
3904 /* 10gig parts do not have a word in the EEPROM to determine the
3905 * default flow control setting, so we explicitly set it to full.
3907 if (hw->fc.requested_mode == ixgbe_fc_default)
3908 hw->fc.requested_mode = ixgbe_fc_full;
3910 /* Determine PAUSE and ASM_DIR bits. */
3911 switch (hw->fc.requested_mode) {
3912 case ixgbe_fc_none:
3913 pause = 0;
3914 asm_dir = 0;
3915 break;
3916 case ixgbe_fc_tx_pause:
3917 pause = 0;
3918 asm_dir = 1;
3919 break;
3920 case ixgbe_fc_rx_pause:
3921 /* Rx Flow control is enabled and Tx Flow control is
3922 * disabled by software override. Since there really
3923 * isn't a way to advertise that we are capable of RX
3924 * Pause ONLY, we will advertise that we support both
3925 * symmetric and asymmetric Rx PAUSE, as such we fall
3926 * through to the fc_full statement. Later, we will
3927 * disable the adapter's ability to send PAUSE frames.
3929 case ixgbe_fc_full:
3930 pause = 1;
3931 asm_dir = 1;
3932 break;
3933 default:
3934 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
3935 "Flow control param set incorrectly\n");
3936 ret_val = IXGBE_ERR_CONFIG;
3937 goto out;
3940 switch (hw->device_id) {
3941 case IXGBE_DEV_ID_X550EM_X_KR:
3942 case IXGBE_DEV_ID_X550EM_A_KR:
3943 case IXGBE_DEV_ID_X550EM_A_KR_L:
3944 ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
3945 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3946 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
3947 if (ret_val != IXGBE_SUCCESS)
3948 goto out;
3949 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
3950 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
3951 if (pause)
3952 reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
3953 if (asm_dir)
3954 reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
3955 ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
3956 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
3957 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
3959 /* This device does not fully support AN. */
3960 hw->fc.disable_fc_autoneg = TRUE;
3961 break;
3962 case IXGBE_DEV_ID_X550EM_X_XFI:
3963 hw->fc.disable_fc_autoneg = TRUE;
3964 break;
3965 default:
3966 break;
3969 out:
3970 return ret_val;
3974 * ixgbe_fc_autoneg_backplane_x550em_a - Enable flow control IEEE clause 37
3975 * @hw: pointer to hardware structure
3977 * Enable flow control according to IEEE clause 37.
3979 void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw)
3981 u32 link_s1, lp_an_page_low, an_cntl_1;
3982 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3983 ixgbe_link_speed speed;
3984 bool link_up;
3986 /* AN should have completed when the cable was plugged in.
3987 * Look for reasons to bail out. Bail out if:
3988 * - FC autoneg is disabled, or if
3989 * - link is not up.
3991 if (hw->fc.disable_fc_autoneg) {
3992 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
3993 "Flow control autoneg is disabled");
3994 goto out;
3997 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
3998 if (!link_up) {
3999 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4000 goto out;
4003 /* Check at auto-negotiation has completed */
4004 status = hw->mac.ops.read_iosf_sb_reg(hw,
4005 IXGBE_KRM_LINK_S1(hw->bus.lan_id),
4006 IXGBE_SB_IOSF_TARGET_KR_PHY, &link_s1);
4008 if (status != IXGBE_SUCCESS ||
4009 (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) {
4010 DEBUGOUT("Auto-Negotiation did not complete\n");
4011 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4012 goto out;
4015 /* Read the 10g AN autoc and LP ability registers and resolve
4016 * local flow control settings accordingly
4018 status = hw->mac.ops.read_iosf_sb_reg(hw,
4019 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4020 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl_1);
4022 if (status != IXGBE_SUCCESS) {
4023 DEBUGOUT("Auto-Negotiation did not complete\n");
4024 goto out;
4027 status = hw->mac.ops.read_iosf_sb_reg(hw,
4028 IXGBE_KRM_LP_BASE_PAGE_HIGH(hw->bus.lan_id),
4029 IXGBE_SB_IOSF_TARGET_KR_PHY, &lp_an_page_low);
4031 if (status != IXGBE_SUCCESS) {
4032 DEBUGOUT("Auto-Negotiation did not complete\n");
4033 goto out;
4036 status = ixgbe_negotiate_fc(hw, an_cntl_1, lp_an_page_low,
4037 IXGBE_KRM_AN_CNTL_1_SYM_PAUSE,
4038 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE,
4039 IXGBE_KRM_LP_BASE_PAGE_HIGH_SYM_PAUSE,
4040 IXGBE_KRM_LP_BASE_PAGE_HIGH_ASM_PAUSE);
4042 out:
4043 if (status == IXGBE_SUCCESS) {
4044 hw->fc.fc_was_autonegged = TRUE;
4045 } else {
4046 hw->fc.fc_was_autonegged = FALSE;
4047 hw->fc.current_mode = hw->fc.requested_mode;
4052 * ixgbe_fc_autoneg_fiber_x550em_a - passthrough FC settings
4053 * @hw: pointer to hardware structure
4056 void ixgbe_fc_autoneg_fiber_x550em_a(struct ixgbe_hw *hw)
4058 hw->fc.fc_was_autonegged = FALSE;
4059 hw->fc.current_mode = hw->fc.requested_mode;
4063 * ixgbe_fc_autoneg_sgmii_x550em_a - Enable flow control IEEE clause 37
4064 * @hw: pointer to hardware structure
4066 * Enable flow control according to IEEE clause 37.
4068 void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw)
4070 s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4071 u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
4072 ixgbe_link_speed speed;
4073 bool link_up;
4075 /* AN should have completed when the cable was plugged in.
4076 * Look for reasons to bail out. Bail out if:
4077 * - FC autoneg is disabled, or if
4078 * - link is not up.
4080 if (hw->fc.disable_fc_autoneg) {
4081 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4082 "Flow control autoneg is disabled");
4083 goto out;
4086 hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
4087 if (!link_up) {
4088 ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down");
4089 goto out;
4092 /* Check if auto-negotiation has completed */
4093 status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info);
4094 if (status != IXGBE_SUCCESS ||
4095 !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) {
4096 DEBUGOUT("Auto-Negotiation did not complete\n");
4097 status = IXGBE_ERR_FC_NOT_NEGOTIATED;
4098 goto out;
4101 /* Negotiate the flow control */
4102 status = ixgbe_negotiate_fc(hw, info[0], info[0],
4103 FW_PHY_ACT_GET_LINK_INFO_FC_RX,
4104 FW_PHY_ACT_GET_LINK_INFO_FC_TX,
4105 FW_PHY_ACT_GET_LINK_INFO_LP_FC_RX,
4106 FW_PHY_ACT_GET_LINK_INFO_LP_FC_TX);
4108 out:
4109 if (status == IXGBE_SUCCESS) {
4110 hw->fc.fc_was_autonegged = TRUE;
4111 } else {
4112 hw->fc.fc_was_autonegged = FALSE;
4113 hw->fc.current_mode = hw->fc.requested_mode;
4118 * ixgbe_setup_fc_backplane_x550em_a - Set up flow control
4119 * @hw: pointer to hardware structure
4121 * Called at init time to set up flow control.
4123 s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
4125 s32 status = IXGBE_SUCCESS;
4126 u32 an_cntl = 0;
4128 DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
4130 /* Validate the requested mode */
4131 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
4132 ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
4133 "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
4134 return IXGBE_ERR_INVALID_LINK_SETTINGS;
4137 if (hw->fc.requested_mode == ixgbe_fc_default)
4138 hw->fc.requested_mode = ixgbe_fc_full;
4140 /* Set up the 1G and 10G flow control advertisement registers so the
4141 * HW will be able to do FC autoneg once the cable is plugged in. If
4142 * we link at 10G, the 1G advertisement is harmless and vice versa.
4144 status = hw->mac.ops.read_iosf_sb_reg(hw,
4145 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4146 IXGBE_SB_IOSF_TARGET_KR_PHY, &an_cntl);
4148 if (status != IXGBE_SUCCESS) {
4149 DEBUGOUT("Auto-Negotiation did not complete\n");
4150 return status;
4153 /* The possible values of fc.requested_mode are:
4154 * 0: Flow control is completely disabled
4155 * 1: Rx flow control is enabled (we can receive pause frames,
4156 * but not send pause frames).
4157 * 2: Tx flow control is enabled (we can send pause frames but
4158 * we do not support receiving pause frames).
4159 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4160 * other: Invalid.
4162 switch (hw->fc.requested_mode) {
4163 case ixgbe_fc_none:
4164 /* Flow control completely disabled by software override. */
4165 an_cntl &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4166 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
4167 break;
4168 case ixgbe_fc_tx_pause:
4169 /* Tx Flow control is enabled, and Rx Flow control is
4170 * disabled by software override.
4172 an_cntl |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4173 an_cntl &= ~IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
4174 break;
4175 case ixgbe_fc_rx_pause:
4176 /* Rx Flow control is enabled and Tx Flow control is
4177 * disabled by software override. Since there really
4178 * isn't a way to advertise that we are capable of RX
4179 * Pause ONLY, we will advertise that we support both
4180 * symmetric and asymmetric Rx PAUSE, as such we fall
4181 * through to the fc_full statement. Later, we will
4182 * disable the adapter's ability to send PAUSE frames.
4184 case ixgbe_fc_full:
4185 /* Flow control (both Rx and Tx) is enabled by SW override. */
4186 an_cntl |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
4187 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
4188 break;
4189 default:
4190 ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
4191 "Flow control param set incorrectly\n");
4192 return IXGBE_ERR_CONFIG;
4195 status = hw->mac.ops.write_iosf_sb_reg(hw,
4196 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
4197 IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
4199 /* Restart auto-negotiation. */
4200 status = ixgbe_restart_an_internal_phy_x550em(hw);
4202 return status;
4206 * ixgbe_set_mux - Set mux for port 1 access with CS4227
4207 * @hw: pointer to hardware structure
4208 * @state: set mux if 1, clear if 0
4210 static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
4212 u32 esdp;
4214 if (!hw->bus.lan_id)
4215 return;
4216 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
4217 if (state)
4218 esdp |= IXGBE_ESDP_SDP1;
4219 else
4220 esdp &= ~IXGBE_ESDP_SDP1;
4221 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
4222 IXGBE_WRITE_FLUSH(hw);
4226 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
4227 * @hw: pointer to hardware structure
4228 * @mask: Mask to specify which semaphore to acquire
4230 * Acquires the SWFW semaphore and sets the I2C MUX
4232 s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4234 s32 status;
4236 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
4238 status = ixgbe_acquire_swfw_sync_X540(hw, mask);
4239 if (status)
4240 return status;
4242 if (mask & IXGBE_GSSR_I2C_MASK)
4243 ixgbe_set_mux(hw, 1);
4245 return IXGBE_SUCCESS;
4249 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
4250 * @hw: pointer to hardware structure
4251 * @mask: Mask to specify which semaphore to release
4253 * Releases the SWFW semaphore and sets the I2C MUX
4255 void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
4257 DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
4259 if (mask & IXGBE_GSSR_I2C_MASK)
4260 ixgbe_set_mux(hw, 0);
4262 ixgbe_release_swfw_sync_X540(hw, mask);
4266 * ixgbe_acquire_swfw_sync_X550a - Acquire SWFW semaphore
4267 * @hw: pointer to hardware structure
4268 * @mask: Mask to specify which semaphore to acquire
4270 * Acquires the SWFW semaphore and get the shared phy token as needed
4272 static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4274 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4275 int retries = FW_PHY_TOKEN_RETRIES;
4276 s32 status = IXGBE_SUCCESS;
4278 DEBUGFUNC("ixgbe_acquire_swfw_sync_X550a");
4280 while (--retries) {
4281 status = IXGBE_SUCCESS;
4282 if (hmask)
4283 status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
4284 if (status) {
4285 DEBUGOUT1("Could not acquire SWFW semaphore, Status = %d\n",
4286 status);
4287 return status;
4289 if (!(mask & IXGBE_GSSR_TOKEN_SM))
4290 return IXGBE_SUCCESS;
4292 status = ixgbe_get_phy_token(hw);
4293 if (status == IXGBE_ERR_TOKEN_RETRY)
4294 DEBUGOUT1("Could not acquire PHY token, Status = %d\n",
4295 status);
4297 if (status == IXGBE_SUCCESS)
4298 return IXGBE_SUCCESS;
4300 if (hmask)
4301 ixgbe_release_swfw_sync_X540(hw, hmask);
4303 if (status != IXGBE_ERR_TOKEN_RETRY) {
4304 DEBUGOUT1("Unable to retry acquiring the PHY token, Status = %d\n",
4305 status);
4306 return status;
4310 DEBUGOUT1("Semaphore acquisition retries failed!: PHY ID = 0x%08X\n",
4311 hw->phy.id);
4312 return status;
4316 * ixgbe_release_swfw_sync_X550a - Release SWFW semaphore
4317 * @hw: pointer to hardware structure
4318 * @mask: Mask to specify which semaphore to release
4320 * Releases the SWFW semaphore and puts the shared phy token as needed
4322 static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *hw, u32 mask)
4324 u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
4326 DEBUGFUNC("ixgbe_release_swfw_sync_X550a");
4328 if (mask & IXGBE_GSSR_TOKEN_SM)
4329 ixgbe_put_phy_token(hw);
4331 if (hmask)
4332 ixgbe_release_swfw_sync_X540(hw, hmask);
4336 * ixgbe_read_phy_reg_x550a - Reads specified PHY register
4337 * @hw: pointer to hardware structure
4338 * @reg_addr: 32 bit address of PHY register to read
4339 * @phy_data: Pointer to read data from PHY register
4341 * Reads a value from a specified PHY register using the SWFW lock and PHY
4342 * Token. The PHY Token is needed since the MDIO is shared between to MAC
4343 * instances.
4345 s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4346 u32 device_type, u16 *phy_data)
4348 s32 status;
4349 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4351 DEBUGFUNC("ixgbe_read_phy_reg_x550a");
4353 if (hw->mac.ops.acquire_swfw_sync(hw, mask))
4354 return IXGBE_ERR_SWFW_SYNC;
4356 status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data);
4358 hw->mac.ops.release_swfw_sync(hw, mask);
4360 return status;
4364 * ixgbe_write_phy_reg_x550a - Writes specified PHY register
4365 * @hw: pointer to hardware structure
4366 * @reg_addr: 32 bit PHY register to write
4367 * @device_type: 5 bit device type
4368 * @phy_data: Data to write to the PHY register
4370 * Writes a value to specified PHY register using the SWFW lock and PHY Token.
4371 * The PHY Token is needed since the MDIO is shared between to MAC instances.
4373 s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
4374 u32 device_type, u16 phy_data)
4376 s32 status;
4377 u32 mask = hw->phy.phy_semaphore_mask | IXGBE_GSSR_TOKEN_SM;
4379 DEBUGFUNC("ixgbe_write_phy_reg_x550a");
4381 if (hw->mac.ops.acquire_swfw_sync(hw, mask) == IXGBE_SUCCESS) {
4382 status = hw->phy.ops.write_reg_mdi(hw, reg_addr, device_type,
4383 phy_data);
4384 hw->mac.ops.release_swfw_sync(hw, mask);
4385 } else {
4386 status = IXGBE_ERR_SWFW_SYNC;
4389 return status;
4393 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
4394 * @hw: pointer to hardware structure
4396 * Handle external Base T PHY interrupt. If high temperature
4397 * failure alarm then return error, else if link status change
4398 * then setup internal/external PHY link
4400 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
4401 * failure alarm, else return PHY access status.
4403 s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
4405 bool lsc;
4406 u32 status;
4408 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
4410 if (status != IXGBE_SUCCESS)
4411 return status;
4413 if (lsc)
4414 return ixgbe_setup_internal_phy(hw);
4416 return IXGBE_SUCCESS;
4420 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
4421 * @hw: pointer to hardware structure
4422 * @speed: new link speed
4423 * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
4425 * Setup internal/external PHY link speed based on link speed, then set
4426 * external PHY auto advertised link speed.
4428 * Returns error status for any failure
4430 s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
4431 ixgbe_link_speed speed,
4432 bool autoneg_wait_to_complete)
4434 s32 status;
4435 ixgbe_link_speed force_speed;
4437 DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
4439 /* Setup internal/external PHY link speed to iXFI (10G), unless
4440 * only 1G is auto advertised then setup KX link.
4442 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
4443 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
4444 else
4445 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
4447 /* If X552 and internal link mode is XFI, then setup XFI internal link.
4449 if (hw->mac.type == ixgbe_mac_X550EM_x &&
4450 !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
4451 status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
4453 if (status != IXGBE_SUCCESS)
4454 return status;
4457 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
4461 * ixgbe_check_link_t_X550em - Determine link and speed status
4462 * @hw: pointer to hardware structure
4463 * @speed: pointer to link speed
4464 * @link_up: TRUE when link is up
4465 * @link_up_wait_to_complete: bool used to wait for link up or not
4467 * Check that both the MAC and X557 external PHY have link.
4469 s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
4470 bool *link_up, bool link_up_wait_to_complete)
4472 u32 status;
4473 u16 i, autoneg_status = 0;
4475 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
4476 return IXGBE_ERR_CONFIG;
4478 status = ixgbe_check_mac_link_generic(hw, speed, link_up,
4479 link_up_wait_to_complete);
4481 /* If check link fails or MAC link is not up, then return */
4482 if (status != IXGBE_SUCCESS || !(*link_up))
4483 return status;
4485 /* MAC link is up, so check external PHY link.
4486 * X557 PHY. Link status is latching low, and can only be used to detect
4487 * link drop, and not the current status of the link without performing
4488 * back-to-back reads.
4490 for (i = 0; i < 2; i++) {
4491 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
4492 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
4493 &autoneg_status);
4495 if (status != IXGBE_SUCCESS)
4496 return status;
4499 /* If external PHY link is not up, then indicate link not up */
4500 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
4501 *link_up = FALSE;
4503 return IXGBE_SUCCESS;
4507 * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
4508 * @hw: pointer to hardware structure
4510 s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
4512 s32 status;
4514 status = ixgbe_reset_phy_generic(hw);
4516 if (status != IXGBE_SUCCESS)
4517 return status;
4519 /* Configure Link Status Alarm and Temperature Threshold interrupts */
4520 return ixgbe_enable_lasi_ext_t_x550em(hw);
4524 * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
4525 * @hw: pointer to hardware structure
4526 * @led_idx: led number to turn on
4528 s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4530 u16 phy_data;
4532 DEBUGFUNC("ixgbe_led_on_t_X550em");
4534 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4535 return IXGBE_ERR_PARAM;
4537 /* To turn on the LED, set mode to ON. */
4538 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4539 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4540 phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
4541 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4542 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4544 /* Some designs have the LEDs wired to the MAC */
4545 return ixgbe_led_on_generic(hw, led_idx);
4549 * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
4550 * @hw: pointer to hardware structure
4551 * @led_idx: led number to turn off
4553 s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
4555 u16 phy_data;
4557 DEBUGFUNC("ixgbe_led_off_t_X550em");
4559 if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
4560 return IXGBE_ERR_PARAM;
4562 /* To turn on the LED, set mode to ON. */
4563 ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4564 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
4565 phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
4566 ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
4567 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
4569 /* Some designs have the LEDs wired to the MAC */
4570 return ixgbe_led_off_generic(hw, led_idx);
4574 * ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
4575 * @hw: pointer to the HW structure
4576 * @maj: driver version major number
4577 * @min: driver version minor number
4578 * @build: driver version build number
4579 * @sub: driver version sub build number
4580 * @len: length of driver_ver string
4581 * @driver_ver: driver string
4583 * Sends driver version number to firmware through the manageability
4584 * block. On success return IXGBE_SUCCESS
4585 * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
4586 * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
4588 s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
4589 u8 build, u8 sub, u16 len, const char *driver_ver)
4591 struct ixgbe_hic_drv_info2 fw_cmd;
4592 s32 ret_val = IXGBE_SUCCESS;
4593 int i;
4595 DEBUGFUNC("ixgbe_set_fw_drv_ver_x550");
4597 if ((len == 0) || (driver_ver == NULL) ||
4598 (len > sizeof(fw_cmd.driver_string)))
4599 return IXGBE_ERR_INVALID_ARGUMENT;
4601 fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
4602 fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
4603 fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
4604 fw_cmd.port_num = (u8)hw->bus.func;
4605 fw_cmd.ver_maj = maj;
4606 fw_cmd.ver_min = min;
4607 fw_cmd.ver_build = build;
4608 fw_cmd.ver_sub = sub;
4609 fw_cmd.hdr.checksum = 0;
4610 memcpy(fw_cmd.driver_string, driver_ver, len);
4611 fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
4612 (FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
4614 for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
4615 ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
4616 sizeof(fw_cmd),
4617 IXGBE_HI_COMMAND_TIMEOUT,
4618 TRUE);
4619 if (ret_val != IXGBE_SUCCESS)
4620 continue;
4622 if (fw_cmd.hdr.cmd_or_resp.ret_status ==
4623 FW_CEM_RESP_STATUS_SUCCESS)
4624 ret_val = IXGBE_SUCCESS;
4625 else
4626 ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
4628 break;
4631 return ret_val;