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