ixgbe_x540.c revision 1.11.2.2 1 1.11.2.2 jdolecek /******************************************************************************
2 1.11.2.2 jdolecek
3 1.11.2.2 jdolecek Copyright (c) 2001-2017, Intel Corporation
4 1.11.2.2 jdolecek All rights reserved.
5 1.11.2.2 jdolecek
6 1.11.2.2 jdolecek Redistribution and use in source and binary forms, with or without
7 1.11.2.2 jdolecek modification, are permitted provided that the following conditions are met:
8 1.11.2.2 jdolecek
9 1.11.2.2 jdolecek 1. Redistributions of source code must retain the above copyright notice,
10 1.11.2.2 jdolecek this list of conditions and the following disclaimer.
11 1.11.2.2 jdolecek
12 1.11.2.2 jdolecek 2. Redistributions in binary form must reproduce the above copyright
13 1.11.2.2 jdolecek notice, this list of conditions and the following disclaimer in the
14 1.11.2.2 jdolecek documentation and/or other materials provided with the distribution.
15 1.11.2.2 jdolecek
16 1.11.2.2 jdolecek 3. Neither the name of the Intel Corporation nor the names of its
17 1.11.2.2 jdolecek contributors may be used to endorse or promote products derived from
18 1.11.2.2 jdolecek this software without specific prior written permission.
19 1.11.2.2 jdolecek
20 1.11.2.2 jdolecek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 1.11.2.2 jdolecek AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.11.2.2 jdolecek IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.11.2.2 jdolecek ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 1.11.2.2 jdolecek LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.11.2.2 jdolecek CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.11.2.2 jdolecek SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.11.2.2 jdolecek INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.11.2.2 jdolecek CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.11.2.2 jdolecek ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.11.2.2 jdolecek POSSIBILITY OF SUCH DAMAGE.
31 1.11.2.2 jdolecek
32 1.11.2.2 jdolecek ******************************************************************************/
33 1.11.2.2 jdolecek /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 320688 2017-07-05 17:27:03Z erj $*/
34 1.11.2.2 jdolecek
35 1.11.2.2 jdolecek #include "ixgbe_x540.h"
36 1.11.2.2 jdolecek #include "ixgbe_type.h"
37 1.11.2.2 jdolecek #include "ixgbe_api.h"
38 1.11.2.2 jdolecek #include "ixgbe_common.h"
39 1.11.2.2 jdolecek #include "ixgbe_phy.h"
40 1.11.2.2 jdolecek
41 1.11.2.2 jdolecek #define IXGBE_X540_MAX_TX_QUEUES 128
42 1.11.2.2 jdolecek #define IXGBE_X540_MAX_RX_QUEUES 128
43 1.11.2.2 jdolecek #define IXGBE_X540_RAR_ENTRIES 128
44 1.11.2.2 jdolecek #define IXGBE_X540_MC_TBL_SIZE 128
45 1.11.2.2 jdolecek #define IXGBE_X540_VFT_TBL_SIZE 128
46 1.11.2.2 jdolecek #define IXGBE_X540_RX_PB_SIZE 384
47 1.11.2.2 jdolecek
48 1.11.2.2 jdolecek static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
49 1.11.2.2 jdolecek static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw);
50 1.11.2.2 jdolecek static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw);
51 1.11.2.2 jdolecek
52 1.11.2.2 jdolecek /**
53 1.11.2.2 jdolecek * ixgbe_init_ops_X540 - Inits func ptrs and MAC type
54 1.11.2.2 jdolecek * @hw: pointer to hardware structure
55 1.11.2.2 jdolecek *
56 1.11.2.2 jdolecek * Initialize the function pointers and assign the MAC type for X540.
57 1.11.2.2 jdolecek * Does not touch the hardware.
58 1.11.2.2 jdolecek **/
59 1.11.2.2 jdolecek s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
60 1.11.2.2 jdolecek {
61 1.11.2.2 jdolecek struct ixgbe_mac_info *mac = &hw->mac;
62 1.11.2.2 jdolecek struct ixgbe_phy_info *phy = &hw->phy;
63 1.11.2.2 jdolecek struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
64 1.11.2.2 jdolecek s32 ret_val;
65 1.11.2.2 jdolecek
66 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_init_ops_X540");
67 1.11.2.2 jdolecek
68 1.11.2.2 jdolecek ret_val = ixgbe_init_phy_ops_generic(hw);
69 1.11.2.2 jdolecek ret_val = ixgbe_init_ops_generic(hw);
70 1.11.2.2 jdolecek
71 1.11.2.2 jdolecek
72 1.11.2.2 jdolecek /* EEPROM */
73 1.11.2.2 jdolecek eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
74 1.11.2.2 jdolecek eeprom->ops.read = ixgbe_read_eerd_X540;
75 1.11.2.2 jdolecek eeprom->ops.read_buffer = ixgbe_read_eerd_buffer_X540;
76 1.11.2.2 jdolecek eeprom->ops.write = ixgbe_write_eewr_X540;
77 1.11.2.2 jdolecek eeprom->ops.write_buffer = ixgbe_write_eewr_buffer_X540;
78 1.11.2.2 jdolecek eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X540;
79 1.11.2.2 jdolecek eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X540;
80 1.11.2.2 jdolecek eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X540;
81 1.11.2.2 jdolecek
82 1.11.2.2 jdolecek /* PHY */
83 1.11.2.2 jdolecek phy->ops.init = ixgbe_init_phy_ops_generic;
84 1.11.2.2 jdolecek phy->ops.reset = NULL;
85 1.11.2.2 jdolecek phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
86 1.11.2.2 jdolecek
87 1.11.2.2 jdolecek /* MAC */
88 1.11.2.2 jdolecek mac->ops.reset_hw = ixgbe_reset_hw_X540;
89 1.11.2.2 jdolecek mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_gen2;
90 1.11.2.2 jdolecek mac->ops.get_media_type = ixgbe_get_media_type_X540;
91 1.11.2.2 jdolecek mac->ops.get_supported_physical_layer =
92 1.11.2.2 jdolecek ixgbe_get_supported_physical_layer_X540;
93 1.11.2.2 jdolecek mac->ops.read_analog_reg8 = NULL;
94 1.11.2.2 jdolecek mac->ops.write_analog_reg8 = NULL;
95 1.11.2.2 jdolecek mac->ops.start_hw = ixgbe_start_hw_X540;
96 1.11.2.2 jdolecek mac->ops.get_san_mac_addr = ixgbe_get_san_mac_addr_generic;
97 1.11.2.2 jdolecek mac->ops.set_san_mac_addr = ixgbe_set_san_mac_addr_generic;
98 1.11.2.2 jdolecek mac->ops.get_device_caps = ixgbe_get_device_caps_generic;
99 1.11.2.2 jdolecek mac->ops.get_wwn_prefix = ixgbe_get_wwn_prefix_generic;
100 1.11.2.2 jdolecek mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
101 1.11.2.2 jdolecek mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
102 1.11.2.2 jdolecek mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
103 1.11.2.2 jdolecek mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540;
104 1.11.2.2 jdolecek mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
105 1.11.2.2 jdolecek mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
106 1.11.2.2 jdolecek
107 1.11.2.2 jdolecek /* RAR, Multicast, VLAN */
108 1.11.2.2 jdolecek mac->ops.set_vmdq = ixgbe_set_vmdq_generic;
109 1.11.2.2 jdolecek mac->ops.set_vmdq_san_mac = ixgbe_set_vmdq_san_mac_generic;
110 1.11.2.2 jdolecek mac->ops.clear_vmdq = ixgbe_clear_vmdq_generic;
111 1.11.2.2 jdolecek mac->ops.insert_mac_addr = ixgbe_insert_mac_addr_generic;
112 1.11.2.2 jdolecek mac->rar_highwater = 1;
113 1.11.2.2 jdolecek mac->ops.set_vfta = ixgbe_set_vfta_generic;
114 1.11.2.2 jdolecek mac->ops.set_vlvf = ixgbe_set_vlvf_generic;
115 1.11.2.2 jdolecek mac->ops.clear_vfta = ixgbe_clear_vfta_generic;
116 1.11.2.2 jdolecek mac->ops.init_uta_tables = ixgbe_init_uta_tables_generic;
117 1.11.2.2 jdolecek mac->ops.set_mac_anti_spoofing = ixgbe_set_mac_anti_spoofing;
118 1.11.2.2 jdolecek mac->ops.set_vlan_anti_spoofing = ixgbe_set_vlan_anti_spoofing;
119 1.11.2.2 jdolecek
120 1.11.2.2 jdolecek /* Link */
121 1.11.2.2 jdolecek mac->ops.get_link_capabilities =
122 1.11.2.2 jdolecek ixgbe_get_copper_link_capabilities_generic;
123 1.11.2.2 jdolecek mac->ops.setup_link = ixgbe_setup_mac_link_X540;
124 1.11.2.2 jdolecek mac->ops.setup_rxpba = ixgbe_set_rxpba_generic;
125 1.11.2.2 jdolecek mac->ops.check_link = ixgbe_check_mac_link_generic;
126 1.11.2.2 jdolecek mac->ops.bypass_rw = ixgbe_bypass_rw_generic;
127 1.11.2.2 jdolecek mac->ops.bypass_valid_rd = ixgbe_bypass_valid_rd_generic;
128 1.11.2.2 jdolecek mac->ops.bypass_set = ixgbe_bypass_set_generic;
129 1.11.2.2 jdolecek mac->ops.bypass_rd_eep = ixgbe_bypass_rd_eep_generic;
130 1.11.2.2 jdolecek
131 1.11.2.2 jdolecek
132 1.11.2.2 jdolecek mac->mcft_size = IXGBE_X540_MC_TBL_SIZE;
133 1.11.2.2 jdolecek mac->vft_size = IXGBE_X540_VFT_TBL_SIZE;
134 1.11.2.2 jdolecek mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES;
135 1.11.2.2 jdolecek mac->rx_pb_size = IXGBE_X540_RX_PB_SIZE;
136 1.11.2.2 jdolecek mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES;
137 1.11.2.2 jdolecek mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES;
138 1.11.2.2 jdolecek mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
139 1.11.2.2 jdolecek
140 1.11.2.2 jdolecek /*
141 1.11.2.2 jdolecek * FWSM register
142 1.11.2.2 jdolecek * ARC supported; valid only if manageability features are
143 1.11.2.2 jdolecek * enabled.
144 1.11.2.2 jdolecek */
145 1.11.2.2 jdolecek mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw))
146 1.11.2.2 jdolecek & IXGBE_FWSM_MODE_MASK);
147 1.11.2.2 jdolecek
148 1.11.2.2 jdolecek hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf;
149 1.11.2.2 jdolecek
150 1.11.2.2 jdolecek /* LEDs */
151 1.11.2.2 jdolecek mac->ops.blink_led_start = ixgbe_blink_led_start_X540;
152 1.11.2.2 jdolecek mac->ops.blink_led_stop = ixgbe_blink_led_stop_X540;
153 1.11.2.2 jdolecek
154 1.11.2.2 jdolecek /* Manageability interface */
155 1.11.2.2 jdolecek mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_generic;
156 1.11.2.2 jdolecek
157 1.11.2.2 jdolecek mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
158 1.11.2.2 jdolecek
159 1.11.2.2 jdolecek return ret_val;
160 1.11.2.2 jdolecek }
161 1.11.2.2 jdolecek
162 1.11.2.2 jdolecek /**
163 1.11.2.2 jdolecek * ixgbe_get_link_capabilities_X540 - Determines link capabilities
164 1.11.2.2 jdolecek * @hw: pointer to hardware structure
165 1.11.2.2 jdolecek * @speed: pointer to link speed
166 1.11.2.2 jdolecek * @autoneg: TRUE when autoneg or autotry is enabled
167 1.11.2.2 jdolecek *
168 1.11.2.2 jdolecek * Determines the link capabilities by reading the AUTOC register.
169 1.11.2.2 jdolecek **/
170 1.11.2.2 jdolecek s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
171 1.11.2.2 jdolecek ixgbe_link_speed *speed,
172 1.11.2.2 jdolecek bool *autoneg)
173 1.11.2.2 jdolecek {
174 1.11.2.2 jdolecek ixgbe_get_copper_link_capabilities_generic(hw, speed, autoneg);
175 1.11.2.2 jdolecek
176 1.11.2.2 jdolecek return IXGBE_SUCCESS;
177 1.11.2.2 jdolecek }
178 1.11.2.2 jdolecek
179 1.11.2.2 jdolecek /**
180 1.11.2.2 jdolecek * ixgbe_get_media_type_X540 - Get media type
181 1.11.2.2 jdolecek * @hw: pointer to hardware structure
182 1.11.2.2 jdolecek *
183 1.11.2.2 jdolecek * Returns the media type (fiber, copper, backplane)
184 1.11.2.2 jdolecek **/
185 1.11.2.2 jdolecek enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
186 1.11.2.2 jdolecek {
187 1.11.2.2 jdolecek UNREFERENCED_1PARAMETER(hw);
188 1.11.2.2 jdolecek return ixgbe_media_type_copper;
189 1.11.2.2 jdolecek }
190 1.11.2.2 jdolecek
191 1.11.2.2 jdolecek /**
192 1.11.2.2 jdolecek * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
193 1.11.2.2 jdolecek * @hw: pointer to hardware structure
194 1.11.2.2 jdolecek * @speed: new link speed
195 1.11.2.2 jdolecek * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
196 1.11.2.2 jdolecek **/
197 1.11.2.2 jdolecek s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
198 1.11.2.2 jdolecek ixgbe_link_speed speed,
199 1.11.2.2 jdolecek bool autoneg_wait_to_complete)
200 1.11.2.2 jdolecek {
201 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_setup_mac_link_X540");
202 1.11.2.2 jdolecek return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
203 1.11.2.2 jdolecek }
204 1.11.2.2 jdolecek
205 1.11.2.2 jdolecek /**
206 1.11.2.2 jdolecek * ixgbe_reset_hw_X540 - Perform hardware reset
207 1.11.2.2 jdolecek * @hw: pointer to hardware structure
208 1.11.2.2 jdolecek *
209 1.11.2.2 jdolecek * Resets the hardware by resetting the transmit and receive units, masks
210 1.11.2.2 jdolecek * and clears all interrupts, and perform a reset.
211 1.11.2.2 jdolecek **/
212 1.11.2.2 jdolecek s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
213 1.11.2.2 jdolecek {
214 1.11.2.2 jdolecek s32 status;
215 1.11.2.2 jdolecek u32 ctrl, i;
216 1.11.2.2 jdolecek u32 swfw_mask = hw->phy.phy_semaphore_mask;
217 1.11.2.2 jdolecek
218 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_reset_hw_X540");
219 1.11.2.2 jdolecek
220 1.11.2.2 jdolecek /* Call adapter stop to disable tx/rx and clear interrupts */
221 1.11.2.2 jdolecek status = hw->mac.ops.stop_adapter(hw);
222 1.11.2.2 jdolecek if (status != IXGBE_SUCCESS)
223 1.11.2.2 jdolecek goto reset_hw_out;
224 1.11.2.2 jdolecek
225 1.11.2.2 jdolecek /* flush pending Tx transactions */
226 1.11.2.2 jdolecek ixgbe_clear_tx_pending(hw);
227 1.11.2.2 jdolecek
228 1.11.2.2 jdolecek mac_reset_top:
229 1.11.2.2 jdolecek status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
230 1.11.2.2 jdolecek if (status != IXGBE_SUCCESS) {
231 1.11.2.2 jdolecek ERROR_REPORT2(IXGBE_ERROR_CAUTION,
232 1.11.2.2 jdolecek "semaphore failed with %d", status);
233 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
234 1.11.2.2 jdolecek }
235 1.11.2.2 jdolecek ctrl = IXGBE_CTRL_RST;
236 1.11.2.2 jdolecek ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
237 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
238 1.11.2.2 jdolecek IXGBE_WRITE_FLUSH(hw);
239 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, swfw_mask);
240 1.11.2.2 jdolecek
241 1.11.2.2 jdolecek /* Poll for reset bit to self-clear indicating reset is complete */
242 1.11.2.2 jdolecek for (i = 0; i < 10; i++) {
243 1.11.2.2 jdolecek usec_delay(1);
244 1.11.2.2 jdolecek ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
245 1.11.2.2 jdolecek if (!(ctrl & IXGBE_CTRL_RST_MASK))
246 1.11.2.2 jdolecek break;
247 1.11.2.2 jdolecek }
248 1.11.2.2 jdolecek
249 1.11.2.2 jdolecek if (ctrl & IXGBE_CTRL_RST_MASK) {
250 1.11.2.2 jdolecek status = IXGBE_ERR_RESET_FAILED;
251 1.11.2.2 jdolecek ERROR_REPORT1(IXGBE_ERROR_POLLING,
252 1.11.2.2 jdolecek "Reset polling failed to complete.\n");
253 1.11.2.2 jdolecek }
254 1.11.2.2 jdolecek msec_delay(100);
255 1.11.2.2 jdolecek
256 1.11.2.2 jdolecek /*
257 1.11.2.2 jdolecek * Double resets are required for recovery from certain error
258 1.11.2.2 jdolecek * conditions. Between resets, it is necessary to stall to allow time
259 1.11.2.2 jdolecek * for any pending HW events to complete.
260 1.11.2.2 jdolecek */
261 1.11.2.2 jdolecek if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
262 1.11.2.2 jdolecek hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
263 1.11.2.2 jdolecek goto mac_reset_top;
264 1.11.2.2 jdolecek }
265 1.11.2.2 jdolecek
266 1.11.2.2 jdolecek /* Set the Rx packet buffer size. */
267 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
268 1.11.2.2 jdolecek
269 1.11.2.2 jdolecek /* Store the permanent mac address */
270 1.11.2.2 jdolecek hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
271 1.11.2.2 jdolecek
272 1.11.2.2 jdolecek /*
273 1.11.2.2 jdolecek * Store MAC address from RAR0, clear receive address registers, and
274 1.11.2.2 jdolecek * clear the multicast table. Also reset num_rar_entries to 128,
275 1.11.2.2 jdolecek * since we modify this value when programming the SAN MAC address.
276 1.11.2.2 jdolecek */
277 1.11.2.2 jdolecek hw->mac.num_rar_entries = 128;
278 1.11.2.2 jdolecek hw->mac.ops.init_rx_addrs(hw);
279 1.11.2.2 jdolecek
280 1.11.2.2 jdolecek /* Store the permanent SAN mac address */
281 1.11.2.2 jdolecek hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
282 1.11.2.2 jdolecek
283 1.11.2.2 jdolecek /* Add the SAN MAC address to the RAR only if it's a valid address */
284 1.11.2.2 jdolecek if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
285 1.11.2.2 jdolecek /* Save the SAN MAC RAR index */
286 1.11.2.2 jdolecek hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1;
287 1.11.2.2 jdolecek
288 1.11.2.2 jdolecek hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index,
289 1.11.2.2 jdolecek hw->mac.san_addr, 0, IXGBE_RAH_AV);
290 1.11.2.2 jdolecek
291 1.11.2.2 jdolecek /* clear VMDq pool/queue selection for this RAR */
292 1.11.2.2 jdolecek hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index,
293 1.11.2.2 jdolecek IXGBE_CLEAR_VMDQ_ALL);
294 1.11.2.2 jdolecek
295 1.11.2.2 jdolecek /* Reserve the last RAR for the SAN MAC address */
296 1.11.2.2 jdolecek hw->mac.num_rar_entries--;
297 1.11.2.2 jdolecek }
298 1.11.2.2 jdolecek
299 1.11.2.2 jdolecek /* Store the alternative WWNN/WWPN prefix */
300 1.11.2.2 jdolecek hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
301 1.11.2.2 jdolecek &hw->mac.wwpn_prefix);
302 1.11.2.2 jdolecek
303 1.11.2.2 jdolecek reset_hw_out:
304 1.11.2.2 jdolecek return status;
305 1.11.2.2 jdolecek }
306 1.11.2.2 jdolecek
307 1.11.2.2 jdolecek /**
308 1.11.2.2 jdolecek * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
309 1.11.2.2 jdolecek * @hw: pointer to hardware structure
310 1.11.2.2 jdolecek *
311 1.11.2.2 jdolecek * Starts the hardware using the generic start_hw function
312 1.11.2.2 jdolecek * and the generation start_hw function.
313 1.11.2.2 jdolecek * Then performs revision-specific operations, if any.
314 1.11.2.2 jdolecek **/
315 1.11.2.2 jdolecek s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
316 1.11.2.2 jdolecek {
317 1.11.2.2 jdolecek s32 ret_val = IXGBE_SUCCESS;
318 1.11.2.2 jdolecek
319 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_start_hw_X540");
320 1.11.2.2 jdolecek
321 1.11.2.2 jdolecek ret_val = ixgbe_start_hw_generic(hw);
322 1.11.2.2 jdolecek if (ret_val != IXGBE_SUCCESS)
323 1.11.2.2 jdolecek goto out;
324 1.11.2.2 jdolecek
325 1.11.2.2 jdolecek ret_val = ixgbe_start_hw_gen2(hw);
326 1.11.2.2 jdolecek
327 1.11.2.2 jdolecek out:
328 1.11.2.2 jdolecek return ret_val;
329 1.11.2.2 jdolecek }
330 1.11.2.2 jdolecek
331 1.11.2.2 jdolecek /**
332 1.11.2.2 jdolecek * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
333 1.11.2.2 jdolecek * @hw: pointer to hardware structure
334 1.11.2.2 jdolecek *
335 1.11.2.2 jdolecek * Determines physical layer capabilities of the current configuration.
336 1.11.2.2 jdolecek **/
337 1.11.2.2 jdolecek u64 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
338 1.11.2.2 jdolecek {
339 1.11.2.2 jdolecek u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
340 1.11.2.2 jdolecek u16 ext_ability = 0;
341 1.11.2.2 jdolecek
342 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_get_supported_physical_layer_X540");
343 1.11.2.2 jdolecek
344 1.11.2.2 jdolecek hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
345 1.11.2.2 jdolecek IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
346 1.11.2.2 jdolecek if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
347 1.11.2.2 jdolecek physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
348 1.11.2.2 jdolecek if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
349 1.11.2.2 jdolecek physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
350 1.11.2.2 jdolecek if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
351 1.11.2.2 jdolecek physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
352 1.11.2.2 jdolecek
353 1.11.2.2 jdolecek if (hw->mac.type == ixgbe_mac_X550) {
354 1.11.2.2 jdolecek physical_layer |= IXGBE_PHYSICAL_LAYER_2500BASE_T
355 1.11.2.2 jdolecek | IXGBE_PHYSICAL_LAYER_5GBASE_T;
356 1.11.2.2 jdolecek }
357 1.11.2.2 jdolecek
358 1.11.2.2 jdolecek return physical_layer;
359 1.11.2.2 jdolecek }
360 1.11.2.2 jdolecek
361 1.11.2.2 jdolecek /**
362 1.11.2.2 jdolecek * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
363 1.11.2.2 jdolecek * @hw: pointer to hardware structure
364 1.11.2.2 jdolecek *
365 1.11.2.2 jdolecek * Initializes the EEPROM parameters ixgbe_eeprom_info within the
366 1.11.2.2 jdolecek * ixgbe_hw struct in order to set up EEPROM access.
367 1.11.2.2 jdolecek **/
368 1.11.2.2 jdolecek s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
369 1.11.2.2 jdolecek {
370 1.11.2.2 jdolecek struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
371 1.11.2.2 jdolecek u32 eec;
372 1.11.2.2 jdolecek u16 eeprom_size;
373 1.11.2.2 jdolecek
374 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_init_eeprom_params_X540");
375 1.11.2.2 jdolecek
376 1.11.2.2 jdolecek if (eeprom->type == ixgbe_eeprom_uninitialized) {
377 1.11.2.2 jdolecek eeprom->semaphore_delay = 10;
378 1.11.2.2 jdolecek eeprom->type = ixgbe_flash;
379 1.11.2.2 jdolecek
380 1.11.2.2 jdolecek eec = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
381 1.11.2.2 jdolecek eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
382 1.11.2.2 jdolecek IXGBE_EEC_SIZE_SHIFT);
383 1.11.2.2 jdolecek eeprom->word_size = 1 << (eeprom_size +
384 1.11.2.2 jdolecek IXGBE_EEPROM_WORD_SIZE_SHIFT);
385 1.11.2.2 jdolecek
386 1.11.2.2 jdolecek DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
387 1.11.2.2 jdolecek eeprom->type, eeprom->word_size);
388 1.11.2.2 jdolecek }
389 1.11.2.2 jdolecek
390 1.11.2.2 jdolecek return IXGBE_SUCCESS;
391 1.11.2.2 jdolecek }
392 1.11.2.2 jdolecek
393 1.11.2.2 jdolecek /**
394 1.11.2.2 jdolecek * ixgbe_read_eerd_X540- Read EEPROM word using EERD
395 1.11.2.2 jdolecek * @hw: pointer to hardware structure
396 1.11.2.2 jdolecek * @offset: offset of word in the EEPROM to read
397 1.11.2.2 jdolecek * @data: word read from the EEPROM
398 1.11.2.2 jdolecek *
399 1.11.2.2 jdolecek * Reads a 16 bit word from the EEPROM using the EERD register.
400 1.11.2.2 jdolecek **/
401 1.11.2.2 jdolecek s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
402 1.11.2.2 jdolecek {
403 1.11.2.2 jdolecek s32 status = IXGBE_SUCCESS;
404 1.11.2.2 jdolecek
405 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_read_eerd_X540");
406 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
407 1.11.2.2 jdolecek IXGBE_SUCCESS) {
408 1.11.2.2 jdolecek status = ixgbe_read_eerd_generic(hw, offset, data);
409 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
410 1.11.2.2 jdolecek } else {
411 1.11.2.2 jdolecek status = IXGBE_ERR_SWFW_SYNC;
412 1.11.2.2 jdolecek }
413 1.11.2.2 jdolecek
414 1.11.2.2 jdolecek return status;
415 1.11.2.2 jdolecek }
416 1.11.2.2 jdolecek
417 1.11.2.2 jdolecek /**
418 1.11.2.2 jdolecek * ixgbe_read_eerd_buffer_X540- Read EEPROM word(s) using EERD
419 1.11.2.2 jdolecek * @hw: pointer to hardware structure
420 1.11.2.2 jdolecek * @offset: offset of word in the EEPROM to read
421 1.11.2.2 jdolecek * @words: number of words
422 1.11.2.2 jdolecek * @data: word(s) read from the EEPROM
423 1.11.2.2 jdolecek *
424 1.11.2.2 jdolecek * Reads a 16 bit word(s) from the EEPROM using the EERD register.
425 1.11.2.2 jdolecek **/
426 1.11.2.2 jdolecek s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
427 1.11.2.2 jdolecek u16 offset, u16 words, u16 *data)
428 1.11.2.2 jdolecek {
429 1.11.2.2 jdolecek s32 status = IXGBE_SUCCESS;
430 1.11.2.2 jdolecek
431 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_read_eerd_buffer_X540");
432 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
433 1.11.2.2 jdolecek IXGBE_SUCCESS) {
434 1.11.2.2 jdolecek status = ixgbe_read_eerd_buffer_generic(hw, offset,
435 1.11.2.2 jdolecek words, data);
436 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
437 1.11.2.2 jdolecek } else {
438 1.11.2.2 jdolecek status = IXGBE_ERR_SWFW_SYNC;
439 1.11.2.2 jdolecek }
440 1.11.2.2 jdolecek
441 1.11.2.2 jdolecek return status;
442 1.11.2.2 jdolecek }
443 1.11.2.2 jdolecek
444 1.11.2.2 jdolecek /**
445 1.11.2.2 jdolecek * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
446 1.11.2.2 jdolecek * @hw: pointer to hardware structure
447 1.11.2.2 jdolecek * @offset: offset of word in the EEPROM to write
448 1.11.2.2 jdolecek * @data: word write to the EEPROM
449 1.11.2.2 jdolecek *
450 1.11.2.2 jdolecek * Write a 16 bit word to the EEPROM using the EEWR register.
451 1.11.2.2 jdolecek **/
452 1.11.2.2 jdolecek s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
453 1.11.2.2 jdolecek {
454 1.11.2.2 jdolecek s32 status = IXGBE_SUCCESS;
455 1.11.2.2 jdolecek
456 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_write_eewr_X540");
457 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
458 1.11.2.2 jdolecek IXGBE_SUCCESS) {
459 1.11.2.2 jdolecek status = ixgbe_write_eewr_generic(hw, offset, data);
460 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
461 1.11.2.2 jdolecek } else {
462 1.11.2.2 jdolecek status = IXGBE_ERR_SWFW_SYNC;
463 1.11.2.2 jdolecek }
464 1.11.2.2 jdolecek
465 1.11.2.2 jdolecek return status;
466 1.11.2.2 jdolecek }
467 1.11.2.2 jdolecek
468 1.11.2.2 jdolecek /**
469 1.11.2.2 jdolecek * ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
470 1.11.2.2 jdolecek * @hw: pointer to hardware structure
471 1.11.2.2 jdolecek * @offset: offset of word in the EEPROM to write
472 1.11.2.2 jdolecek * @words: number of words
473 1.11.2.2 jdolecek * @data: word(s) write to the EEPROM
474 1.11.2.2 jdolecek *
475 1.11.2.2 jdolecek * Write a 16 bit word(s) to the EEPROM using the EEWR register.
476 1.11.2.2 jdolecek **/
477 1.11.2.2 jdolecek s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
478 1.11.2.2 jdolecek u16 offset, u16 words, u16 *data)
479 1.11.2.2 jdolecek {
480 1.11.2.2 jdolecek s32 status = IXGBE_SUCCESS;
481 1.11.2.2 jdolecek
482 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_write_eewr_buffer_X540");
483 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
484 1.11.2.2 jdolecek IXGBE_SUCCESS) {
485 1.11.2.2 jdolecek status = ixgbe_write_eewr_buffer_generic(hw, offset,
486 1.11.2.2 jdolecek words, data);
487 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
488 1.11.2.2 jdolecek } else {
489 1.11.2.2 jdolecek status = IXGBE_ERR_SWFW_SYNC;
490 1.11.2.2 jdolecek }
491 1.11.2.2 jdolecek
492 1.11.2.2 jdolecek return status;
493 1.11.2.2 jdolecek }
494 1.11.2.2 jdolecek
495 1.11.2.2 jdolecek /**
496 1.11.2.2 jdolecek * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
497 1.11.2.2 jdolecek *
498 1.11.2.2 jdolecek * This function does not use synchronization for EERD and EEWR. It can
499 1.11.2.2 jdolecek * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
500 1.11.2.2 jdolecek *
501 1.11.2.2 jdolecek * @hw: pointer to hardware structure
502 1.11.2.2 jdolecek *
503 1.11.2.2 jdolecek * Returns a negative error code on error, or the 16-bit checksum
504 1.11.2.2 jdolecek **/
505 1.11.2.2 jdolecek s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
506 1.11.2.2 jdolecek {
507 1.11.2.2 jdolecek u16 i, j;
508 1.11.2.2 jdolecek u16 checksum = 0;
509 1.11.2.2 jdolecek u16 length = 0;
510 1.11.2.2 jdolecek u16 pointer = 0;
511 1.11.2.2 jdolecek u16 word = 0;
512 1.11.2.2 jdolecek u16 ptr_start = IXGBE_PCIE_ANALOG_PTR;
513 1.11.2.2 jdolecek
514 1.11.2.2 jdolecek /* Do not use hw->eeprom.ops.read because we do not want to take
515 1.11.2.2 jdolecek * the synchronization semaphores here. Instead use
516 1.11.2.2 jdolecek * ixgbe_read_eerd_generic
517 1.11.2.2 jdolecek */
518 1.11.2.2 jdolecek
519 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_calc_eeprom_checksum_X540");
520 1.11.2.2 jdolecek
521 1.11.2.2 jdolecek /* Include 0x0 up to IXGBE_EEPROM_CHECKSUM; do not include the
522 1.11.2.2 jdolecek * checksum itself
523 1.11.2.2 jdolecek */
524 1.11.2.2 jdolecek for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
525 1.11.2.2 jdolecek if (ixgbe_read_eerd_generic(hw, i, &word)) {
526 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
527 1.11.2.2 jdolecek return IXGBE_ERR_EEPROM;
528 1.11.2.2 jdolecek }
529 1.11.2.2 jdolecek checksum += word;
530 1.11.2.2 jdolecek }
531 1.11.2.2 jdolecek
532 1.11.2.2 jdolecek /* Include all data from pointers 0x3, 0x6-0xE. This excludes the
533 1.11.2.2 jdolecek * FW, PHY module, and PCIe Expansion/Option ROM pointers.
534 1.11.2.2 jdolecek */
535 1.11.2.2 jdolecek for (i = ptr_start; i < IXGBE_FW_PTR; i++) {
536 1.11.2.2 jdolecek if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
537 1.11.2.2 jdolecek continue;
538 1.11.2.2 jdolecek
539 1.11.2.2 jdolecek if (ixgbe_read_eerd_generic(hw, i, &pointer)) {
540 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
541 1.11.2.2 jdolecek return IXGBE_ERR_EEPROM;
542 1.11.2.2 jdolecek }
543 1.11.2.2 jdolecek
544 1.11.2.2 jdolecek /* Skip pointer section if the pointer is invalid. */
545 1.11.2.2 jdolecek if (pointer == 0xFFFF || pointer == 0 ||
546 1.11.2.2 jdolecek pointer >= hw->eeprom.word_size)
547 1.11.2.2 jdolecek continue;
548 1.11.2.2 jdolecek
549 1.11.2.2 jdolecek if (ixgbe_read_eerd_generic(hw, pointer, &length)) {
550 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
551 1.11.2.2 jdolecek return IXGBE_ERR_EEPROM;
552 1.11.2.2 jdolecek }
553 1.11.2.2 jdolecek
554 1.11.2.2 jdolecek /* Skip pointer section if length is invalid. */
555 1.11.2.2 jdolecek if (length == 0xFFFF || length == 0 ||
556 1.11.2.2 jdolecek (pointer + length) >= hw->eeprom.word_size)
557 1.11.2.2 jdolecek continue;
558 1.11.2.2 jdolecek
559 1.11.2.2 jdolecek for (j = pointer + 1; j <= pointer + length; j++) {
560 1.11.2.2 jdolecek if (ixgbe_read_eerd_generic(hw, j, &word)) {
561 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
562 1.11.2.2 jdolecek return IXGBE_ERR_EEPROM;
563 1.11.2.2 jdolecek }
564 1.11.2.2 jdolecek checksum += word;
565 1.11.2.2 jdolecek }
566 1.11.2.2 jdolecek }
567 1.11.2.2 jdolecek
568 1.11.2.2 jdolecek checksum = (u16)IXGBE_EEPROM_SUM - checksum;
569 1.11.2.2 jdolecek
570 1.11.2.2 jdolecek return (s32)checksum;
571 1.11.2.2 jdolecek }
572 1.11.2.2 jdolecek
573 1.11.2.2 jdolecek /**
574 1.11.2.2 jdolecek * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
575 1.11.2.2 jdolecek * @hw: pointer to hardware structure
576 1.11.2.2 jdolecek * @checksum_val: calculated checksum
577 1.11.2.2 jdolecek *
578 1.11.2.2 jdolecek * Performs checksum calculation and validates the EEPROM checksum. If the
579 1.11.2.2 jdolecek * caller does not need checksum_val, the value can be NULL.
580 1.11.2.2 jdolecek **/
581 1.11.2.2 jdolecek s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
582 1.11.2.2 jdolecek u16 *checksum_val)
583 1.11.2.2 jdolecek {
584 1.11.2.2 jdolecek s32 status;
585 1.11.2.2 jdolecek u16 checksum;
586 1.11.2.2 jdolecek u16 read_checksum = 0;
587 1.11.2.2 jdolecek
588 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_validate_eeprom_checksum_X540");
589 1.11.2.2 jdolecek
590 1.11.2.2 jdolecek /* Read the first word from the EEPROM. If this times out or fails, do
591 1.11.2.2 jdolecek * not continue or we could be in for a very long wait while every
592 1.11.2.2 jdolecek * EEPROM read fails
593 1.11.2.2 jdolecek */
594 1.11.2.2 jdolecek status = hw->eeprom.ops.read(hw, 0, &checksum);
595 1.11.2.2 jdolecek if (status) {
596 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
597 1.11.2.2 jdolecek return status;
598 1.11.2.2 jdolecek }
599 1.11.2.2 jdolecek
600 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
601 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
602 1.11.2.2 jdolecek
603 1.11.2.2 jdolecek status = hw->eeprom.ops.calc_checksum(hw);
604 1.11.2.2 jdolecek if (status < 0)
605 1.11.2.2 jdolecek goto out;
606 1.11.2.2 jdolecek
607 1.11.2.2 jdolecek checksum = (u16)(status & 0xffff);
608 1.11.2.2 jdolecek
609 1.11.2.2 jdolecek /* Do not use hw->eeprom.ops.read because we do not want to take
610 1.11.2.2 jdolecek * the synchronization semaphores twice here.
611 1.11.2.2 jdolecek */
612 1.11.2.2 jdolecek status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
613 1.11.2.2 jdolecek &read_checksum);
614 1.11.2.2 jdolecek if (status)
615 1.11.2.2 jdolecek goto out;
616 1.11.2.2 jdolecek
617 1.11.2.2 jdolecek /* Verify read checksum from EEPROM is the same as
618 1.11.2.2 jdolecek * calculated checksum
619 1.11.2.2 jdolecek */
620 1.11.2.2 jdolecek if (read_checksum != checksum) {
621 1.11.2.2 jdolecek ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
622 1.11.2.2 jdolecek "Invalid EEPROM checksum");
623 1.11.2.2 jdolecek status = IXGBE_ERR_EEPROM_CHECKSUM;
624 1.11.2.2 jdolecek }
625 1.11.2.2 jdolecek
626 1.11.2.2 jdolecek /* If the user cares, return the calculated checksum */
627 1.11.2.2 jdolecek if (checksum_val)
628 1.11.2.2 jdolecek *checksum_val = checksum;
629 1.11.2.2 jdolecek
630 1.11.2.2 jdolecek out:
631 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
632 1.11.2.2 jdolecek
633 1.11.2.2 jdolecek return status;
634 1.11.2.2 jdolecek }
635 1.11.2.2 jdolecek
636 1.11.2.2 jdolecek /**
637 1.11.2.2 jdolecek * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
638 1.11.2.2 jdolecek * @hw: pointer to hardware structure
639 1.11.2.2 jdolecek *
640 1.11.2.2 jdolecek * After writing EEPROM to shadow RAM using EEWR register, software calculates
641 1.11.2.2 jdolecek * checksum and updates the EEPROM and instructs the hardware to update
642 1.11.2.2 jdolecek * the flash.
643 1.11.2.2 jdolecek **/
644 1.11.2.2 jdolecek s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
645 1.11.2.2 jdolecek {
646 1.11.2.2 jdolecek s32 status;
647 1.11.2.2 jdolecek u16 checksum;
648 1.11.2.2 jdolecek
649 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_update_eeprom_checksum_X540");
650 1.11.2.2 jdolecek
651 1.11.2.2 jdolecek /* Read the first word from the EEPROM. If this times out or fails, do
652 1.11.2.2 jdolecek * not continue or we could be in for a very long wait while every
653 1.11.2.2 jdolecek * EEPROM read fails
654 1.11.2.2 jdolecek */
655 1.11.2.2 jdolecek status = hw->eeprom.ops.read(hw, 0, &checksum);
656 1.11.2.2 jdolecek if (status) {
657 1.11.2.2 jdolecek DEBUGOUT("EEPROM read failed\n");
658 1.11.2.2 jdolecek return status;
659 1.11.2.2 jdolecek }
660 1.11.2.2 jdolecek
661 1.11.2.2 jdolecek if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
662 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
663 1.11.2.2 jdolecek
664 1.11.2.2 jdolecek status = hw->eeprom.ops.calc_checksum(hw);
665 1.11.2.2 jdolecek if (status < 0)
666 1.11.2.2 jdolecek goto out;
667 1.11.2.2 jdolecek
668 1.11.2.2 jdolecek checksum = (u16)(status & 0xffff);
669 1.11.2.2 jdolecek
670 1.11.2.2 jdolecek /* Do not use hw->eeprom.ops.write because we do not want to
671 1.11.2.2 jdolecek * take the synchronization semaphores twice here.
672 1.11.2.2 jdolecek */
673 1.11.2.2 jdolecek status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
674 1.11.2.2 jdolecek if (status)
675 1.11.2.2 jdolecek goto out;
676 1.11.2.2 jdolecek
677 1.11.2.2 jdolecek status = ixgbe_update_flash_X540(hw);
678 1.11.2.2 jdolecek
679 1.11.2.2 jdolecek out:
680 1.11.2.2 jdolecek hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
681 1.11.2.2 jdolecek
682 1.11.2.2 jdolecek return status;
683 1.11.2.2 jdolecek }
684 1.11.2.2 jdolecek
685 1.11.2.2 jdolecek /**
686 1.11.2.2 jdolecek * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device
687 1.11.2.2 jdolecek * @hw: pointer to hardware structure
688 1.11.2.2 jdolecek *
689 1.11.2.2 jdolecek * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy
690 1.11.2.2 jdolecek * EEPROM from shadow RAM to the flash device.
691 1.11.2.2 jdolecek **/
692 1.11.2.2 jdolecek s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
693 1.11.2.2 jdolecek {
694 1.11.2.2 jdolecek u32 flup;
695 1.11.2.2 jdolecek s32 status;
696 1.11.2.2 jdolecek
697 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_update_flash_X540");
698 1.11.2.2 jdolecek
699 1.11.2.2 jdolecek status = ixgbe_poll_flash_update_done_X540(hw);
700 1.11.2.2 jdolecek if (status == IXGBE_ERR_EEPROM) {
701 1.11.2.2 jdolecek DEBUGOUT("Flash update time out\n");
702 1.11.2.2 jdolecek goto out;
703 1.11.2.2 jdolecek }
704 1.11.2.2 jdolecek
705 1.11.2.2 jdolecek flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw)) | IXGBE_EEC_FLUP;
706 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
707 1.11.2.2 jdolecek
708 1.11.2.2 jdolecek status = ixgbe_poll_flash_update_done_X540(hw);
709 1.11.2.2 jdolecek if (status == IXGBE_SUCCESS)
710 1.11.2.2 jdolecek DEBUGOUT("Flash update complete\n");
711 1.11.2.2 jdolecek else
712 1.11.2.2 jdolecek DEBUGOUT("Flash update time out\n");
713 1.11.2.2 jdolecek
714 1.11.2.2 jdolecek if (hw->mac.type == ixgbe_mac_X540 && hw->revision_id == 0) {
715 1.11.2.2 jdolecek flup = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
716 1.11.2.2 jdolecek
717 1.11.2.2 jdolecek if (flup & IXGBE_EEC_SEC1VAL) {
718 1.11.2.2 jdolecek flup |= IXGBE_EEC_FLUP;
719 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_EEC_BY_MAC(hw), flup);
720 1.11.2.2 jdolecek }
721 1.11.2.2 jdolecek
722 1.11.2.2 jdolecek status = ixgbe_poll_flash_update_done_X540(hw);
723 1.11.2.2 jdolecek if (status == IXGBE_SUCCESS)
724 1.11.2.2 jdolecek DEBUGOUT("Flash update complete\n");
725 1.11.2.2 jdolecek else
726 1.11.2.2 jdolecek DEBUGOUT("Flash update time out\n");
727 1.11.2.2 jdolecek }
728 1.11.2.2 jdolecek out:
729 1.11.2.2 jdolecek return status;
730 1.11.2.2 jdolecek }
731 1.11.2.2 jdolecek
732 1.11.2.2 jdolecek /**
733 1.11.2.2 jdolecek * ixgbe_poll_flash_update_done_X540 - Poll flash update status
734 1.11.2.2 jdolecek * @hw: pointer to hardware structure
735 1.11.2.2 jdolecek *
736 1.11.2.2 jdolecek * Polls the FLUDONE (bit 26) of the EEC Register to determine when the
737 1.11.2.2 jdolecek * flash update is done.
738 1.11.2.2 jdolecek **/
739 1.11.2.2 jdolecek static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
740 1.11.2.2 jdolecek {
741 1.11.2.2 jdolecek u32 i;
742 1.11.2.2 jdolecek u32 reg;
743 1.11.2.2 jdolecek s32 status = IXGBE_ERR_EEPROM;
744 1.11.2.2 jdolecek
745 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_poll_flash_update_done_X540");
746 1.11.2.2 jdolecek
747 1.11.2.2 jdolecek for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
748 1.11.2.2 jdolecek reg = IXGBE_READ_REG(hw, IXGBE_EEC_BY_MAC(hw));
749 1.11.2.2 jdolecek if (reg & IXGBE_EEC_FLUDONE) {
750 1.11.2.2 jdolecek status = IXGBE_SUCCESS;
751 1.11.2.2 jdolecek break;
752 1.11.2.2 jdolecek }
753 1.11.2.2 jdolecek msec_delay(5);
754 1.11.2.2 jdolecek }
755 1.11.2.2 jdolecek
756 1.11.2.2 jdolecek if (i == IXGBE_FLUDONE_ATTEMPTS)
757 1.11.2.2 jdolecek ERROR_REPORT1(IXGBE_ERROR_POLLING,
758 1.11.2.2 jdolecek "Flash update status polling timed out");
759 1.11.2.2 jdolecek
760 1.11.2.2 jdolecek return status;
761 1.11.2.2 jdolecek }
762 1.11.2.2 jdolecek
763 1.11.2.2 jdolecek /**
764 1.11.2.2 jdolecek * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore
765 1.11.2.2 jdolecek * @hw: pointer to hardware structure
766 1.11.2.2 jdolecek * @mask: Mask to specify which semaphore to acquire
767 1.11.2.2 jdolecek *
768 1.11.2.2 jdolecek * Acquires the SWFW semaphore thought the SW_FW_SYNC register for
769 1.11.2.2 jdolecek * the specified function (CSR, PHY0, PHY1, NVM, Flash)
770 1.11.2.2 jdolecek **/
771 1.11.2.2 jdolecek s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
772 1.11.2.2 jdolecek {
773 1.11.2.2 jdolecek u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK;
774 1.11.2.2 jdolecek u32 fwmask = swmask << 5;
775 1.11.2.2 jdolecek u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK;
776 1.11.2.2 jdolecek u32 timeout = 200;
777 1.11.2.2 jdolecek u32 hwmask = 0;
778 1.11.2.2 jdolecek u32 swfw_sync;
779 1.11.2.2 jdolecek u32 i;
780 1.11.2.2 jdolecek
781 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_acquire_swfw_sync_X540");
782 1.11.2.2 jdolecek
783 1.11.2.2 jdolecek if (swmask & IXGBE_GSSR_EEP_SM)
784 1.11.2.2 jdolecek hwmask |= IXGBE_GSSR_FLASH_SM;
785 1.11.2.2 jdolecek
786 1.11.2.2 jdolecek /* SW only mask doesn't have FW bit pair */
787 1.11.2.2 jdolecek if (mask & IXGBE_GSSR_SW_MNG_SM)
788 1.11.2.2 jdolecek swmask |= IXGBE_GSSR_SW_MNG_SM;
789 1.11.2.2 jdolecek
790 1.11.2.2 jdolecek swmask |= swi2c_mask;
791 1.11.2.2 jdolecek fwmask |= swi2c_mask << 2;
792 1.11.2.2 jdolecek for (i = 0; i < timeout; i++) {
793 1.11.2.2 jdolecek /* SW NVM semaphore bit is used for access to all
794 1.11.2.2 jdolecek * SW_FW_SYNC bits (not just NVM)
795 1.11.2.2 jdolecek */
796 1.11.2.2 jdolecek if (ixgbe_get_swfw_sync_semaphore(hw)) {
797 1.11.2.2 jdolecek DEBUGOUT("Failed to get NVM access and register semaphore, returning IXGBE_ERR_SWFW_SYNC\n");
798 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
799 1.11.2.2 jdolecek }
800 1.11.2.2 jdolecek
801 1.11.2.2 jdolecek swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
802 1.11.2.2 jdolecek if (!(swfw_sync & (fwmask | swmask | hwmask))) {
803 1.11.2.2 jdolecek swfw_sync |= swmask;
804 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw),
805 1.11.2.2 jdolecek swfw_sync);
806 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
807 1.11.2.2 jdolecek return IXGBE_SUCCESS;
808 1.11.2.2 jdolecek }
809 1.11.2.2 jdolecek /* Firmware currently using resource (fwmask), hardware
810 1.11.2.2 jdolecek * currently using resource (hwmask), or other software
811 1.11.2.2 jdolecek * thread currently using resource (swmask)
812 1.11.2.2 jdolecek */
813 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
814 1.11.2.2 jdolecek msec_delay(5);
815 1.11.2.2 jdolecek }
816 1.11.2.2 jdolecek
817 1.11.2.2 jdolecek /* If the resource is not released by the FW/HW the SW can assume that
818 1.11.2.2 jdolecek * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
819 1.11.2.2 jdolecek * of the requested resource(s) while ignoring the corresponding FW/HW
820 1.11.2.2 jdolecek * bits in the SW_FW_SYNC register.
821 1.11.2.2 jdolecek */
822 1.11.2.2 jdolecek if (ixgbe_get_swfw_sync_semaphore(hw)) {
823 1.11.2.2 jdolecek DEBUGOUT("Failed to get NVM sempahore and register semaphore while forcefully ignoring FW sempahore bit(s) and setting SW semaphore bit(s), returning IXGBE_ERR_SWFW_SYNC\n");
824 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
825 1.11.2.2 jdolecek }
826 1.11.2.2 jdolecek swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
827 1.11.2.2 jdolecek if (swfw_sync & (fwmask | hwmask)) {
828 1.11.2.2 jdolecek swfw_sync |= swmask;
829 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
830 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
831 1.11.2.2 jdolecek msec_delay(5);
832 1.11.2.2 jdolecek return IXGBE_SUCCESS;
833 1.11.2.2 jdolecek }
834 1.11.2.2 jdolecek /* If the resource is not released by other SW the SW can assume that
835 1.11.2.2 jdolecek * the other SW malfunctions. In that case the SW should clear all SW
836 1.11.2.2 jdolecek * flags that it does not own and then repeat the whole process once
837 1.11.2.2 jdolecek * again.
838 1.11.2.2 jdolecek */
839 1.11.2.2 jdolecek if (swfw_sync & swmask) {
840 1.11.2.2 jdolecek u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
841 1.11.2.2 jdolecek IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
842 1.11.2.2 jdolecek IXGBE_GSSR_SW_MNG_SM;
843 1.11.2.2 jdolecek
844 1.11.2.2 jdolecek if (swi2c_mask)
845 1.11.2.2 jdolecek rmask |= IXGBE_GSSR_I2C_MASK;
846 1.11.2.2 jdolecek ixgbe_release_swfw_sync_X540(hw, rmask);
847 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
848 1.11.2.2 jdolecek DEBUGOUT("Resource not released by other SW, returning IXGBE_ERR_SWFW_SYNC\n");
849 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
850 1.11.2.2 jdolecek }
851 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
852 1.11.2.2 jdolecek DEBUGOUT("Returning error IXGBE_ERR_SWFW_SYNC\n");
853 1.11.2.2 jdolecek
854 1.11.2.2 jdolecek return IXGBE_ERR_SWFW_SYNC;
855 1.11.2.2 jdolecek }
856 1.11.2.2 jdolecek
857 1.11.2.2 jdolecek /**
858 1.11.2.2 jdolecek * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore
859 1.11.2.2 jdolecek * @hw: pointer to hardware structure
860 1.11.2.2 jdolecek * @mask: Mask to specify which semaphore to release
861 1.11.2.2 jdolecek *
862 1.11.2.2 jdolecek * Releases the SWFW semaphore through the SW_FW_SYNC register
863 1.11.2.2 jdolecek * for the specified function (CSR, PHY0, PHY1, EVM, Flash)
864 1.11.2.2 jdolecek **/
865 1.11.2.2 jdolecek void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
866 1.11.2.2 jdolecek {
867 1.11.2.2 jdolecek u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM);
868 1.11.2.2 jdolecek u32 swfw_sync;
869 1.11.2.2 jdolecek
870 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_release_swfw_sync_X540");
871 1.11.2.2 jdolecek
872 1.11.2.2 jdolecek if (mask & IXGBE_GSSR_I2C_MASK)
873 1.11.2.2 jdolecek swmask |= mask & IXGBE_GSSR_I2C_MASK;
874 1.11.2.2 jdolecek ixgbe_get_swfw_sync_semaphore(hw);
875 1.11.2.2 jdolecek
876 1.11.2.2 jdolecek swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
877 1.11.2.2 jdolecek swfw_sync &= ~swmask;
878 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swfw_sync);
879 1.11.2.2 jdolecek
880 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
881 1.11.2.2 jdolecek msec_delay(2);
882 1.11.2.2 jdolecek }
883 1.11.2.2 jdolecek
884 1.11.2.2 jdolecek /**
885 1.11.2.2 jdolecek * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore
886 1.11.2.2 jdolecek * @hw: pointer to hardware structure
887 1.11.2.2 jdolecek *
888 1.11.2.2 jdolecek * Sets the hardware semaphores so SW/FW can gain control of shared resources
889 1.11.2.2 jdolecek **/
890 1.11.2.2 jdolecek static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
891 1.11.2.2 jdolecek {
892 1.11.2.2 jdolecek s32 status = IXGBE_ERR_EEPROM;
893 1.11.2.2 jdolecek u32 timeout = 2000;
894 1.11.2.2 jdolecek u32 i;
895 1.11.2.2 jdolecek u32 swsm;
896 1.11.2.2 jdolecek
897 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_get_swfw_sync_semaphore");
898 1.11.2.2 jdolecek
899 1.11.2.2 jdolecek /* Get SMBI software semaphore between device drivers first */
900 1.11.2.2 jdolecek for (i = 0; i < timeout; i++) {
901 1.11.2.2 jdolecek /*
902 1.11.2.2 jdolecek * If the SMBI bit is 0 when we read it, then the bit will be
903 1.11.2.2 jdolecek * set and we have the semaphore
904 1.11.2.2 jdolecek */
905 1.11.2.2 jdolecek swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
906 1.11.2.2 jdolecek if (!(swsm & IXGBE_SWSM_SMBI)) {
907 1.11.2.2 jdolecek status = IXGBE_SUCCESS;
908 1.11.2.2 jdolecek break;
909 1.11.2.2 jdolecek }
910 1.11.2.2 jdolecek usec_delay(50);
911 1.11.2.2 jdolecek }
912 1.11.2.2 jdolecek
913 1.11.2.2 jdolecek /* Now get the semaphore between SW/FW through the REGSMP bit */
914 1.11.2.2 jdolecek if (status == IXGBE_SUCCESS) {
915 1.11.2.2 jdolecek for (i = 0; i < timeout; i++) {
916 1.11.2.2 jdolecek swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
917 1.11.2.2 jdolecek if (!(swsm & IXGBE_SWFW_REGSMP))
918 1.11.2.2 jdolecek break;
919 1.11.2.2 jdolecek
920 1.11.2.2 jdolecek usec_delay(50);
921 1.11.2.2 jdolecek }
922 1.11.2.2 jdolecek
923 1.11.2.2 jdolecek /*
924 1.11.2.2 jdolecek * Release semaphores and return error if SW NVM semaphore
925 1.11.2.2 jdolecek * was not granted because we don't have access to the EEPROM
926 1.11.2.2 jdolecek */
927 1.11.2.2 jdolecek if (i >= timeout) {
928 1.11.2.2 jdolecek ERROR_REPORT1(IXGBE_ERROR_POLLING,
929 1.11.2.2 jdolecek "REGSMP Software NVM semaphore not granted.\n");
930 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
931 1.11.2.2 jdolecek status = IXGBE_ERR_EEPROM;
932 1.11.2.2 jdolecek }
933 1.11.2.2 jdolecek } else {
934 1.11.2.2 jdolecek ERROR_REPORT1(IXGBE_ERROR_POLLING,
935 1.11.2.2 jdolecek "Software semaphore SMBI between device drivers "
936 1.11.2.2 jdolecek "not granted.\n");
937 1.11.2.2 jdolecek }
938 1.11.2.2 jdolecek
939 1.11.2.2 jdolecek return status;
940 1.11.2.2 jdolecek }
941 1.11.2.2 jdolecek
942 1.11.2.2 jdolecek /**
943 1.11.2.2 jdolecek * ixgbe_release_swfw_sync_semaphore - Release hardware semaphore
944 1.11.2.2 jdolecek * @hw: pointer to hardware structure
945 1.11.2.2 jdolecek *
946 1.11.2.2 jdolecek * This function clears hardware semaphore bits.
947 1.11.2.2 jdolecek **/
948 1.11.2.2 jdolecek static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
949 1.11.2.2 jdolecek {
950 1.11.2.2 jdolecek u32 swsm;
951 1.11.2.2 jdolecek
952 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_release_swfw_sync_semaphore");
953 1.11.2.2 jdolecek
954 1.11.2.2 jdolecek /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
955 1.11.2.2 jdolecek
956 1.11.2.2 jdolecek swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw));
957 1.11.2.2 jdolecek swsm &= ~IXGBE_SWFW_REGSMP;
958 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC_BY_MAC(hw), swsm);
959 1.11.2.2 jdolecek
960 1.11.2.2 jdolecek swsm = IXGBE_READ_REG(hw, IXGBE_SWSM_BY_MAC(hw));
961 1.11.2.2 jdolecek swsm &= ~IXGBE_SWSM_SMBI;
962 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_SWSM_BY_MAC(hw), swsm);
963 1.11.2.2 jdolecek
964 1.11.2.2 jdolecek IXGBE_WRITE_FLUSH(hw);
965 1.11.2.2 jdolecek }
966 1.11.2.2 jdolecek
967 1.11.2.2 jdolecek /**
968 1.11.2.2 jdolecek * ixgbe_init_swfw_sync_X540 - Release hardware semaphore
969 1.11.2.2 jdolecek * @hw: pointer to hardware structure
970 1.11.2.2 jdolecek *
971 1.11.2.2 jdolecek * This function reset hardware semaphore bits for a semaphore that may
972 1.11.2.2 jdolecek * have be left locked due to a catastrophic failure.
973 1.11.2.2 jdolecek **/
974 1.11.2.2 jdolecek void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
975 1.11.2.2 jdolecek {
976 1.11.2.2 jdolecek u32 rmask;
977 1.11.2.2 jdolecek
978 1.11.2.2 jdolecek /* First try to grab the semaphore but we don't need to bother
979 1.11.2.2 jdolecek * looking to see whether we got the lock or not since we do
980 1.11.2.2 jdolecek * the same thing regardless of whether we got the lock or not.
981 1.11.2.2 jdolecek * We got the lock - we release it.
982 1.11.2.2 jdolecek * We timeout trying to get the lock - we force its release.
983 1.11.2.2 jdolecek */
984 1.11.2.2 jdolecek ixgbe_get_swfw_sync_semaphore(hw);
985 1.11.2.2 jdolecek ixgbe_release_swfw_sync_semaphore(hw);
986 1.11.2.2 jdolecek
987 1.11.2.2 jdolecek /* Acquire and release all software resources. */
988 1.11.2.2 jdolecek rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
989 1.11.2.2 jdolecek IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM |
990 1.11.2.2 jdolecek IXGBE_GSSR_SW_MNG_SM;
991 1.11.2.2 jdolecek
992 1.11.2.2 jdolecek rmask |= IXGBE_GSSR_I2C_MASK;
993 1.11.2.2 jdolecek ixgbe_acquire_swfw_sync_X540(hw, rmask);
994 1.11.2.2 jdolecek ixgbe_release_swfw_sync_X540(hw, rmask);
995 1.11.2.2 jdolecek }
996 1.11.2.2 jdolecek
997 1.11.2.2 jdolecek /**
998 1.11.2.2 jdolecek * ixgbe_blink_led_start_X540 - Blink LED based on index.
999 1.11.2.2 jdolecek * @hw: pointer to hardware structure
1000 1.11.2.2 jdolecek * @index: led number to blink
1001 1.11.2.2 jdolecek *
1002 1.11.2.2 jdolecek * Devices that implement the version 2 interface:
1003 1.11.2.2 jdolecek * X540
1004 1.11.2.2 jdolecek **/
1005 1.11.2.2 jdolecek s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
1006 1.11.2.2 jdolecek {
1007 1.11.2.2 jdolecek u32 macc_reg;
1008 1.11.2.2 jdolecek u32 ledctl_reg;
1009 1.11.2.2 jdolecek ixgbe_link_speed speed;
1010 1.11.2.2 jdolecek bool link_up;
1011 1.11.2.2 jdolecek
1012 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_blink_led_start_X540");
1013 1.11.2.2 jdolecek
1014 1.11.2.2 jdolecek if (index > 3)
1015 1.11.2.2 jdolecek return IXGBE_ERR_PARAM;
1016 1.11.2.2 jdolecek
1017 1.11.2.2 jdolecek /*
1018 1.11.2.2 jdolecek * Link should be up in order for the blink bit in the LED control
1019 1.11.2.2 jdolecek * register to work. Force link and speed in the MAC if link is down.
1020 1.11.2.2 jdolecek * This will be reversed when we stop the blinking.
1021 1.11.2.2 jdolecek */
1022 1.11.2.2 jdolecek hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
1023 1.11.2.2 jdolecek if (link_up == FALSE) {
1024 1.11.2.2 jdolecek macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
1025 1.11.2.2 jdolecek macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
1026 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
1027 1.11.2.2 jdolecek }
1028 1.11.2.2 jdolecek /* Set the LED to LINK_UP + BLINK. */
1029 1.11.2.2 jdolecek ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
1030 1.11.2.2 jdolecek ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
1031 1.11.2.2 jdolecek ledctl_reg |= IXGBE_LED_BLINK(index);
1032 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
1033 1.11.2.2 jdolecek IXGBE_WRITE_FLUSH(hw);
1034 1.11.2.2 jdolecek
1035 1.11.2.2 jdolecek return IXGBE_SUCCESS;
1036 1.11.2.2 jdolecek }
1037 1.11.2.2 jdolecek
1038 1.11.2.2 jdolecek /**
1039 1.11.2.2 jdolecek * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
1040 1.11.2.2 jdolecek * @hw: pointer to hardware structure
1041 1.11.2.2 jdolecek * @index: led number to stop blinking
1042 1.11.2.2 jdolecek *
1043 1.11.2.2 jdolecek * Devices that implement the version 2 interface:
1044 1.11.2.2 jdolecek * X540
1045 1.11.2.2 jdolecek **/
1046 1.11.2.2 jdolecek s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
1047 1.11.2.2 jdolecek {
1048 1.11.2.2 jdolecek u32 macc_reg;
1049 1.11.2.2 jdolecek u32 ledctl_reg;
1050 1.11.2.2 jdolecek
1051 1.11.2.2 jdolecek if (index > 3)
1052 1.11.2.2 jdolecek return IXGBE_ERR_PARAM;
1053 1.11.2.2 jdolecek
1054 1.11.2.2 jdolecek DEBUGFUNC("ixgbe_blink_led_stop_X540");
1055 1.11.2.2 jdolecek
1056 1.11.2.2 jdolecek /* Restore the LED to its default value. */
1057 1.11.2.2 jdolecek ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
1058 1.11.2.2 jdolecek ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
1059 1.11.2.2 jdolecek ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
1060 1.11.2.2 jdolecek ledctl_reg &= ~IXGBE_LED_BLINK(index);
1061 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
1062 1.11.2.2 jdolecek
1063 1.11.2.2 jdolecek /* Unforce link and speed in the MAC. */
1064 1.11.2.2 jdolecek macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
1065 1.11.2.2 jdolecek macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
1066 1.11.2.2 jdolecek IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
1067 1.11.2.2 jdolecek IXGBE_WRITE_FLUSH(hw);
1068 1.11.2.2 jdolecek
1069 1.11.2.2 jdolecek return IXGBE_SUCCESS;
1070 1.11.2.2 jdolecek }
1071