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