1dc0cb1cdSDale Ghent /******************************************************************************
2dc0cb1cdSDale Ghent
3*48ed61a7SRobert Mustacchi Copyright (c) 2001-2017, Intel Corporation
4dc0cb1cdSDale Ghent All rights reserved.
5*48ed61a7SRobert Mustacchi
6*48ed61a7SRobert Mustacchi Redistribution and use in source and binary forms, with or without
7dc0cb1cdSDale Ghent modification, are permitted provided that the following conditions are met:
8*48ed61a7SRobert Mustacchi
9*48ed61a7SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
10dc0cb1cdSDale Ghent this list of conditions and the following disclaimer.
11*48ed61a7SRobert Mustacchi
12*48ed61a7SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
13*48ed61a7SRobert Mustacchi notice, this list of conditions and the following disclaimer in the
14dc0cb1cdSDale Ghent documentation and/or other materials provided with the distribution.
15*48ed61a7SRobert Mustacchi
16*48ed61a7SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
17*48ed61a7SRobert Mustacchi contributors may be used to endorse or promote products derived from
18dc0cb1cdSDale Ghent this software without specific prior written permission.
19*48ed61a7SRobert Mustacchi
20dc0cb1cdSDale Ghent THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21*48ed61a7SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*48ed61a7SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*48ed61a7SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24*48ed61a7SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*48ed61a7SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*48ed61a7SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*48ed61a7SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*48ed61a7SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29dc0cb1cdSDale Ghent ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30dc0cb1cdSDale Ghent POSSIBILITY OF SUCH DAMAGE.
31dc0cb1cdSDale Ghent
32dc0cb1cdSDale Ghent ******************************************************************************/
33dc0cb1cdSDale Ghent /*$FreeBSD$*/
34dc0cb1cdSDale Ghent
35dc0cb1cdSDale Ghent #include "ixgbe_x550.h"
36dc0cb1cdSDale Ghent #include "ixgbe_x540.h"
37dc0cb1cdSDale Ghent #include "ixgbe_type.h"
38dc0cb1cdSDale Ghent #include "ixgbe_api.h"
39dc0cb1cdSDale Ghent #include "ixgbe_common.h"
40dc0cb1cdSDale Ghent #include "ixgbe_phy.h"
41dc0cb1cdSDale Ghent
42dc0cb1cdSDale Ghent static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
43*48ed61a7SRobert Mustacchi static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
44*48ed61a7SRobert Mustacchi static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
45*48ed61a7SRobert Mustacchi static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
46dc0cb1cdSDale Ghent
47dc0cb1cdSDale Ghent /**
48dc0cb1cdSDale Ghent * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
49dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
50dc0cb1cdSDale Ghent *
51dc0cb1cdSDale Ghent * Initialize the function pointers and assign the MAC type for X550.
52dc0cb1cdSDale Ghent * Does not touch the hardware.
53dc0cb1cdSDale Ghent **/
ixgbe_init_ops_X550(struct ixgbe_hw * hw)54dc0cb1cdSDale Ghent s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
55dc0cb1cdSDale Ghent {
56dc0cb1cdSDale Ghent struct ixgbe_mac_info *mac = &hw->mac;
57dc0cb1cdSDale Ghent struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
58dc0cb1cdSDale Ghent s32 ret_val;
59dc0cb1cdSDale Ghent
60dc0cb1cdSDale Ghent DEBUGFUNC("ixgbe_init_ops_X550");
61dc0cb1cdSDale Ghent
62dc0cb1cdSDale Ghent ret_val = ixgbe_init_ops_X540(hw);
63dc0cb1cdSDale Ghent mac->ops.dmac_config = ixgbe_dmac_config_X550;
64dc0cb1cdSDale Ghent mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
65dc0cb1cdSDale Ghent mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
66*48ed61a7SRobert Mustacchi mac->ops.setup_eee = NULL;
67dc0cb1cdSDale Ghent mac->ops.set_source_address_pruning =
68dc0cb1cdSDale Ghent ixgbe_set_source_address_pruning_X550;
69dc0cb1cdSDale Ghent mac->ops.set_ethertype_anti_spoofing =
70dc0cb1cdSDale Ghent ixgbe_set_ethertype_anti_spoofing_X550;
71dc0cb1cdSDale Ghent
72dc0cb1cdSDale Ghent mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
73dc0cb1cdSDale Ghent eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
74dc0cb1cdSDale Ghent eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
75dc0cb1cdSDale Ghent eeprom->ops.read = ixgbe_read_ee_hostif_X550;
76dc0cb1cdSDale Ghent eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
77dc0cb1cdSDale Ghent eeprom->ops.write = ixgbe_write_ee_hostif_X550;
78dc0cb1cdSDale Ghent eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
79dc0cb1cdSDale Ghent eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
80dc0cb1cdSDale Ghent eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
81dc0cb1cdSDale Ghent
82dc0cb1cdSDale Ghent mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
83dc0cb1cdSDale Ghent mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
84dc0cb1cdSDale Ghent mac->ops.mdd_event = ixgbe_mdd_event_X550;
85dc0cb1cdSDale Ghent mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
86dc0cb1cdSDale Ghent mac->ops.disable_rx = ixgbe_disable_rx_x550;
87*48ed61a7SRobert Mustacchi /* Manageability interface */
88*48ed61a7SRobert Mustacchi mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_x550;
89*48ed61a7SRobert Mustacchi switch (hw->device_id) {
90*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_X_1G_T:
91*48ed61a7SRobert Mustacchi hw->mac.ops.led_on = NULL;
92*48ed61a7SRobert Mustacchi hw->mac.ops.led_off = NULL;
93*48ed61a7SRobert Mustacchi break;
94*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_X_10G_T:
95*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_10G_T:
96dc0cb1cdSDale Ghent hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
97dc0cb1cdSDale Ghent hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
98*48ed61a7SRobert Mustacchi break;
99*48ed61a7SRobert Mustacchi default:
100*48ed61a7SRobert Mustacchi break;
101dc0cb1cdSDale Ghent }
102dc0cb1cdSDale Ghent return ret_val;
103dc0cb1cdSDale Ghent }
104dc0cb1cdSDale Ghent
105dc0cb1cdSDale Ghent /**
106dc0cb1cdSDale Ghent * ixgbe_read_cs4227 - Read CS4227 register
107dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
108dc0cb1cdSDale Ghent * @reg: register number to write
109dc0cb1cdSDale Ghent * @value: pointer to receive value read
110dc0cb1cdSDale Ghent *
111dc0cb1cdSDale Ghent * Returns status code
112dc0cb1cdSDale Ghent **/
ixgbe_read_cs4227(struct ixgbe_hw * hw,u16 reg,u16 * value)113dc0cb1cdSDale Ghent static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
114dc0cb1cdSDale Ghent {
115*48ed61a7SRobert Mustacchi return hw->link.ops.read_link_unlocked(hw, hw->link.addr, reg, value);
116dc0cb1cdSDale Ghent }
117dc0cb1cdSDale Ghent
118dc0cb1cdSDale Ghent /**
119dc0cb1cdSDale Ghent * ixgbe_write_cs4227 - Write CS4227 register
120dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
121dc0cb1cdSDale Ghent * @reg: register number to write
122dc0cb1cdSDale Ghent * @value: value to write to register
123dc0cb1cdSDale Ghent *
124dc0cb1cdSDale Ghent * Returns status code
125dc0cb1cdSDale Ghent **/
ixgbe_write_cs4227(struct ixgbe_hw * hw,u16 reg,u16 value)126dc0cb1cdSDale Ghent static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
127dc0cb1cdSDale Ghent {
128*48ed61a7SRobert Mustacchi return hw->link.ops.write_link_unlocked(hw, hw->link.addr, reg, value);
129dc0cb1cdSDale Ghent }
130dc0cb1cdSDale Ghent
131dc0cb1cdSDale Ghent /**
132dc0cb1cdSDale Ghent * ixgbe_read_pe - Read register from port expander
133dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
134dc0cb1cdSDale Ghent * @reg: register number to read
135dc0cb1cdSDale Ghent * @value: pointer to receive read value
136dc0cb1cdSDale Ghent *
137dc0cb1cdSDale Ghent * Returns status code
138dc0cb1cdSDale Ghent **/
ixgbe_read_pe(struct ixgbe_hw * hw,u8 reg,u8 * value)139dc0cb1cdSDale Ghent static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
140dc0cb1cdSDale Ghent {
141dc0cb1cdSDale Ghent s32 status;
142dc0cb1cdSDale Ghent
143dc0cb1cdSDale Ghent status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
144dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
145dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
146dc0cb1cdSDale Ghent "port expander access failed with %d\n", status);
147dc0cb1cdSDale Ghent return status;
148dc0cb1cdSDale Ghent }
149dc0cb1cdSDale Ghent
150dc0cb1cdSDale Ghent /**
151dc0cb1cdSDale Ghent * ixgbe_write_pe - Write register to port expander
152dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
153dc0cb1cdSDale Ghent * @reg: register number to write
154dc0cb1cdSDale Ghent * @value: value to write
155dc0cb1cdSDale Ghent *
156dc0cb1cdSDale Ghent * Returns status code
157dc0cb1cdSDale Ghent **/
ixgbe_write_pe(struct ixgbe_hw * hw,u8 reg,u8 value)158dc0cb1cdSDale Ghent static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
159dc0cb1cdSDale Ghent {
160dc0cb1cdSDale Ghent s32 status;
161dc0cb1cdSDale Ghent
162dc0cb1cdSDale Ghent status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
163dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
164dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
165dc0cb1cdSDale Ghent "port expander access failed with %d\n", status);
166dc0cb1cdSDale Ghent return status;
167dc0cb1cdSDale Ghent }
168dc0cb1cdSDale Ghent
169dc0cb1cdSDale Ghent /**
170dc0cb1cdSDale Ghent * ixgbe_reset_cs4227 - Reset CS4227 using port expander
171dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
172dc0cb1cdSDale Ghent *
173dc0cb1cdSDale Ghent * This function assumes that the caller has acquired the proper semaphore.
174dc0cb1cdSDale Ghent * Returns error code
175dc0cb1cdSDale Ghent **/
ixgbe_reset_cs4227(struct ixgbe_hw * hw)176dc0cb1cdSDale Ghent static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
177dc0cb1cdSDale Ghent {
178dc0cb1cdSDale Ghent s32 status;
179dc0cb1cdSDale Ghent u32 retry;
180dc0cb1cdSDale Ghent u16 value;
181dc0cb1cdSDale Ghent u8 reg;
182dc0cb1cdSDale Ghent
183dc0cb1cdSDale Ghent /* Trigger hard reset. */
184dc0cb1cdSDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
185dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
186dc0cb1cdSDale Ghent return status;
187dc0cb1cdSDale Ghent reg |= IXGBE_PE_BIT1;
188dc0cb1cdSDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
189dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
190dc0cb1cdSDale Ghent return status;
191dc0cb1cdSDale Ghent
192dc0cb1cdSDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, ®);
193dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
194dc0cb1cdSDale Ghent return status;
195dc0cb1cdSDale Ghent reg &= ~IXGBE_PE_BIT1;
196dc0cb1cdSDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
197dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
198dc0cb1cdSDale Ghent return status;
199dc0cb1cdSDale Ghent
200dc0cb1cdSDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
201dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
202dc0cb1cdSDale Ghent return status;
203dc0cb1cdSDale Ghent reg &= ~IXGBE_PE_BIT1;
204dc0cb1cdSDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
205dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
206dc0cb1cdSDale Ghent return status;
207dc0cb1cdSDale Ghent
208dc0cb1cdSDale Ghent usec_delay(IXGBE_CS4227_RESET_HOLD);
209dc0cb1cdSDale Ghent
210dc0cb1cdSDale Ghent status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, ®);
211dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
212dc0cb1cdSDale Ghent return status;
213dc0cb1cdSDale Ghent reg |= IXGBE_PE_BIT1;
214dc0cb1cdSDale Ghent status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
215dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS)
216dc0cb1cdSDale Ghent return status;
217dc0cb1cdSDale Ghent
218dc0cb1cdSDale Ghent /* Wait for the reset to complete. */
219dc0cb1cdSDale Ghent msec_delay(IXGBE_CS4227_RESET_DELAY);
220dc0cb1cdSDale Ghent for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
221dc0cb1cdSDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
222dc0cb1cdSDale Ghent &value);
223dc0cb1cdSDale Ghent if (status == IXGBE_SUCCESS &&
224dc0cb1cdSDale Ghent value == IXGBE_CS4227_EEPROM_LOAD_OK)
225dc0cb1cdSDale Ghent break;
226dc0cb1cdSDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
227dc0cb1cdSDale Ghent }
228dc0cb1cdSDale Ghent if (retry == IXGBE_CS4227_RETRIES) {
229dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
230dc0cb1cdSDale Ghent "CS4227 reset did not complete.");
231dc0cb1cdSDale Ghent return IXGBE_ERR_PHY;
232dc0cb1cdSDale Ghent }
233dc0cb1cdSDale Ghent
234dc0cb1cdSDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
235dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS ||
236dc0cb1cdSDale Ghent !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
237dc0cb1cdSDale Ghent ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
238dc0cb1cdSDale Ghent "CS4227 EEPROM did not load successfully.");
239dc0cb1cdSDale Ghent return IXGBE_ERR_PHY;
240dc0cb1cdSDale Ghent }
241dc0cb1cdSDale Ghent
242dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
243dc0cb1cdSDale Ghent }
244dc0cb1cdSDale Ghent
245dc0cb1cdSDale Ghent /**
246dc0cb1cdSDale Ghent * ixgbe_check_cs4227 - Check CS4227 and reset as needed
247dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
248dc0cb1cdSDale Ghent **/
ixgbe_check_cs4227(struct ixgbe_hw * hw)249dc0cb1cdSDale Ghent static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
250dc0cb1cdSDale Ghent {
251dc0cb1cdSDale Ghent s32 status = IXGBE_SUCCESS;
252dc0cb1cdSDale Ghent u32 swfw_mask = hw->phy.phy_semaphore_mask;
253dc0cb1cdSDale Ghent u16 value = 0;
254dc0cb1cdSDale Ghent u8 retry;
255dc0cb1cdSDale Ghent
256dc0cb1cdSDale Ghent for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
257dc0cb1cdSDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
258dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS) {
259dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
260dc0cb1cdSDale Ghent "semaphore failed with %d", status);
261dc0cb1cdSDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
262dc0cb1cdSDale Ghent continue;
263dc0cb1cdSDale Ghent }
264dc0cb1cdSDale Ghent
265dc0cb1cdSDale Ghent /* Get status of reset flow. */
266dc0cb1cdSDale Ghent status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
267dc0cb1cdSDale Ghent
268dc0cb1cdSDale Ghent if (status == IXGBE_SUCCESS &&
269dc0cb1cdSDale Ghent value == IXGBE_CS4227_RESET_COMPLETE)
270dc0cb1cdSDale Ghent goto out;
271dc0cb1cdSDale Ghent
272dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS ||
273dc0cb1cdSDale Ghent value != IXGBE_CS4227_RESET_PENDING)
274dc0cb1cdSDale Ghent break;
275dc0cb1cdSDale Ghent
276dc0cb1cdSDale Ghent /* Reset is pending. Wait and check again. */
277dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
278dc0cb1cdSDale Ghent msec_delay(IXGBE_CS4227_CHECK_DELAY);
279dc0cb1cdSDale Ghent }
280dc0cb1cdSDale Ghent
281dc0cb1cdSDale Ghent /* If still pending, assume other instance failed. */
282dc0cb1cdSDale Ghent if (retry == IXGBE_CS4227_RETRIES) {
283dc0cb1cdSDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
284dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS) {
285dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
286dc0cb1cdSDale Ghent "semaphore failed with %d", status);
287dc0cb1cdSDale Ghent return;
288dc0cb1cdSDale Ghent }
289dc0cb1cdSDale Ghent }
290dc0cb1cdSDale Ghent
291dc0cb1cdSDale Ghent /* Reset the CS4227. */
292dc0cb1cdSDale Ghent status = ixgbe_reset_cs4227(hw);
293dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS) {
294dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
295dc0cb1cdSDale Ghent "CS4227 reset failed: %d", status);
296dc0cb1cdSDale Ghent goto out;
297dc0cb1cdSDale Ghent }
298dc0cb1cdSDale Ghent
299dc0cb1cdSDale Ghent /* Reset takes so long, temporarily release semaphore in case the
300dc0cb1cdSDale Ghent * other driver instance is waiting for the reset indication.
301dc0cb1cdSDale Ghent */
302dc0cb1cdSDale Ghent ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
303dc0cb1cdSDale Ghent IXGBE_CS4227_RESET_PENDING);
304dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
305dc0cb1cdSDale Ghent msec_delay(10);
306dc0cb1cdSDale Ghent status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
307dc0cb1cdSDale Ghent if (status != IXGBE_SUCCESS) {
308dc0cb1cdSDale Ghent ERROR_REPORT2(IXGBE_ERROR_CAUTION,
309dc0cb1cdSDale Ghent "semaphore failed with %d", status);
310dc0cb1cdSDale Ghent return;
311dc0cb1cdSDale Ghent }
312dc0cb1cdSDale Ghent
313dc0cb1cdSDale Ghent /* Record completion for next time. */
314dc0cb1cdSDale Ghent status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
315dc0cb1cdSDale Ghent IXGBE_CS4227_RESET_COMPLETE);
316dc0cb1cdSDale Ghent
317dc0cb1cdSDale Ghent out:
318dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, swfw_mask);
319dc0cb1cdSDale Ghent msec_delay(hw->eeprom.semaphore_delay);
320dc0cb1cdSDale Ghent }
321dc0cb1cdSDale Ghent
322dc0cb1cdSDale Ghent /**
323dc0cb1cdSDale Ghent * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
324dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
325dc0cb1cdSDale Ghent **/
ixgbe_setup_mux_ctl(struct ixgbe_hw * hw)326dc0cb1cdSDale Ghent static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
327dc0cb1cdSDale Ghent {
328dc0cb1cdSDale Ghent u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
329dc0cb1cdSDale Ghent
330dc0cb1cdSDale Ghent if (hw->bus.lan_id) {
331dc0cb1cdSDale Ghent esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
332dc0cb1cdSDale Ghent esdp |= IXGBE_ESDP_SDP1_DIR;
333dc0cb1cdSDale Ghent }
334dc0cb1cdSDale Ghent esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
335dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
336dc0cb1cdSDale Ghent IXGBE_WRITE_FLUSH(hw);
337dc0cb1cdSDale Ghent }
338dc0cb1cdSDale Ghent
339dc0cb1cdSDale Ghent /**
340dc0cb1cdSDale Ghent * ixgbe_identify_phy_x550em - Get PHY type based on device id
341dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
342dc0cb1cdSDale Ghent *
343dc0cb1cdSDale Ghent * Returns error code
344dc0cb1cdSDale Ghent */
ixgbe_identify_phy_x550em(struct ixgbe_hw * hw)345dc0cb1cdSDale Ghent static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
346dc0cb1cdSDale Ghent {
347*48ed61a7SRobert Mustacchi hw->mac.ops.set_lan_id(hw);
348*48ed61a7SRobert Mustacchi
349*48ed61a7SRobert Mustacchi ixgbe_read_mng_if_sel_x550em(hw);
350*48ed61a7SRobert Mustacchi
351dc0cb1cdSDale Ghent switch (hw->device_id) {
352*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_SFP:
353*48ed61a7SRobert Mustacchi return ixgbe_identify_module_generic(hw);
354dc0cb1cdSDale Ghent case IXGBE_DEV_ID_X550EM_X_SFP:
355dc0cb1cdSDale Ghent /* set up for CS4227 usage */
356dc0cb1cdSDale Ghent ixgbe_setup_mux_ctl(hw);
357dc0cb1cdSDale Ghent ixgbe_check_cs4227(hw);
358*48ed61a7SRobert Mustacchi /* Fallthrough */
359dc0cb1cdSDale Ghent
360*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_SFP_N:
361dc0cb1cdSDale Ghent return ixgbe_identify_module_generic(hw);
362dc0cb1cdSDale Ghent break;
363dc0cb1cdSDale Ghent case IXGBE_DEV_ID_X550EM_X_KX4:
364dc0cb1cdSDale Ghent hw->phy.type = ixgbe_phy_x550em_kx4;
365dc0cb1cdSDale Ghent break;
366*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_X_XFI:
367*48ed61a7SRobert Mustacchi hw->phy.type = ixgbe_phy_x550em_xfi;
368*48ed61a7SRobert Mustacchi break;
369dc0cb1cdSDale Ghent case IXGBE_DEV_ID_X550EM_X_KR:
370*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_KR:
371*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_KR_L:
372dc0cb1cdSDale Ghent hw->phy.type = ixgbe_phy_x550em_kr;
373dc0cb1cdSDale Ghent break;
374*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_10G_T:
375dc0cb1cdSDale Ghent case IXGBE_DEV_ID_X550EM_X_10G_T:
376dc0cb1cdSDale Ghent return ixgbe_identify_phy_generic(hw);
377*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_X_1G_T:
378*48ed61a7SRobert Mustacchi hw->phy.type = ixgbe_phy_ext_1g_t;
379*48ed61a7SRobert Mustacchi break;
380*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_1G_T:
381*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_1G_T_L:
382*48ed61a7SRobert Mustacchi hw->phy.type = ixgbe_phy_fw;
383*48ed61a7SRobert Mustacchi if (hw->bus.lan_id)
384*48ed61a7SRobert Mustacchi hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM;
385*48ed61a7SRobert Mustacchi else
386*48ed61a7SRobert Mustacchi hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM;
387*48ed61a7SRobert Mustacchi break;
388dc0cb1cdSDale Ghent default:
389dc0cb1cdSDale Ghent break;
390dc0cb1cdSDale Ghent }
391dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
392dc0cb1cdSDale Ghent }
393dc0cb1cdSDale Ghent
394*48ed61a7SRobert Mustacchi /**
395*48ed61a7SRobert Mustacchi * ixgbe_fw_phy_activity - Perform an activity on a PHY
396*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
397*48ed61a7SRobert Mustacchi * @activity: activity to perform
398*48ed61a7SRobert Mustacchi * @data: Pointer to 4 32-bit words of data
399*48ed61a7SRobert Mustacchi */
ixgbe_fw_phy_activity(struct ixgbe_hw * hw,u16 activity,u32 (* data)[FW_PHY_ACT_DATA_COUNT])400*48ed61a7SRobert Mustacchi s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
401*48ed61a7SRobert Mustacchi u32 (*data)[FW_PHY_ACT_DATA_COUNT])
402*48ed61a7SRobert Mustacchi {
403*48ed61a7SRobert Mustacchi union {
404*48ed61a7SRobert Mustacchi struct ixgbe_hic_phy_activity_req cmd;
405*48ed61a7SRobert Mustacchi struct ixgbe_hic_phy_activity_resp rsp;
406*48ed61a7SRobert Mustacchi } hic;
407*48ed61a7SRobert Mustacchi u16 retries = FW_PHY_ACT_RETRIES;
408*48ed61a7SRobert Mustacchi s32 rc;
409*48ed61a7SRobert Mustacchi u16 i;
410*48ed61a7SRobert Mustacchi
411*48ed61a7SRobert Mustacchi do {
412*48ed61a7SRobert Mustacchi memset(&hic, 0, sizeof(hic));
413*48ed61a7SRobert Mustacchi hic.cmd.hdr.cmd = FW_PHY_ACT_REQ_CMD;
414*48ed61a7SRobert Mustacchi hic.cmd.hdr.buf_len = FW_PHY_ACT_REQ_LEN;
415*48ed61a7SRobert Mustacchi hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
416*48ed61a7SRobert Mustacchi hic.cmd.port_number = hw->bus.lan_id;
417*48ed61a7SRobert Mustacchi hic.cmd.activity_id = IXGBE_CPU_TO_LE16(activity);
418*48ed61a7SRobert Mustacchi for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
419*48ed61a7SRobert Mustacchi hic.cmd.data[i] = IXGBE_CPU_TO_BE32((*data)[i]);
420*48ed61a7SRobert Mustacchi
421*48ed61a7SRobert Mustacchi rc = ixgbe_host_interface_command(hw, (u32 *)&hic.cmd,
422*48ed61a7SRobert Mustacchi sizeof(hic.cmd),
423*48ed61a7SRobert Mustacchi IXGBE_HI_COMMAND_TIMEOUT,
424*48ed61a7SRobert Mustacchi TRUE);
425*48ed61a7SRobert Mustacchi if (rc != IXGBE_SUCCESS)
426*48ed61a7SRobert Mustacchi return rc;
427*48ed61a7SRobert Mustacchi if (hic.rsp.hdr.cmd_or_resp.ret_status ==
428*48ed61a7SRobert Mustacchi FW_CEM_RESP_STATUS_SUCCESS) {
429*48ed61a7SRobert Mustacchi for (i = 0; i < FW_PHY_ACT_DATA_COUNT; ++i)
430*48ed61a7SRobert Mustacchi (*data)[i] = IXGBE_BE32_TO_CPU(hic.rsp.data[i]);
431*48ed61a7SRobert Mustacchi return IXGBE_SUCCESS;
432*48ed61a7SRobert Mustacchi }
433*48ed61a7SRobert Mustacchi usec_delay(20);
434*48ed61a7SRobert Mustacchi --retries;
435*48ed61a7SRobert Mustacchi } while (retries > 0);
436*48ed61a7SRobert Mustacchi
437*48ed61a7SRobert Mustacchi return IXGBE_ERR_HOST_INTERFACE_COMMAND;
438*48ed61a7SRobert Mustacchi }
439*48ed61a7SRobert Mustacchi
440*48ed61a7SRobert Mustacchi static const struct {
441*48ed61a7SRobert Mustacchi u16 fw_speed;
442*48ed61a7SRobert Mustacchi ixgbe_link_speed phy_speed;
443*48ed61a7SRobert Mustacchi } ixgbe_fw_map[] = {
444*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_10, IXGBE_LINK_SPEED_10_FULL },
445*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_100, IXGBE_LINK_SPEED_100_FULL },
446*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_1G, IXGBE_LINK_SPEED_1GB_FULL },
447*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_2_5G, IXGBE_LINK_SPEED_2_5GB_FULL },
448*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_5G, IXGBE_LINK_SPEED_5GB_FULL },
449*48ed61a7SRobert Mustacchi { FW_PHY_ACT_LINK_SPEED_10G, IXGBE_LINK_SPEED_10GB_FULL },
450*48ed61a7SRobert Mustacchi };
451*48ed61a7SRobert Mustacchi
452*48ed61a7SRobert Mustacchi /**
453*48ed61a7SRobert Mustacchi * ixgbe_get_phy_id_fw - Get the phy ID via firmware command
454*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
455*48ed61a7SRobert Mustacchi *
456*48ed61a7SRobert Mustacchi * Returns error code
457*48ed61a7SRobert Mustacchi */
ixgbe_get_phy_id_fw(struct ixgbe_hw * hw)458*48ed61a7SRobert Mustacchi static s32 ixgbe_get_phy_id_fw(struct ixgbe_hw *hw)
459*48ed61a7SRobert Mustacchi {
460*48ed61a7SRobert Mustacchi u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 };
461*48ed61a7SRobert Mustacchi u16 phy_speeds;
462*48ed61a7SRobert Mustacchi u16 phy_id_lo;
463*48ed61a7SRobert Mustacchi s32 rc;
464*48ed61a7SRobert Mustacchi u16 i;
465*48ed61a7SRobert Mustacchi
466*48ed61a7SRobert Mustacchi rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_PHY_INFO, &info);
467*48ed61a7SRobert Mustacchi if (rc)
468*48ed61a7SRobert Mustacchi return rc;
469*48ed61a7SRobert Mustacchi
470*48ed61a7SRobert Mustacchi hw->phy.speeds_supported = 0;
471*48ed61a7SRobert Mustacchi phy_speeds = info[0] & FW_PHY_INFO_SPEED_MASK;
472*48ed61a7SRobert Mustacchi for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
473*48ed61a7SRobert Mustacchi if (phy_speeds & ixgbe_fw_map[i].fw_speed)
474*48ed61a7SRobert Mustacchi hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
475*48ed61a7SRobert Mustacchi }
476*48ed61a7SRobert Mustacchi if (!hw->phy.autoneg_advertised)
477*48ed61a7SRobert Mustacchi hw->phy.autoneg_advertised = hw->phy.speeds_supported;
478*48ed61a7SRobert Mustacchi
479*48ed61a7SRobert Mustacchi hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
480*48ed61a7SRobert Mustacchi phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
481*48ed61a7SRobert Mustacchi hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK;
482*48ed61a7SRobert Mustacchi hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK;
483*48ed61a7SRobert Mustacchi if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK)
484*48ed61a7SRobert Mustacchi return IXGBE_ERR_PHY_ADDR_INVALID;
485*48ed61a7SRobert Mustacchi return IXGBE_SUCCESS;
486*48ed61a7SRobert Mustacchi }
487*48ed61a7SRobert Mustacchi
488*48ed61a7SRobert Mustacchi /**
489*48ed61a7SRobert Mustacchi * ixgbe_identify_phy_fw - Get PHY type based on firmware command
490*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
491*48ed61a7SRobert Mustacchi *
492*48ed61a7SRobert Mustacchi * Returns error code
493*48ed61a7SRobert Mustacchi */
ixgbe_identify_phy_fw(struct ixgbe_hw * hw)494*48ed61a7SRobert Mustacchi static s32 ixgbe_identify_phy_fw(struct ixgbe_hw *hw)
495*48ed61a7SRobert Mustacchi {
496*48ed61a7SRobert Mustacchi if (hw->bus.lan_id)
497*48ed61a7SRobert Mustacchi hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM;
498*48ed61a7SRobert Mustacchi else
499*48ed61a7SRobert Mustacchi hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM;
500*48ed61a7SRobert Mustacchi
501*48ed61a7SRobert Mustacchi hw->phy.type = ixgbe_phy_fw;
502*48ed61a7SRobert Mustacchi hw->phy.ops.read_reg = NULL;
503*48ed61a7SRobert Mustacchi hw->phy.ops.write_reg = NULL;
504*48ed61a7SRobert Mustacchi return ixgbe_get_phy_id_fw(hw);
505*48ed61a7SRobert Mustacchi }
506*48ed61a7SRobert Mustacchi
507*48ed61a7SRobert Mustacchi /**
508*48ed61a7SRobert Mustacchi * ixgbe_shutdown_fw_phy - Shutdown a firmware-controlled PHY
509*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
510*48ed61a7SRobert Mustacchi *
511*48ed61a7SRobert Mustacchi * Returns error code
512*48ed61a7SRobert Mustacchi */
ixgbe_shutdown_fw_phy(struct ixgbe_hw * hw)513*48ed61a7SRobert Mustacchi s32 ixgbe_shutdown_fw_phy(struct ixgbe_hw *hw)
514*48ed61a7SRobert Mustacchi {
515*48ed61a7SRobert Mustacchi u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
516*48ed61a7SRobert Mustacchi
517*48ed61a7SRobert Mustacchi setup[0] = FW_PHY_ACT_FORCE_LINK_DOWN_OFF;
518*48ed61a7SRobert Mustacchi return ixgbe_fw_phy_activity(hw, FW_PHY_ACT_FORCE_LINK_DOWN, &setup);
519*48ed61a7SRobert Mustacchi }
520*48ed61a7SRobert Mustacchi
ixgbe_read_phy_reg_x550em(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 * phy_data)521dc0cb1cdSDale Ghent static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
522dc0cb1cdSDale Ghent u32 device_type, u16 *phy_data)
523dc0cb1cdSDale Ghent {
524dc0cb1cdSDale Ghent UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
525dc0cb1cdSDale Ghent return IXGBE_NOT_IMPLEMENTED;
526dc0cb1cdSDale Ghent }
527dc0cb1cdSDale Ghent
ixgbe_write_phy_reg_x550em(struct ixgbe_hw * hw,u32 reg_addr,u32 device_type,u16 phy_data)528dc0cb1cdSDale Ghent static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
529dc0cb1cdSDale Ghent u32 device_type, u16 phy_data)
530dc0cb1cdSDale Ghent {
531dc0cb1cdSDale Ghent UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
532dc0cb1cdSDale Ghent return IXGBE_NOT_IMPLEMENTED;
533dc0cb1cdSDale Ghent }
534dc0cb1cdSDale Ghent
535*48ed61a7SRobert Mustacchi /**
536*48ed61a7SRobert Mustacchi * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
537*48ed61a7SRobert Mustacchi * @hw: pointer to the hardware structure
538*48ed61a7SRobert Mustacchi * @addr: I2C bus address to read from
539*48ed61a7SRobert Mustacchi * @reg: I2C device register to read from
540*48ed61a7SRobert Mustacchi * @val: pointer to location to receive read value
541*48ed61a7SRobert Mustacchi *
542*48ed61a7SRobert Mustacchi * Returns an error code on error.
543*48ed61a7SRobert Mustacchi **/
ixgbe_read_i2c_combined_generic(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val)544*48ed61a7SRobert Mustacchi static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
545*48ed61a7SRobert Mustacchi u16 reg, u16 *val)
546*48ed61a7SRobert Mustacchi {
547*48ed61a7SRobert Mustacchi return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
548*48ed61a7SRobert Mustacchi }
549*48ed61a7SRobert Mustacchi
550*48ed61a7SRobert Mustacchi /**
551*48ed61a7SRobert Mustacchi * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
552*48ed61a7SRobert Mustacchi * @hw: pointer to the hardware structure
553*48ed61a7SRobert Mustacchi * @addr: I2C bus address to read from
554*48ed61a7SRobert Mustacchi * @reg: I2C device register to read from
555*48ed61a7SRobert Mustacchi * @val: pointer to location to receive read value
556*48ed61a7SRobert Mustacchi *
557*48ed61a7SRobert Mustacchi * Returns an error code on error.
558*48ed61a7SRobert Mustacchi **/
559*48ed61a7SRobert Mustacchi static s32
ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 * val)560*48ed61a7SRobert Mustacchi ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
561*48ed61a7SRobert Mustacchi u16 reg, u16 *val)
562*48ed61a7SRobert Mustacchi {
563*48ed61a7SRobert Mustacchi return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
564*48ed61a7SRobert Mustacchi }
565*48ed61a7SRobert Mustacchi
566*48ed61a7SRobert Mustacchi /**
567*48ed61a7SRobert Mustacchi * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
568*48ed61a7SRobert Mustacchi * @hw: pointer to the hardware structure
569*48ed61a7SRobert Mustacchi * @addr: I2C bus address to write to
570*48ed61a7SRobert Mustacchi * @reg: I2C device register to write to
571*48ed61a7SRobert Mustacchi * @val: value to write
572*48ed61a7SRobert Mustacchi *
573*48ed61a7SRobert Mustacchi * Returns an error code on error.
574*48ed61a7SRobert Mustacchi **/
ixgbe_write_i2c_combined_generic(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val)575*48ed61a7SRobert Mustacchi static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
576*48ed61a7SRobert Mustacchi u8 addr, u16 reg, u16 val)
577*48ed61a7SRobert Mustacchi {
578*48ed61a7SRobert Mustacchi return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
579*48ed61a7SRobert Mustacchi }
580*48ed61a7SRobert Mustacchi
581*48ed61a7SRobert Mustacchi /**
582*48ed61a7SRobert Mustacchi * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
583*48ed61a7SRobert Mustacchi * @hw: pointer to the hardware structure
584*48ed61a7SRobert Mustacchi * @addr: I2C bus address to write to
585*48ed61a7SRobert Mustacchi * @reg: I2C device register to write to
586*48ed61a7SRobert Mustacchi * @val: value to write
587*48ed61a7SRobert Mustacchi *
588*48ed61a7SRobert Mustacchi * Returns an error code on error.
589*48ed61a7SRobert Mustacchi **/
590*48ed61a7SRobert Mustacchi static s32
ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw * hw,u8 addr,u16 reg,u16 val)591*48ed61a7SRobert Mustacchi ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
592*48ed61a7SRobert Mustacchi u8 addr, u16 reg, u16 val)
593*48ed61a7SRobert Mustacchi {
594*48ed61a7SRobert Mustacchi return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
595*48ed61a7SRobert Mustacchi }
596*48ed61a7SRobert Mustacchi
597dc0cb1cdSDale Ghent /**
598dc0cb1cdSDale Ghent * ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
599dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
600dc0cb1cdSDale Ghent *
601dc0cb1cdSDale Ghent * Initialize the function pointers and for MAC type X550EM.
602dc0cb1cdSDale Ghent * Does not touch the hardware.
603dc0cb1cdSDale Ghent **/
ixgbe_init_ops_X550EM(struct ixgbe_hw * hw)604dc0cb1cdSDale Ghent s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
605dc0cb1cdSDale Ghent {
606dc0cb1cdSDale Ghent struct ixgbe_mac_info *mac = &hw->mac;
607dc0cb1cdSDale Ghent struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
608dc0cb1cdSDale Ghent struct ixgbe_phy_info *phy = &hw->phy;
609dc0cb1cdSDale Ghent s32 ret_val;
610dc0cb1cdSDale Ghent
611dc0cb1cdSDale Ghent DEBUGFUNC("ixgbe_init_ops_X550EM");
612dc0cb1cdSDale Ghent
613dc0cb1cdSDale Ghent /* Similar to X550 so start there. */
614dc0cb1cdSDale Ghent ret_val = ixgbe_init_ops_X550(hw);
615dc0cb1cdSDale Ghent
616dc0cb1cdSDale Ghent /* Since this function eventually calls
617dc0cb1cdSDale Ghent * ixgbe_init_ops_540 by design, we are setting
618dc0cb1cdSDale Ghent * the pointers to NULL explicitly here to overwrite
619dc0cb1cdSDale Ghent * the values being set in the x540 function.
620dc0cb1cdSDale Ghent */
621dc0cb1cdSDale Ghent
622*48ed61a7SRobert Mustacchi /* Bypass not supported in x550EM */
623*48ed61a7SRobert Mustacchi mac->ops.bypass_rw = NULL;
624*48ed61a7SRobert Mustacchi mac->ops.bypass_valid_rd = NULL;
625*48ed61a7SRobert Mustacchi mac->ops.bypass_set = NULL;
626*48ed61a7SRobert Mustacchi mac->ops.bypass_rd_eep = NULL;
627*48ed61a7SRobert Mustacchi
628dc0cb1cdSDale Ghent /* FCOE not supported in x550EM */
629dc0cb1cdSDale Ghent mac->ops.get_san_mac_addr = NULL;
630dc0cb1cdSDale Ghent mac->ops.set_san_mac_addr = NULL;
631dc0cb1cdSDale Ghent mac->ops.get_wwn_prefix = NULL;
632dc0cb1cdSDale Ghent mac->ops.get_fcoe_boot_status = NULL;
633dc0cb1cdSDale Ghent
634dc0cb1cdSDale Ghent /* IPsec not supported in x550EM */
635dc0cb1cdSDale Ghent mac->ops.disable_sec_rx_path = NULL;
636dc0cb1cdSDale Ghent mac->ops.enable_sec_rx_path = NULL;
637dc0cb1cdSDale Ghent
638dc0cb1cdSDale Ghent /* AUTOC register is not present in x550EM. */
639dc0cb1cdSDale Ghent mac->ops.prot_autoc_read = NULL;
640dc0cb1cdSDale Ghent mac->ops.prot_autoc_write = NULL;
641dc0cb1cdSDale Ghent
642dc0cb1cdSDale Ghent /* X550EM bus type is internal*/
643dc0cb1cdSDale Ghent hw->bus.type = ixgbe_bus_type_internal;
644dc0cb1cdSDale Ghent mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
645dc0cb1cdSDale Ghent
646dc0cb1cdSDale Ghent
647dc0cb1cdSDale Ghent mac->ops.get_media_type = ixgbe_get_media_type_X550em;
648dc0cb1cdSDale Ghent mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
649dc0cb1cdSDale Ghent mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
650dc0cb1cdSDale Ghent mac->ops.reset_hw = ixgbe_reset_hw_X550em;
651dc0cb1cdSDale Ghent mac->ops.get_supported_physical_layer =
652dc0cb1cdSDale Ghent ixgbe_get_supported_physical_layer_X550em;
653dc0cb1cdSDale Ghent
654dc0cb1cdSDale Ghent if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
655dc0cb1cdSDale Ghent mac->ops.setup_fc = ixgbe_setup_fc_generic;
656dc0cb1cdSDale Ghent else
657dc0cb1cdSDale Ghent mac->ops.setup_fc = ixgbe_setup_fc_X550em;
658dc0cb1cdSDale Ghent
659dc0cb1cdSDale Ghent /* PHY */
660dc0cb1cdSDale Ghent phy->ops.init = ixgbe_init_phy_ops_X550em;
661*48ed61a7SRobert Mustacchi switch (hw->device_id) {
662*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_1G_T:
663*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_A_1G_T_L:
664*48ed61a7SRobert Mustacchi mac->ops.setup_fc = NULL;
665*48ed61a7SRobert Mustacchi phy->ops.identify = ixgbe_identify_phy_fw;
666*48ed61a7SRobert Mustacchi phy->ops.set_phy_power = NULL;
667*48ed61a7SRobert Mustacchi phy->ops.get_firmware_version = NULL;
668*48ed61a7SRobert Mustacchi break;
669*48ed61a7SRobert Mustacchi case IXGBE_DEV_ID_X550EM_X_1G_T:
670*48ed61a7SRobert Mustacchi mac->ops.setup_fc = NULL;
671*48ed61a7SRobert Mustacchi phy->ops.identify = ixgbe_identify_phy_x550em;
672*48ed61a7SRobert Mustacchi phy->ops.set_phy_power = NULL;
673*48ed61a7SRobert Mustacchi break;
674*48ed61a7SRobert Mustacchi default:
675*48ed61a7SRobert Mustacchi phy->ops.identify = ixgbe_identify_phy_x550em;
676*48ed61a7SRobert Mustacchi }
677*48ed61a7SRobert Mustacchi
678dc0cb1cdSDale Ghent if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
679dc0cb1cdSDale Ghent phy->ops.set_phy_power = NULL;
680dc0cb1cdSDale Ghent
681dc0cb1cdSDale Ghent
682dc0cb1cdSDale Ghent /* EEPROM */
683dc0cb1cdSDale Ghent eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
684dc0cb1cdSDale Ghent eeprom->ops.read = ixgbe_read_ee_hostif_X550;
685dc0cb1cdSDale Ghent eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
686dc0cb1cdSDale Ghent eeprom->ops.write = ixgbe_write_ee_hostif_X550;
687dc0cb1cdSDale Ghent eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
688dc0cb1cdSDale Ghent eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
689dc0cb1cdSDale Ghent eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
690dc0cb1cdSDale Ghent eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
691dc0cb1cdSDale Ghent
692dc0cb1cdSDale Ghent return ret_val;
693dc0cb1cdSDale Ghent }
694dc0cb1cdSDale Ghent
695*48ed61a7SRobert Mustacchi /**
696*48ed61a7SRobert Mustacchi * ixgbe_setup_fw_link - Setup firmware-controlled PHYs
697*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
698*48ed61a7SRobert Mustacchi */
ixgbe_setup_fw_link(struct ixgbe_hw * hw)699*48ed61a7SRobert Mustacchi static s32 ixgbe_setup_fw_link(struct ixgbe_hw *hw)
700*48ed61a7SRobert Mustacchi {
701*48ed61a7SRobert Mustacchi u32 setup[FW_PHY_ACT_DATA_COUNT] = { 0 };
702*48ed61a7SRobert Mustacchi s32 rc;
703*48ed61a7SRobert Mustacchi u16 i;
704*48ed61a7SRobert Mustacchi
705*48ed61a7SRobert Mustacchi if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw))
706*48ed61a7SRobert Mustacchi return 0;
707*48ed61a7SRobert Mustacchi
708*48ed61a7SRobert Mustacchi if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
709*48ed61a7SRobert Mustacchi ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
710*48ed61a7SRobert Mustacchi "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
711*48ed61a7SRobert Mustacchi return IXGBE_ERR_INVALID_LINK_SETTINGS;
712*48ed61a7SRobert Mustacchi }
713*48ed61a7SRobert Mustacchi
714*48ed61a7SRobert Mustacchi switch (hw->fc.requested_mode) {
715*48ed61a7SRobert Mustacchi case ixgbe_fc_full:
716*48ed61a7SRobert Mustacchi setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RXTX <<
717*48ed61a7SRobert Mustacchi FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
718*48ed61a7SRobert Mustacchi break;
719*48ed61a7SRobert Mustacchi case ixgbe_fc_rx_pause:
720*48ed61a7SRobert Mustacchi setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_RX <<
721*48ed61a7SRobert Mustacchi FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
722*48ed61a7SRobert Mustacchi break;
723*48ed61a7SRobert Mustacchi case ixgbe_fc_tx_pause:
724*48ed61a7SRobert Mustacchi setup[0] |= FW_PHY_ACT_SETUP_LINK_PAUSE_TX <<
725*48ed61a7SRobert Mustacchi FW_PHY_ACT_SETUP_LINK_PAUSE_SHIFT;
726*48ed61a7SRobert Mustacchi break;
727*48ed61a7SRobert Mustacchi default:
728*48ed61a7SRobert Mustacchi break;
729*48ed61a7SRobert Mustacchi }
730*48ed61a7SRobert Mustacchi
731*48ed61a7SRobert Mustacchi for (i = 0; i < sizeof(ixgbe_fw_map) / sizeof(ixgbe_fw_map[0]); ++i) {
732*48ed61a7SRobert Mustacchi if (hw->phy.autoneg_advertised & ixgbe_fw_map[i].phy_speed)
733*48ed61a7SRobert Mustacchi setup[0] |= ixgbe_fw_map[i].fw_speed;
734*48ed61a7SRobert Mustacchi }
735*48ed61a7SRobert Mustacchi setup[0] |= FW_PHY_ACT_SETUP_LINK_HP | FW_PHY_ACT_SETUP_LINK_AN;
736*48ed61a7SRobert Mustacchi
737*48ed61a7SRobert Mustacchi if (hw->phy.eee_speeds_advertised)
738*48ed61a7SRobert Mustacchi setup[0] |= FW_PHY_ACT_SETUP_LINK_EEE;
739*48ed61a7SRobert Mustacchi
740*48ed61a7SRobert Mustacchi rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup);
741*48ed61a7SRobert Mustacchi if (rc)
742*48ed61a7SRobert Mustacchi return rc;
743*48ed61a7SRobert Mustacchi if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN)
744*48ed61a7SRobert Mustacchi return IXGBE_ERR_OVERTEMP;
745*48ed61a7SRobert Mustacchi return IXGBE_SUCCESS;
746*48ed61a7SRobert Mustacchi }
747*48ed61a7SRobert Mustacchi
748*48ed61a7SRobert Mustacchi /**
749*48ed61a7SRobert Mustacchi * ixgbe_fc_autoneg_fw _ Set up flow control for FW-controlled PHYs
750*48ed61a7SRobert Mustacchi * @hw: pointer to hardware structure
751*48ed61a7SRobert Mustacchi *
752*48ed61a7SRobert Mustacchi * Called at init time to set up flow control.
753