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