Bug Summary

File:dev/pci/ixgbe_x550.c
Warning:line 1874, column 2
Value stored to 'status' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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