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