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