blob: 65832fa30426756cc8e666525fb6c0099770d2ce [file] [log] [blame]
Don Skidmore6a14ee02014-12-05 03:59:50 +00001/*******************************************************************************
2 *
3 * Intel 10 Gigabit PCI Express Linux driver
Mark Rustad37689012016-01-07 10:13:03 -08004 * Copyright(c) 1999 - 2016 Intel Corporation.
Don Skidmore6a14ee02014-12-05 03:59:50 +00005 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Contact Information:
19 * Linux NICS <linux.nics@intel.com>
20 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
21 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
22 *
23 ******************************************************************************/
24#include "ixgbe_x540.h"
25#include "ixgbe_type.h"
26#include "ixgbe_common.h"
27#include "ixgbe_phy.h"
28
Mark Rustadd91e3a72015-09-28 14:37:47 -070029static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed);
Mark Rustadafdc71e2016-01-25 16:32:10 -080030static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *);
Mark Rustadd91e3a72015-09-28 14:37:47 -070031
Don Skidmoreb5529ef2015-06-10 20:42:30 -040032static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw)
33{
34 struct ixgbe_mac_info *mac = &hw->mac;
35 struct ixgbe_phy_info *phy = &hw->phy;
36
37 /* Start with X540 invariants, since so simular */
38 ixgbe_get_invariants_X540(hw);
39
40 if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
41 phy->ops.set_phy_power = NULL;
42
43 return 0;
44}
45
Don Skidmoreab5fe0c2015-06-09 16:18:56 -070046/** ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
47 * @hw: pointer to hardware structure
48 **/
49static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
50{
51 u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
52
53 if (hw->bus.lan_id) {
54 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
55 esdp |= IXGBE_ESDP_SDP1_DIR;
56 }
57 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
58 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
59 IXGBE_WRITE_FLUSH(hw);
60}
61
Mark Rustad542b6ee2015-08-08 16:18:38 -070062/**
63 * ixgbe_read_cs4227 - Read CS4227 register
64 * @hw: pointer to hardware structure
65 * @reg: register number to write
66 * @value: pointer to receive value read
67 *
68 * Returns status code
69 */
70static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
71{
72 return hw->phy.ops.read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
73 value);
74}
75
76/**
77 * ixgbe_write_cs4227 - Write CS4227 register
78 * @hw: pointer to hardware structure
79 * @reg: register number to write
80 * @value: value to write to register
81 *
82 * Returns status code
83 */
84static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
85{
86 return hw->phy.ops.write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
87 value);
88}
89
90/**
Mark Rustad542b6ee2015-08-08 16:18:38 -070091 * ixgbe_read_pe - Read register from port expander
92 * @hw: pointer to hardware structure
93 * @reg: register number to read
94 * @value: pointer to receive read value
95 *
96 * Returns status code
97 */
98static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
99{
100 s32 status;
101
102 status = ixgbe_read_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE, value);
103 if (status)
104 hw_err(hw, "port expander access failed with %d\n", status);
105 return status;
106}
107
108/**
109 * ixgbe_write_pe - Write register to port expander
110 * @hw: pointer to hardware structure
111 * @reg: register number to write
112 * @value: value to write
113 *
114 * Returns status code
115 */
116static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
117{
118 s32 status;
119
120 status = ixgbe_write_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE,
121 value);
122 if (status)
123 hw_err(hw, "port expander access failed with %d\n", status);
124 return status;
125}
126
127/**
128 * ixgbe_reset_cs4227 - Reset CS4227 using port expander
129 * @hw: pointer to hardware structure
130 *
Mark Rustad8bf7a7b2015-08-26 14:10:22 -0700131 * This function assumes that the caller has acquired the proper semaphore.
Mark Rustad542b6ee2015-08-08 16:18:38 -0700132 * Returns error code
133 */
134static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
135{
136 s32 status;
137 u32 retry;
138 u16 value;
139 u8 reg;
140
141 /* Trigger hard reset. */
142 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
143 if (status)
144 return status;
145 reg |= IXGBE_PE_BIT1;
146 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
147 if (status)
148 return status;
149
150 status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
151 if (status)
152 return status;
153 reg &= ~IXGBE_PE_BIT1;
154 status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
155 if (status)
156 return status;
157
158 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
159 if (status)
160 return status;
161 reg &= ~IXGBE_PE_BIT1;
162 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
163 if (status)
164 return status;
165
166 usleep_range(IXGBE_CS4227_RESET_HOLD, IXGBE_CS4227_RESET_HOLD + 100);
167
168 status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
169 if (status)
170 return status;
171 reg |= IXGBE_PE_BIT1;
172 status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
173 if (status)
174 return status;
175
176 /* Wait for the reset to complete. */
177 msleep(IXGBE_CS4227_RESET_DELAY);
178 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
179 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
180 &value);
181 if (!status && value == IXGBE_CS4227_EEPROM_LOAD_OK)
182 break;
183 msleep(IXGBE_CS4227_CHECK_DELAY);
184 }
185 if (retry == IXGBE_CS4227_RETRIES) {
186 hw_err(hw, "CS4227 reset did not complete\n");
187 return IXGBE_ERR_PHY;
188 }
189
190 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
191 if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
192 hw_err(hw, "CS4227 EEPROM did not load successfully\n");
193 return IXGBE_ERR_PHY;
194 }
195
196 return 0;
197}
198
199/**
200 * ixgbe_check_cs4227 - Check CS4227 and reset as needed
201 * @hw: pointer to hardware structure
202 */
203static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
204{
205 u32 swfw_mask = hw->phy.phy_semaphore_mask;
206 s32 status;
207 u16 value;
208 u8 retry;
209
210 for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
211 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
212 if (status) {
213 hw_err(hw, "semaphore failed with %d\n", status);
214 msleep(IXGBE_CS4227_CHECK_DELAY);
215 continue;
216 }
217
218 /* Get status of reset flow. */
219 status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
220 if (!status && value == IXGBE_CS4227_RESET_COMPLETE)
221 goto out;
222
223 if (status || value != IXGBE_CS4227_RESET_PENDING)
224 break;
225
226 /* Reset is pending. Wait and check again. */
227 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
228 msleep(IXGBE_CS4227_CHECK_DELAY);
229 }
Mark Rustad8bf7a7b2015-08-26 14:10:22 -0700230 /* If still pending, assume other instance failed. */
231 if (retry == IXGBE_CS4227_RETRIES) {
232 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
233 if (status) {
234 hw_err(hw, "semaphore failed with %d\n", status);
235 return;
236 }
237 }
Mark Rustad542b6ee2015-08-08 16:18:38 -0700238
239 /* Reset the CS4227. */
240 status = ixgbe_reset_cs4227(hw);
241 if (status) {
242 hw_err(hw, "CS4227 reset failed: %d", status);
243 goto out;
244 }
245
246 /* Reset takes so long, temporarily release semaphore in case the
247 * other driver instance is waiting for the reset indication.
248 */
249 ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
250 IXGBE_CS4227_RESET_PENDING);
251 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
252 usleep_range(10000, 12000);
253 status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
254 if (status) {
255 hw_err(hw, "semaphore failed with %d", status);
256 return;
257 }
258
Mark Rustad542b6ee2015-08-08 16:18:38 -0700259 /* Record completion for next time. */
260 status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
261 IXGBE_CS4227_RESET_COMPLETE);
262
263out:
264 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
265 msleep(hw->eeprom.semaphore_delay);
266}
267
Don Skidmore6a14ee02014-12-05 03:59:50 +0000268/** ixgbe_identify_phy_x550em - Get PHY type based on device id
269 * @hw: pointer to hardware structure
270 *
271 * Returns error code
272 */
273static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
274{
Don Skidmore6a14ee02014-12-05 03:59:50 +0000275 switch (hw->device_id) {
276 case IXGBE_DEV_ID_X550EM_X_SFP:
277 /* set up for CS4227 usage */
278 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
Don Skidmoreab5fe0c2015-06-09 16:18:56 -0700279 ixgbe_setup_mux_ctl(hw);
Mark Rustad542b6ee2015-08-08 16:18:38 -0700280 ixgbe_check_cs4227(hw);
Don Skidmore6a14ee02014-12-05 03:59:50 +0000281 return ixgbe_identify_module_generic(hw);
282 case IXGBE_DEV_ID_X550EM_X_KX4:
283 hw->phy.type = ixgbe_phy_x550em_kx4;
284 break;
285 case IXGBE_DEV_ID_X550EM_X_KR:
286 hw->phy.type = ixgbe_phy_x550em_kr;
287 break;
288 case IXGBE_DEV_ID_X550EM_X_1G_T:
289 case IXGBE_DEV_ID_X550EM_X_10G_T:
290 return ixgbe_identify_phy_generic(hw);
291 default:
292 break;
293 }
294 return 0;
295}
296
297static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
298 u32 device_type, u16 *phy_data)
299{
300 return IXGBE_NOT_IMPLEMENTED;
301}
302
303static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
304 u32 device_type, u16 phy_data)
305{
306 return IXGBE_NOT_IMPLEMENTED;
307}
308
309/** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
310 * @hw: pointer to hardware structure
311 *
312 * Initializes the EEPROM parameters ixgbe_eeprom_info within the
313 * ixgbe_hw struct in order to set up EEPROM access.
314 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000315static s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000316{
317 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
318 u32 eec;
319 u16 eeprom_size;
320
321 if (eeprom->type == ixgbe_eeprom_uninitialized) {
322 eeprom->semaphore_delay = 10;
323 eeprom->type = ixgbe_flash;
324
Don Skidmore9a900ec2015-06-09 17:15:01 -0700325 eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw));
Don Skidmore6a14ee02014-12-05 03:59:50 +0000326 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
327 IXGBE_EEC_SIZE_SHIFT);
328 eeprom->word_size = 1 << (eeprom_size +
329 IXGBE_EEPROM_WORD_SIZE_SHIFT);
330
331 hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
332 eeprom->type, eeprom->word_size);
333 }
334
335 return 0;
336}
337
Mark Rustadae14a1d2015-04-10 10:36:26 -0700338/**
339 * ixgbe_iosf_wait - Wait for IOSF command completion
340 * @hw: pointer to hardware structure
341 * @ctrl: pointer to location to receive final IOSF control value
342 *
343 * Return: failing status on timeout
344 *
345 * Note: ctrl can be NULL if the IOSF control register value is not needed
346 */
347static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
348{
349 u32 i, command;
350
351 /* Check every 10 usec to see if the address cycle completed.
352 * The SB IOSF BUSY bit will clear when the operation is
353 * complete.
354 */
355 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
356 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
357 if (!(command & IXGBE_SB_IOSF_CTRL_BUSY))
358 break;
Mark Rustadd90b5b02016-01-29 14:44:29 -0800359 udelay(10);
Mark Rustadae14a1d2015-04-10 10:36:26 -0700360 }
361 if (ctrl)
362 *ctrl = command;
363 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
364 hw_dbg(hw, "IOSF wait timed out\n");
365 return IXGBE_ERR_PHY;
366 }
367
368 return 0;
369}
370
Don Skidmore6a14ee02014-12-05 03:59:50 +0000371/** ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the
372 * IOSF device
373 * @hw: pointer to hardware structure
374 * @reg_addr: 32 bit PHY register to write
375 * @device_type: 3 bit device type
376 * @phy_data: Pointer to read data from the register
377 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000378static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
379 u32 device_type, u32 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000380{
Mark Rustadae14a1d2015-04-10 10:36:26 -0700381 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
382 u32 command, error;
383 s32 ret;
384
385 ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
386 if (ret)
387 return ret;
388
389 ret = ixgbe_iosf_wait(hw, NULL);
390 if (ret)
391 goto out;
Don Skidmore6a14ee02014-12-05 03:59:50 +0000392
393 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
394 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
395
396 /* Write IOSF control register */
397 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
398
Mark Rustadae14a1d2015-04-10 10:36:26 -0700399 ret = ixgbe_iosf_wait(hw, &command);
Don Skidmore6a14ee02014-12-05 03:59:50 +0000400
401 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
402 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
403 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
404 hw_dbg(hw, "Failed to read, error %x\n", error);
405 return IXGBE_ERR_PHY;
406 }
407
Mark Rustadae14a1d2015-04-10 10:36:26 -0700408 if (!ret)
409 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
Don Skidmore6a14ee02014-12-05 03:59:50 +0000410
Mark Rustadae14a1d2015-04-10 10:36:26 -0700411out:
412 hw->mac.ops.release_swfw_sync(hw, gssr);
413 return ret;
Don Skidmore6a14ee02014-12-05 03:59:50 +0000414}
415
416/** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface
417 * command assuming that the semaphore is already obtained.
418 * @hw: pointer to hardware structure
419 * @offset: offset of word in the EEPROM to read
420 * @data: word read from the EEPROM
421 *
422 * Reads a 16 bit word from the EEPROM using the hostif.
423 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000424static s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
425 u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000426{
427 s32 status;
428 struct ixgbe_hic_read_shadow_ram buffer;
429
430 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
431 buffer.hdr.req.buf_lenh = 0;
432 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
433 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
434
435 /* convert offset from words to bytes */
436 buffer.address = cpu_to_be32(offset * 2);
437 /* one word */
438 buffer.length = cpu_to_be16(sizeof(u16));
439
Mark Rustad5cffde32016-03-14 11:05:57 -0700440 status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer),
Don Skidmore6a14ee02014-12-05 03:59:50 +0000441 IXGBE_HI_COMMAND_TIMEOUT, false);
442 if (status)
443 return status;
444
445 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
446 FW_NVM_DATA_OFFSET);
447
448 return 0;
449}
450
451/** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
452 * @hw: pointer to hardware structure
453 * @offset: offset of word in the EEPROM to read
454 * @words: number of words
455 * @data: word(s) read from the EEPROM
456 *
457 * Reads a 16 bit word(s) from the EEPROM using the hostif.
458 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000459static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
460 u16 offset, u16 words, u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000461{
462 struct ixgbe_hic_read_shadow_ram buffer;
463 u32 current_word = 0;
464 u16 words_to_read;
465 s32 status;
466 u32 i;
467
468 /* Take semaphore for the entire operation. */
469 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
470 if (status) {
471 hw_dbg(hw, "EEPROM read buffer - semaphore failed\n");
472 return status;
473 }
474
475 while (words) {
476 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
477 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
478 else
479 words_to_read = words;
480
481 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
482 buffer.hdr.req.buf_lenh = 0;
483 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
484 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
485
486 /* convert offset from words to bytes */
487 buffer.address = cpu_to_be32((offset + current_word) * 2);
488 buffer.length = cpu_to_be16(words_to_read * 2);
489
Mark Rustad5cffde32016-03-14 11:05:57 -0700490 status = ixgbe_host_interface_command(hw, &buffer,
Don Skidmore6a14ee02014-12-05 03:59:50 +0000491 sizeof(buffer),
492 IXGBE_HI_COMMAND_TIMEOUT,
493 false);
494 if (status) {
495 hw_dbg(hw, "Host interface command failed\n");
496 goto out;
497 }
498
499 for (i = 0; i < words_to_read; i++) {
500 u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
501 2 * i;
502 u32 value = IXGBE_READ_REG(hw, reg);
503
504 data[current_word] = (u16)(value & 0xffff);
505 current_word++;
506 i++;
507 if (i < words_to_read) {
508 value >>= 16;
509 data[current_word] = (u16)(value & 0xffff);
510 current_word++;
511 }
512 }
513 words -= words_to_read;
514 }
515
516out:
517 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
518 return status;
519}
520
521/** ixgbe_checksum_ptr_x550 - Checksum one pointer region
522 * @hw: pointer to hardware structure
523 * @ptr: pointer offset in eeprom
524 * @size: size of section pointed by ptr, if 0 first word will be used as size
525 * @csum: address of checksum to update
526 *
527 * Returns error status for any failure
528 **/
529static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
530 u16 size, u16 *csum, u16 *buffer,
531 u32 buffer_size)
532{
533 u16 buf[256];
534 s32 status;
535 u16 length, bufsz, i, start;
536 u16 *local_buffer;
537
538 bufsz = sizeof(buf) / sizeof(buf[0]);
539
540 /* Read a chunk at the pointer location */
541 if (!buffer) {
542 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
543 if (status) {
544 hw_dbg(hw, "Failed to read EEPROM image\n");
545 return status;
546 }
547 local_buffer = buf;
548 } else {
549 if (buffer_size < ptr)
550 return IXGBE_ERR_PARAM;
551 local_buffer = &buffer[ptr];
552 }
553
554 if (size) {
555 start = 0;
556 length = size;
557 } else {
558 start = 1;
559 length = local_buffer[0];
560
561 /* Skip pointer section if length is invalid. */
562 if (length == 0xFFFF || length == 0 ||
563 (ptr + length) >= hw->eeprom.word_size)
564 return 0;
565 }
566
567 if (buffer && ((u32)start + (u32)length > buffer_size))
568 return IXGBE_ERR_PARAM;
569
570 for (i = start; length; i++, length--) {
571 if (i == bufsz && !buffer) {
572 ptr += bufsz;
573 i = 0;
574 if (length < bufsz)
575 bufsz = length;
576
577 /* Read a chunk at the pointer location */
578 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
579 bufsz, buf);
580 if (status) {
581 hw_dbg(hw, "Failed to read EEPROM image\n");
582 return status;
583 }
584 }
585 *csum += local_buffer[i];
586 }
587 return 0;
588}
589
590/** ixgbe_calc_checksum_X550 - Calculates and returns the checksum
591 * @hw: pointer to hardware structure
592 * @buffer: pointer to buffer containing calculated checksum
593 * @buffer_size: size of buffer
594 *
595 * Returns a negative error code on error, or the 16-bit checksum
596 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000597static s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer,
598 u32 buffer_size)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000599{
600 u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
601 u16 *local_buffer;
602 s32 status;
603 u16 checksum = 0;
604 u16 pointer, i, size;
605
606 hw->eeprom.ops.init_params(hw);
607
608 if (!buffer) {
609 /* Read pointer area */
610 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
611 IXGBE_EEPROM_LAST_WORD + 1,
612 eeprom_ptrs);
613 if (status) {
614 hw_dbg(hw, "Failed to read EEPROM image\n");
615 return status;
616 }
617 local_buffer = eeprom_ptrs;
618 } else {
619 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
620 return IXGBE_ERR_PARAM;
621 local_buffer = buffer;
622 }
623
624 /* For X550 hardware include 0x0-0x41 in the checksum, skip the
625 * checksum word itself
626 */
627 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
628 if (i != IXGBE_EEPROM_CHECKSUM)
629 checksum += local_buffer[i];
630
631 /* Include all data from pointers 0x3, 0x6-0xE. This excludes the
632 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
633 */
634 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
635 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
636 continue;
637
638 pointer = local_buffer[i];
639
640 /* Skip pointer section if the pointer is invalid. */
641 if (pointer == 0xFFFF || pointer == 0 ||
642 pointer >= hw->eeprom.word_size)
643 continue;
644
645 switch (i) {
646 case IXGBE_PCIE_GENERAL_PTR:
647 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
648 break;
649 case IXGBE_PCIE_CONFIG0_PTR:
650 case IXGBE_PCIE_CONFIG1_PTR:
651 size = IXGBE_PCIE_CONFIG_SIZE;
652 break;
653 default:
654 size = 0;
655 break;
656 }
657
658 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
659 buffer, buffer_size);
660 if (status)
661 return status;
662 }
663
664 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
665
666 return (s32)checksum;
667}
668
669/** ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
670 * @hw: pointer to hardware structure
671 *
672 * Returns a negative error code on error, or the 16-bit checksum
673 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000674static s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000675{
676 return ixgbe_calc_checksum_X550(hw, NULL, 0);
677}
678
679/** ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
680 * @hw: pointer to hardware structure
681 * @offset: offset of word in the EEPROM to read
682 * @data: word read from the EEPROM
683 *
684 * Reads a 16 bit word from the EEPROM using the hostif.
685 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000686static s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000687{
688 s32 status = 0;
689
690 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
691 status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
692 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
693 } else {
694 status = IXGBE_ERR_SWFW_SYNC;
695 }
696
697 return status;
698}
699
700/** ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
701 * @hw: pointer to hardware structure
702 * @checksum_val: calculated checksum
703 *
704 * Performs checksum calculation and validates the EEPROM checksum. If the
705 * caller does not need checksum_val, the value can be NULL.
706 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000707static s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
708 u16 *checksum_val)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000709{
710 s32 status;
711 u16 checksum;
712 u16 read_checksum = 0;
713
714 /* Read the first word from the EEPROM. If this times out or fails, do
715 * not continue or we could be in for a very long wait while every
716 * EEPROM read fails
717 */
718 status = hw->eeprom.ops.read(hw, 0, &checksum);
719 if (status) {
720 hw_dbg(hw, "EEPROM read failed\n");
721 return status;
722 }
723
724 status = hw->eeprom.ops.calc_checksum(hw);
725 if (status < 0)
726 return status;
727
728 checksum = (u16)(status & 0xffff);
729
730 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
731 &read_checksum);
732 if (status)
733 return status;
734
735 /* Verify read checksum from EEPROM is the same as
736 * calculated checksum
737 */
738 if (read_checksum != checksum) {
739 status = IXGBE_ERR_EEPROM_CHECKSUM;
740 hw_dbg(hw, "Invalid EEPROM checksum");
741 }
742
743 /* If the user cares, return the calculated checksum */
744 if (checksum_val)
745 *checksum_val = checksum;
746
747 return status;
748}
749
750/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
751 * @hw: pointer to hardware structure
752 * @offset: offset of word in the EEPROM to write
753 * @data: word write to the EEPROM
754 *
755 * Write a 16 bit word to the EEPROM using the hostif.
756 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000757static s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
758 u16 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000759{
760 s32 status;
761 struct ixgbe_hic_write_shadow_ram buffer;
762
763 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
764 buffer.hdr.req.buf_lenh = 0;
765 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
766 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
767
768 /* one word */
769 buffer.length = cpu_to_be16(sizeof(u16));
770 buffer.data = data;
771 buffer.address = cpu_to_be32(offset * 2);
772
Mark Rustad5cffde32016-03-14 11:05:57 -0700773 status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer),
Don Skidmore6a14ee02014-12-05 03:59:50 +0000774 IXGBE_HI_COMMAND_TIMEOUT, false);
775 return status;
776}
777
778/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
779 * @hw: pointer to hardware structure
780 * @offset: offset of word in the EEPROM to write
781 * @data: word write to the EEPROM
782 *
783 * Write a 16 bit word to the EEPROM using the hostif.
784 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000785static s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000786{
787 s32 status = 0;
788
789 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
790 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
791 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
792 } else {
793 hw_dbg(hw, "write ee hostif failed to get semaphore");
794 status = IXGBE_ERR_SWFW_SYNC;
795 }
796
797 return status;
798}
799
800/** ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
801 * @hw: pointer to hardware structure
802 *
803 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
804 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000805static s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000806{
807 s32 status = 0;
808 union ixgbe_hic_hdr2 buffer;
809
810 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
811 buffer.req.buf_lenh = 0;
812 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
813 buffer.req.checksum = FW_DEFAULT_CHECKSUM;
814
Mark Rustad5cffde32016-03-14 11:05:57 -0700815 status = ixgbe_host_interface_command(hw, &buffer, sizeof(buffer),
Don Skidmore6a14ee02014-12-05 03:59:50 +0000816 IXGBE_HI_COMMAND_TIMEOUT, false);
817 return status;
818}
819
Don Skidmore454c65d2015-06-17 20:59:59 -0400820/**
821 * ixgbe_get_bus_info_X550em - Set PCI bus info
822 * @hw: pointer to hardware structure
823 *
824 * Sets bus link width and speed to unknown because X550em is
825 * not a PCI device.
826 **/
827static s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
828{
Don Skidmoref9328bc2015-06-18 13:24:06 -0400829 hw->bus.type = ixgbe_bus_type_internal;
Don Skidmore454c65d2015-06-17 20:59:59 -0400830 hw->bus.width = ixgbe_bus_width_unknown;
831 hw->bus.speed = ixgbe_bus_speed_unknown;
832
833 hw->mac.ops.set_lan_id(hw);
834
835 return 0;
836}
837
Don Skidmore1f9ac572015-03-13 13:54:30 -0700838/** ixgbe_disable_rx_x550 - Disable RX unit
839 *
840 * Enables the Rx DMA unit for x550
841 **/
842static void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
843{
844 u32 rxctrl, pfdtxgswc;
845 s32 status;
846 struct ixgbe_hic_disable_rxen fw_cmd;
847
848 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
849 if (rxctrl & IXGBE_RXCTRL_RXEN) {
850 pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
851 if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
852 pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
853 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
854 hw->mac.set_lben = true;
855 } else {
856 hw->mac.set_lben = false;
857 }
858
859 fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
860 fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
861 fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
Mark Rustad3775b812016-03-14 11:05:46 -0700862 fw_cmd.port_number = hw->bus.lan_id;
Don Skidmore1f9ac572015-03-13 13:54:30 -0700863
Mark Rustad5cffde32016-03-14 11:05:57 -0700864 status = ixgbe_host_interface_command(hw, &fw_cmd,
Don Skidmore1f9ac572015-03-13 13:54:30 -0700865 sizeof(struct ixgbe_hic_disable_rxen),
866 IXGBE_HI_COMMAND_TIMEOUT, true);
867
868 /* If we fail - disable RX using register write */
869 if (status) {
870 rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
871 if (rxctrl & IXGBE_RXCTRL_RXEN) {
872 rxctrl &= ~IXGBE_RXCTRL_RXEN;
873 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
874 }
875 }
876 }
877}
878
Don Skidmore6a14ee02014-12-05 03:59:50 +0000879/** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
880 * @hw: pointer to hardware structure
881 *
882 * After writing EEPROM to shadow RAM using EEWR register, software calculates
883 * checksum and updates the EEPROM and instructs the hardware to update
884 * the flash.
885 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000886static s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000887{
888 s32 status;
889 u16 checksum = 0;
890
891 /* Read the first word from the EEPROM. If this times out or fails, do
892 * not continue or we could be in for a very long wait while every
893 * EEPROM read fails
894 */
895 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
896 if (status) {
897 hw_dbg(hw, "EEPROM read failed\n");
898 return status;
899 }
900
901 status = ixgbe_calc_eeprom_checksum_X550(hw);
902 if (status < 0)
903 return status;
904
905 checksum = (u16)(status & 0xffff);
906
907 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
908 checksum);
909 if (status)
910 return status;
911
912 status = ixgbe_update_flash_X550(hw);
913
914 return status;
915}
916
917/** ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
918 * @hw: pointer to hardware structure
919 * @offset: offset of word in the EEPROM to write
920 * @words: number of words
921 * @data: word(s) write to the EEPROM
922 *
923 *
924 * Write a 16 bit word(s) to the EEPROM using the hostif.
925 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000926static s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
927 u16 offset, u16 words,
928 u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000929{
930 s32 status = 0;
931 u32 i = 0;
932
933 /* Take semaphore for the entire operation. */
934 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
935 if (status) {
936 hw_dbg(hw, "EEPROM write buffer - semaphore failed\n");
937 return status;
938 }
939
940 for (i = 0; i < words; i++) {
941 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
942 data[i]);
943 if (status) {
944 hw_dbg(hw, "Eeprom buffered write failed\n");
945 break;
946 }
947 }
948
949 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
950
951 return status;
952}
953
Don Skidmore6a14ee02014-12-05 03:59:50 +0000954/** ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the
955 * IOSF device
956 *
957 * @hw: pointer to hardware structure
958 * @reg_addr: 32 bit PHY register to write
959 * @device_type: 3 bit device type
960 * @data: Data to write to the register
961 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000962static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
963 u32 device_type, u32 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000964{
Mark Rustadae14a1d2015-04-10 10:36:26 -0700965 u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
966 u32 command, error;
967 s32 ret;
968
969 ret = hw->mac.ops.acquire_swfw_sync(hw, gssr);
970 if (ret)
971 return ret;
972
973 ret = ixgbe_iosf_wait(hw, NULL);
974 if (ret)
975 goto out;
Don Skidmore6a14ee02014-12-05 03:59:50 +0000976
977 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
978 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
979
980 /* Write IOSF control register */
981 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
982
983 /* Write IOSF data register */
984 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
985
Mark Rustadae14a1d2015-04-10 10:36:26 -0700986 ret = ixgbe_iosf_wait(hw, &command);
Don Skidmore6a14ee02014-12-05 03:59:50 +0000987
988 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
989 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
990 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
991 hw_dbg(hw, "Failed to write, error %x\n", error);
992 return IXGBE_ERR_PHY;
993 }
994
Mark Rustadae14a1d2015-04-10 10:36:26 -0700995out:
996 hw->mac.ops.release_swfw_sync(hw, gssr);
997 return ret;
Don Skidmore6a14ee02014-12-05 03:59:50 +0000998}
999
1000/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
1001 * @hw: pointer to hardware structure
1002 * @speed: the link speed to force
1003 *
1004 * Configures the integrated KR PHY to use iXFI mode. Used to connect an
1005 * internal and external PHY at a specific speed, without autonegotiation.
1006 **/
1007static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
1008{
1009 s32 status;
1010 u32 reg_val;
1011
1012 /* Disable AN and force speed to 10G Serial. */
1013 status = ixgbe_read_iosf_sb_reg_x550(hw,
1014 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1015 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1016 if (status)
1017 return status;
1018
1019 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1020 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
1021
1022 /* Select forced link speed for internal PHY. */
1023 switch (*speed) {
1024 case IXGBE_LINK_SPEED_10GB_FULL:
1025 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
1026 break;
1027 case IXGBE_LINK_SPEED_1GB_FULL:
1028 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
1029 break;
1030 default:
1031 /* Other link speeds are not supported by internal KR PHY. */
1032 return IXGBE_ERR_LINK_SETUP;
1033 }
1034
1035 status = ixgbe_write_iosf_sb_reg_x550(hw,
Don Skidmorebec4e682015-06-09 17:55:59 -07001036 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
Don Skidmore6a14ee02014-12-05 03:59:50 +00001037 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1038 if (status)
1039 return status;
1040
1041 /* Disable training protocol FSM. */
1042 status = ixgbe_read_iosf_sb_reg_x550(hw,
1043 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1044 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1045 if (status)
1046 return status;
1047
1048 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
1049 status = ixgbe_write_iosf_sb_reg_x550(hw,
1050 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
1051 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1052 if (status)
1053 return status;
1054
1055 /* Disable Flex from training TXFFE. */
1056 status = ixgbe_read_iosf_sb_reg_x550(hw,
1057 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1058 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1059 if (status)
1060 return status;
1061
1062 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1063 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1064 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1065 status = ixgbe_write_iosf_sb_reg_x550(hw,
1066 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
1067 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1068 if (status)
1069 return status;
1070
1071 status = ixgbe_read_iosf_sb_reg_x550(hw,
1072 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1073 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1074 if (status)
1075 return status;
1076
1077 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
1078 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
1079 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
1080 status = ixgbe_write_iosf_sb_reg_x550(hw,
1081 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
1082 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1083 if (status)
1084 return status;
1085
1086 /* Enable override for coefficients. */
1087 status = ixgbe_read_iosf_sb_reg_x550(hw,
1088 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1089 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1090 if (status)
1091 return status;
1092
1093 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
1094 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
1095 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
1096 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
1097 status = ixgbe_write_iosf_sb_reg_x550(hw,
1098 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
1099 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1100 if (status)
1101 return status;
1102
1103 /* Toggle port SW reset by AN reset. */
1104 status = ixgbe_read_iosf_sb_reg_x550(hw,
1105 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1106 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1107 if (status)
1108 return status;
1109
1110 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1111 status = ixgbe_write_iosf_sb_reg_x550(hw,
1112 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1113 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1114
1115 return status;
1116}
1117
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001118/**
Mark Rustade23f3332015-08-08 16:18:33 -07001119 * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
1120 * @hw: pointer to hardware structure
1121 * @linear: true if SFP module is linear
1122 */
1123static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
1124{
1125 switch (hw->phy.sfp_type) {
1126 case ixgbe_sfp_type_not_present:
1127 return IXGBE_ERR_SFP_NOT_PRESENT;
1128 case ixgbe_sfp_type_da_cu_core0:
1129 case ixgbe_sfp_type_da_cu_core1:
1130 *linear = true;
1131 break;
1132 case ixgbe_sfp_type_srlr_core0:
1133 case ixgbe_sfp_type_srlr_core1:
1134 case ixgbe_sfp_type_da_act_lmt_core0:
1135 case ixgbe_sfp_type_da_act_lmt_core1:
1136 case ixgbe_sfp_type_1g_sx_core0:
1137 case ixgbe_sfp_type_1g_sx_core1:
1138 case ixgbe_sfp_type_1g_lx_core0:
1139 case ixgbe_sfp_type_1g_lx_core1:
1140 *linear = false;
1141 break;
1142 case ixgbe_sfp_type_unknown:
1143 case ixgbe_sfp_type_1g_cu_core0:
1144 case ixgbe_sfp_type_1g_cu_core1:
1145 default:
1146 return IXGBE_ERR_SFP_NOT_SUPPORTED;
1147 }
1148
1149 return 0;
1150}
1151
1152/**
Mark Rustad6d373a12015-08-08 16:18:28 -07001153 * ixgbe_setup_mac_link_sfp_x550em - Configure the KR PHY for SFP.
1154 * @hw: pointer to hardware structure
1155 *
1156 * Configures the extern PHY and the integrated KR PHY for SFP support.
1157 */
1158static s32
1159ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
1160 ixgbe_link_speed speed,
1161 __always_unused bool autoneg_wait_to_complete)
1162{
Mark Rustade23f3332015-08-08 16:18:33 -07001163 s32 status;
1164 u16 slice, value;
1165 bool setup_linear = false;
1166
1167 /* Check if SFP module is supported and linear */
1168 status = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
1169
1170 /* If no SFP module present, then return success. Return success since
1171 * there is no reason to configure CS4227 and SFP not present error is
1172 * not accepted in the setup MAC link flow.
1173 */
1174 if (status == IXGBE_ERR_SFP_NOT_PRESENT)
1175 return 0;
1176
1177 if (status)
1178 return status;
1179
Mark Rustadd91e3a72015-09-28 14:37:47 -07001180 if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
1181 /* Configure CS4227 LINE side to 10G SR. */
1182 slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
1183 value = IXGBE_CS4227_SPEED_10G;
1184 status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1185 slice, value);
1186 if (status)
1187 goto i2c_err;
Mark Rustade23f3332015-08-08 16:18:33 -07001188
Mark Rustadd91e3a72015-09-28 14:37:47 -07001189 slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
Mark Rustade23f3332015-08-08 16:18:33 -07001190 value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
Mark Rustadd91e3a72015-09-28 14:37:47 -07001191 status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1192 slice, value);
1193 if (status)
1194 goto i2c_err;
Mark Rustade23f3332015-08-08 16:18:33 -07001195
Mark Rustadd91e3a72015-09-28 14:37:47 -07001196 /* Configure CS4227 for HOST connection rate then type. */
1197 slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
1198 value = speed & IXGBE_LINK_SPEED_10GB_FULL ?
1199 IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
1200 status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1201 slice, value);
1202 if (status)
1203 goto i2c_err;
1204
1205 slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
1206 if (setup_linear)
1207 value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
1208 else
1209 value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1210 status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1211 slice, value);
1212 if (status)
1213 goto i2c_err;
1214
1215 /* Setup XFI internal link. */
Mark Rustade23f3332015-08-08 16:18:33 -07001216 status = ixgbe_setup_ixfi_x550em(hw, &speed);
Mark Rustadd91e3a72015-09-28 14:37:47 -07001217 if (status) {
1218 hw_dbg(hw, "setup_ixfi failed with %d\n", status);
1219 return status;
1220 }
1221 } else {
1222 /* Configure internal PHY for KR/KX. */
1223 status = ixgbe_setup_kr_speed_x550em(hw, speed);
1224 if (status) {
1225 hw_dbg(hw, "setup_kr_speed failed with %d\n", status);
1226 return status;
1227 }
Mark Rustade23f3332015-08-08 16:18:33 -07001228
Mark Rustadd91e3a72015-09-28 14:37:47 -07001229 /* Configure CS4227 LINE side to proper mode. */
1230 slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
1231 if (setup_linear)
1232 value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
1233 else
1234 value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
1235 status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227,
1236 slice, value);
1237 if (status)
1238 goto i2c_err;
1239 }
1240
1241 return 0;
1242
1243i2c_err:
1244 hw_dbg(hw, "combined i2c access failed with %d\n", status);
Mark Rustade23f3332015-08-08 16:18:33 -07001245 return status;
Mark Rustad6d373a12015-08-08 16:18:28 -07001246}
1247
1248/**
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001249 * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
1250 * @hw: pointer to hardware structure
1251 * @speed: new link speed
1252 * @autoneg_wait_to_complete: true when waiting for completion is needed
1253 *
1254 * Setup internal/external PHY link speed based on link speed, then set
1255 * external PHY auto advertised link speed.
1256 *
1257 * Returns error status for any failure
1258 **/
1259static s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
1260 ixgbe_link_speed speed,
1261 bool autoneg_wait)
1262{
1263 s32 status;
1264 ixgbe_link_speed force_speed;
1265
1266 /* Setup internal/external PHY link speed to iXFI (10G), unless
1267 * only 1G is auto advertised then setup KX link.
1268 */
1269 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1270 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1271 else
1272 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1273
1274 /* If internal link mode is XFI, then setup XFI internal link. */
1275 if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
1276 status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
1277
1278 if (status)
1279 return status;
1280 }
1281
1282 return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
1283}
1284
Don Skidmorea4e293a2015-06-09 17:44:58 -07001285/** ixgbe_check_link_t_X550em - Determine link and speed status
1286 * @hw: pointer to hardware structure
1287 * @speed: pointer to link speed
1288 * @link_up: true when link is up
1289 * @link_up_wait_to_complete: bool used to wait for link up or not
1290 *
1291 * Check that both the MAC and X557 external PHY have link.
1292 **/
1293static s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw,
1294 ixgbe_link_speed *speed,
1295 bool *link_up,
1296 bool link_up_wait_to_complete)
1297{
1298 u32 status;
1299 u16 autoneg_status;
1300
1301 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
1302 return IXGBE_ERR_CONFIG;
1303
1304 status = ixgbe_check_mac_link_generic(hw, speed, link_up,
1305 link_up_wait_to_complete);
1306
1307 /* If check link fails or MAC link is not up, then return */
1308 if (status || !(*link_up))
1309 return status;
1310
1311 /* MAC link is up, so check external PHY link.
1312 * Read this twice back to back to indicate current status.
1313 */
1314 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1315 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1316 &autoneg_status);
1317 if (status)
1318 return status;
1319
1320 /* If external PHY link is not up, then indicate link not up */
1321 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
1322 *link_up = false;
1323
1324 return 0;
1325}
1326
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001327/** ixgbe_init_mac_link_ops_X550em - init mac link function pointers
1328 * @hw: pointer to hardware structure
1329 **/
1330static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
1331{
1332 struct ixgbe_mac_info *mac = &hw->mac;
1333
1334 switch (mac->ops.get_media_type(hw)) {
1335 case ixgbe_media_type_fiber:
1336 /* CS4227 does not support autoneg, so disable the laser control
1337 * functions for SFP+ fiber
1338 */
1339 mac->ops.disable_tx_laser = NULL;
1340 mac->ops.enable_tx_laser = NULL;
1341 mac->ops.flap_tx_laser = NULL;
Mark Rustad6d373a12015-08-08 16:18:28 -07001342 mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
Mark Rustadafdc71e2016-01-25 16:32:10 -08001343 mac->ops.setup_fc = ixgbe_setup_fc_x550em;
Mark Rustad6d373a12015-08-08 16:18:28 -07001344 mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
1345 mac->ops.set_rate_select_speed =
1346 ixgbe_set_soft_rate_select_speed;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001347 break;
1348 case ixgbe_media_type_copper:
1349 mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
Mark Rustadafdc71e2016-01-25 16:32:10 -08001350 mac->ops.setup_fc = ixgbe_setup_fc_generic;
Don Skidmorea4e293a2015-06-09 17:44:58 -07001351 mac->ops.check_link = ixgbe_check_link_t_X550em;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001352 break;
1353 default:
Mark Rustadafdc71e2016-01-25 16:32:10 -08001354 mac->ops.setup_fc = ixgbe_setup_fc_x550em;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001355 break;
1356 }
1357}
1358
1359/** ixgbe_setup_sfp_modules_X550em - Setup SFP module
1360 * @hw: pointer to hardware structure
1361 */
1362static s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
1363{
Mark Rustade23f3332015-08-08 16:18:33 -07001364 s32 status;
1365 bool linear;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001366
Mark Rustade23f3332015-08-08 16:18:33 -07001367 /* Check if SFP module is supported */
1368 status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
1369 if (status)
1370 return status;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001371
1372 ixgbe_init_mac_link_ops_X550em(hw);
1373 hw->phy.ops.reset = NULL;
1374
Mark Rustade23f3332015-08-08 16:18:33 -07001375 return 0;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001376}
1377
1378/** ixgbe_get_link_capabilities_x550em - Determines link capabilities
1379 * @hw: pointer to hardware structure
1380 * @speed: pointer to link speed
1381 * @autoneg: true when autoneg or autotry is enabled
1382 **/
1383static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
1384 ixgbe_link_speed *speed,
1385 bool *autoneg)
1386{
1387 /* SFP */
1388 if (hw->phy.media_type == ixgbe_media_type_fiber) {
1389 /* CS4227 SFP must not enable auto-negotiation */
1390 *autoneg = false;
1391
1392 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
1393 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
1394 *speed = IXGBE_LINK_SPEED_1GB_FULL;
1395 return 0;
1396 }
1397
1398 /* Link capabilities are based on SFP */
1399 if (hw->phy.multispeed_fiber)
1400 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1401 IXGBE_LINK_SPEED_1GB_FULL;
1402 else
1403 *speed = IXGBE_LINK_SPEED_10GB_FULL;
1404 } else {
1405 *speed = IXGBE_LINK_SPEED_10GB_FULL |
1406 IXGBE_LINK_SPEED_1GB_FULL;
1407 *autoneg = true;
1408 }
1409 return 0;
1410}
1411
1412/**
1413 * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
1414 * @hw: pointer to hardware structure
1415 * @lsc: pointer to boolean flag which indicates whether external Base T
1416 * PHY interrupt is lsc
1417 *
1418 * Determime if external Base T PHY interrupt cause is high temperature
1419 * failure alarm or link status change.
1420 *
1421 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1422 * failure alarm, else return PHY access status.
1423 **/
1424static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
1425{
1426 u32 status;
1427 u16 reg;
1428
1429 *lsc = false;
1430
1431 /* Vendor alarm triggered */
1432 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1433 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1434 &reg);
1435
1436 if (status || !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
1437 return status;
1438
1439 /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
1440 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
1441 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1442 &reg);
1443
1444 if (status || !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1445 IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
1446 return status;
1447
Mark Rustad83a9fb22015-10-19 09:22:14 -07001448 /* Global alarm triggered */
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001449 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
1450 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1451 &reg);
1452
1453 if (status)
1454 return status;
1455
1456 /* If high temperature failure, then return over temp error and exit */
1457 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
1458 /* power down the PHY in case the PHY FW didn't already */
1459 ixgbe_set_copper_phy_power(hw, false);
1460 return IXGBE_ERR_OVERTEMP;
1461 }
Mark Rustad83a9fb22015-10-19 09:22:14 -07001462 if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
1463 /* device fault alarm triggered */
1464 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
1465 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1466 &reg);
1467 if (status)
1468 return status;
1469
1470 /* if device fault was due to high temp alarm handle and exit */
1471 if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
1472 /* power down the PHY in case the PHY FW didn't */
1473 ixgbe_set_copper_phy_power(hw, false);
1474 return IXGBE_ERR_OVERTEMP;
1475 }
1476 }
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001477
1478 /* Vendor alarm 2 triggered */
1479 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
1480 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1481
1482 if (status || !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
1483 return status;
1484
1485 /* link connect/disconnect event occurred */
1486 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
1487 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1488
1489 if (status)
1490 return status;
1491
1492 /* Indicate LSC */
1493 if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
1494 *lsc = true;
1495
1496 return 0;
1497}
1498
1499/**
1500 * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
1501 * @hw: pointer to hardware structure
1502 *
1503 * Enable link status change and temperature failure alarm for the external
1504 * Base T PHY
1505 *
1506 * Returns PHY access status
1507 **/
1508static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
1509{
1510 u32 status;
1511 u16 reg;
1512 bool lsc;
1513
1514 /* Clear interrupt flags */
1515 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
1516
1517 /* Enable link status change alarm */
1518 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1519 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
1520 if (status)
1521 return status;
1522
1523 reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
1524
1525 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
1526 IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
1527 if (status)
1528 return status;
1529
Mark Rustad83a9fb22015-10-19 09:22:14 -07001530 /* Enable high temperature failure and global fault alarms */
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001531 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1532 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1533 &reg);
1534 if (status)
1535 return status;
1536
Mark Rustad83a9fb22015-10-19 09:22:14 -07001537 reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
1538 IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001539
1540 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
1541 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1542 reg);
1543 if (status)
1544 return status;
1545
1546 /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
1547 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1548 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1549 &reg);
1550 if (status)
1551 return status;
1552
1553 reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
1554 IXGBE_MDIO_GLOBAL_ALARM_1_INT);
1555
1556 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
1557 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1558 reg);
1559 if (status)
1560 return status;
1561
1562 /* Enable chip-wide vendor alarm */
1563 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1564 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1565 &reg);
1566 if (status)
1567 return status;
1568
1569 reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
1570
1571 status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
1572 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1573 reg);
1574
1575 return status;
1576}
1577
1578/**
1579 * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
1580 * @hw: pointer to hardware structure
1581 *
1582 * Handle external Base T PHY interrupt. If high temperature
1583 * failure alarm then return error, else if link status change
1584 * then setup internal/external PHY link
1585 *
1586 * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
1587 * failure alarm, else return PHY access status.
1588 **/
1589static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
1590{
1591 struct ixgbe_phy_info *phy = &hw->phy;
1592 bool lsc;
1593 u32 status;
1594
1595 status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
1596 if (status)
1597 return status;
1598
Mark Rustada85ce532015-09-09 13:37:33 -07001599 if (lsc && phy->ops.setup_internal_link)
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001600 return phy->ops.setup_internal_link(hw);
1601
1602 return 0;
1603}
1604
1605/**
1606 * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
1607 * @hw: pointer to hardware structure
1608 * @speed: link speed
1609 *
1610 * Configures the integrated KR PHY.
1611 **/
1612static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
1613 ixgbe_link_speed speed)
1614{
1615 s32 status;
1616 u32 reg_val;
1617
1618 status = ixgbe_read_iosf_sb_reg_x550(hw,
1619 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1620 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1621 if (status)
1622 return status;
1623
1624 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
1625 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ |
1626 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC);
1627 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
1628 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
1629
1630 /* Advertise 10G support. */
1631 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
1632 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
1633
1634 /* Advertise 1G support. */
1635 if (speed & IXGBE_LINK_SPEED_1GB_FULL)
1636 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
1637
1638 /* Restart auto-negotiation. */
1639 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
1640 status = ixgbe_write_iosf_sb_reg_x550(hw,
1641 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
1642 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1643
1644 return status;
1645}
1646
Don Skidmore6a14ee02014-12-05 03:59:50 +00001647/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
1648 * @hw: pointer to hardware structure
1649 *
1650 * Configures the integrated KX4 PHY.
1651 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00001652static s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001653{
1654 s32 status;
1655 u32 reg_val;
1656
1657 status = ixgbe_read_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
1658 IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
1659 hw->bus.lan_id, &reg_val);
1660 if (status)
1661 return status;
1662
1663 reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 |
1664 IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX);
1665
1666 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE;
1667
1668 /* Advertise 10G support. */
1669 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
1670 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4;
1671
1672 /* Advertise 1G support. */
1673 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
1674 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX;
1675
1676 /* Restart auto-negotiation. */
1677 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART;
1678 status = ixgbe_write_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
1679 IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
1680 hw->bus.lan_id, reg_val);
1681
1682 return status;
1683}
1684
1685/** ixgbe_setup_kr_x550em - Configure the KR PHY.
1686 * @hw: pointer to hardware structure
1687 *
1688 * Configures the integrated KR PHY.
1689 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00001690static s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001691{
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001692 return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
Don Skidmore6a14ee02014-12-05 03:59:50 +00001693}
1694
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001695/** ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
1696 * @hw: address of hardware structure
1697 * @link_up: address of boolean to indicate link status
1698 *
1699 * Returns error code if unable to get link status.
1700 **/
1701static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
1702{
1703 u32 ret;
1704 u16 autoneg_status;
1705
1706 *link_up = false;
1707
1708 /* read this twice back to back to indicate current status */
1709 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1710 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1711 &autoneg_status);
1712 if (ret)
1713 return ret;
1714
1715 ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1716 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1717 &autoneg_status);
1718 if (ret)
1719 return ret;
1720
1721 *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
1722
1723 return 0;
1724}
1725
1726/** ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
Don Skidmore6a14ee02014-12-05 03:59:50 +00001727 * @hw: point to hardware structure
1728 *
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001729 * Configures the link between the integrated KR PHY and the external X557 PHY
1730 * The driver will call this function when it gets a link status change
1731 * interrupt from the X557 PHY. This function configures the link speed
1732 * between the PHYs to match the link speed of the BASE-T link.
Don Skidmore6a14ee02014-12-05 03:59:50 +00001733 *
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001734 * A return of a non-zero value indicates an error, and the base driver should
1735 * not report link up.
Don Skidmore6a14ee02014-12-05 03:59:50 +00001736 **/
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001737static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001738{
Don Skidmore6a14ee02014-12-05 03:59:50 +00001739 ixgbe_link_speed force_speed;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001740 bool link_up;
1741 u32 status;
1742 u16 speed;
Don Skidmore6a14ee02014-12-05 03:59:50 +00001743
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001744 if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
1745 return IXGBE_ERR_CONFIG;
1746
Mark Rustadf164b842015-10-16 13:27:49 -07001747 if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
1748 speed = IXGBE_LINK_SPEED_10GB_FULL |
1749 IXGBE_LINK_SPEED_1GB_FULL;
1750 return ixgbe_setup_kr_speed_x550em(hw, speed);
1751 }
1752
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001753 /* If link is not up, then there is no setup necessary so return */
1754 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
Don Skidmore6a14ee02014-12-05 03:59:50 +00001755 if (status)
1756 return status;
1757
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001758 if (!link_up)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001759 return 0;
1760
Don Skidmore6a14ee02014-12-05 03:59:50 +00001761 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
1762 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1763 &speed);
Don Skidmorec3dc4c02015-06-09 16:26:44 -07001764 if (status)
1765 return status;
1766
1767 /* If link is not still up, then no setup is necessary so return */
1768 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1769 if (status)
1770 return status;
1771
1772 if (!link_up)
1773 return 0;
Don Skidmore6a14ee02014-12-05 03:59:50 +00001774
1775 /* clear everything but the speed and duplex bits */
1776 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
1777
1778 switch (speed) {
1779 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
1780 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1781 break;
1782 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
1783 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1784 break;
1785 default:
1786 /* Internal PHY does not support anything else */
1787 return IXGBE_ERR_INVALID_LINK_SETTINGS;
1788 }
1789
1790 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
1791}
1792
Don Skidmoref4410d22015-06-09 16:29:51 -07001793/** ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
1794 * @hw: pointer to hardware structure
1795 **/
1796static s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
1797{
1798 s32 status;
1799
1800 status = ixgbe_reset_phy_generic(hw);
1801
1802 if (status)
1803 return status;
1804
1805 /* Configure Link Status Alarm and Temperature Threshold interrupts */
1806 return ixgbe_enable_lasi_ext_t_x550em(hw);
1807}
1808
Don Skidmore6ac74392015-06-17 17:34:31 -04001809/** ixgbe_get_lcd_x550em - Determine lowest common denominator
1810 * @hw: pointer to hardware structure
1811 * @lcd_speed: pointer to lowest common link speed
1812 *
1813 * Determine lowest common link speed with link partner.
1814 **/
1815static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw,
1816 ixgbe_link_speed *lcd_speed)
1817{
1818 u16 an_lp_status;
1819 s32 status;
1820 u16 word = hw->eeprom.ctrl_word_3;
1821
1822 *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
1823
1824 status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
1825 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1826 &an_lp_status);
1827 if (status)
1828 return status;
1829
1830 /* If link partner advertised 1G, return 1G */
1831 if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
1832 *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
1833 return status;
1834 }
1835
1836 /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
1837 if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
1838 (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
1839 return status;
1840
1841 /* Link partner not capable of lower speeds, return 10G */
1842 *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
1843 return status;
1844}
1845
Mark Rustadafdc71e2016-01-25 16:32:10 -08001846/**
1847 * ixgbe_setup_fc_x550em - Set up flow control
1848 * @hw: pointer to hardware structure
1849 */
1850static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw)
1851{
1852 bool pause, asm_dir;
1853 u32 reg_val;
1854 s32 rc;
1855
1856 /* Validate the requested mode */
1857 if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
1858 hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
1859 return IXGBE_ERR_INVALID_LINK_SETTINGS;
1860 }
1861
1862 /* 10gig parts do not have a word in the EEPROM to determine the
1863 * default flow control setting, so we explicitly set it to full.
1864 */
1865 if (hw->fc.requested_mode == ixgbe_fc_default)
1866 hw->fc.requested_mode = ixgbe_fc_full;
1867
1868 /* Determine PAUSE and ASM_DIR bits. */
1869 switch (hw->fc.requested_mode) {
1870 case ixgbe_fc_none:
1871 pause = false;
1872 asm_dir = false;
1873 break;
1874 case ixgbe_fc_tx_pause:
1875 pause = false;
1876 asm_dir = true;
1877 break;
1878 case ixgbe_fc_rx_pause:
1879 /* Rx Flow control is enabled and Tx Flow control is
1880 * disabled by software override. Since there really
1881 * isn't a way to advertise that we are capable of RX
1882 * Pause ONLY, we will advertise that we support both
1883 * symmetric and asymmetric Rx PAUSE, as such we fall
1884 * through to the fc_full statement. Later, we will
1885 * disable the adapter's ability to send PAUSE frames.
1886 */
1887 /* Fallthrough */
1888 case ixgbe_fc_full:
1889 pause = true;
1890 asm_dir = true;
1891 break;
1892 default:
1893 hw_err(hw, "Flow control param set incorrectly\n");
1894 return IXGBE_ERR_CONFIG;
1895 }
1896
1897 if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR)
1898 return 0;
1899
1900 rc = ixgbe_read_iosf_sb_reg_x550(hw,
1901 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
1902 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
1903 if (rc)
1904 return rc;
1905
1906 reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
1907 IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
1908 if (pause)
1909 reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
1910 if (asm_dir)
1911 reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
1912 rc = ixgbe_write_iosf_sb_reg_x550(hw,
1913 IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
1914 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
1915
1916 /* This device does not fully support AN. */
1917 hw->fc.disable_fc_autoneg = true;
1918
1919 return rc;
1920}
1921
Don Skidmore6ac74392015-06-17 17:34:31 -04001922/** ixgbe_enter_lplu_x550em - Transition to low power states
1923 * @hw: pointer to hardware structure
1924 *
1925 * Configures Low Power Link Up on transition to low power states
1926 * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting
1927 * the X557 PHY immediately prior to entering LPLU.
1928 **/
1929static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
1930{
1931 u16 an_10g_cntl_reg, autoneg_reg, speed;
1932 s32 status;
1933 ixgbe_link_speed lcd_speed;
1934 u32 save_autoneg;
1935 bool link_up;
1936
Don Skidmore6ac74392015-06-17 17:34:31 -04001937 /* If blocked by MNG FW, then don't restart AN */
1938 if (ixgbe_check_reset_blocked(hw))
1939 return 0;
1940
1941 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1942 if (status)
1943 return status;
1944
1945 status = hw->eeprom.ops.read(hw, NVM_INIT_CTRL_3,
1946 &hw->eeprom.ctrl_word_3);
1947 if (status)
1948 return status;
1949
1950 /* If link is down, LPLU disabled in NVM, WoL disabled, or
1951 * manageability disabled, then force link down by entering
1952 * low power mode.
1953 */
1954 if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
1955 !(hw->wol_enabled || ixgbe_mng_present(hw)))
1956 return ixgbe_set_copper_phy_power(hw, false);
1957
1958 /* Determine LCD */
1959 status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
1960 if (status)
1961 return status;
1962
1963 /* If no valid LCD link speed, then force link down and exit. */
1964 if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
1965 return ixgbe_set_copper_phy_power(hw, false);
1966
1967 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
1968 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1969 &speed);
1970 if (status)
1971 return status;
1972
1973 /* If no link now, speed is invalid so take link down */
1974 status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
1975 if (status)
1976 return ixgbe_set_copper_phy_power(hw, false);
1977
1978 /* clear everything but the speed bits */
1979 speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
1980
1981 /* If current speed is already LCD, then exit. */
1982 if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
1983 (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
1984 ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
1985 (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
1986 return status;
1987
1988 /* Clear AN completed indication */
1989 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
1990 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1991 &autoneg_reg);
1992 if (status)
1993 return status;
1994
1995 status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
1996 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1997 &an_10g_cntl_reg);
1998 if (status)
1999 return status;
2000
2001 status = hw->phy.ops.read_reg(hw,
2002 IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
2003 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
2004 &autoneg_reg);
2005 if (status)
2006 return status;
2007
2008 save_autoneg = hw->phy.autoneg_advertised;
2009
2010 /* Setup link at least common link speed */
2011 status = hw->mac.ops.setup_link(hw, lcd_speed, false);
2012
2013 /* restore autoneg from before setting lplu speed */
2014 hw->phy.autoneg_advertised = save_autoneg;
2015
2016 return status;
2017}
2018
Don Skidmore6a14ee02014-12-05 03:59:50 +00002019/** ixgbe_init_phy_ops_X550em - PHY/SFP specific init
2020 * @hw: pointer to hardware structure
2021 *
2022 * Initialize any function pointers that were not able to be
2023 * set during init_shared_code because the PHY/SFP type was
2024 * not known. Perform the SFP init if necessary.
2025 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00002026static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00002027{
2028 struct ixgbe_phy_info *phy = &hw->phy;
2029 s32 ret_val;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002030
Don Skidmore7e49d612015-06-09 17:48:54 -07002031 hw->mac.ops.set_lan_id(hw);
2032
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002033 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002034 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
Don Skidmoreab5fe0c2015-06-09 16:18:56 -07002035 ixgbe_setup_mux_ctl(hw);
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002036
2037 /* Save NW management interface connected on board. This is used
2038 * to determine internal PHY mode.
2039 */
2040 phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
Don Skidmore6a14ee02014-12-05 03:59:50 +00002041 }
2042
2043 /* Identify the PHY or SFP module */
2044 ret_val = phy->ops.identify(hw);
2045
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002046 /* Setup function pointers based on detected hardware */
Don Skidmore6a14ee02014-12-05 03:59:50 +00002047 ixgbe_init_mac_link_ops_X550em(hw);
2048 if (phy->sfp_type != ixgbe_sfp_type_unknown)
2049 phy->ops.reset = NULL;
2050
2051 /* Set functions pointers based on phy type */
2052 switch (hw->phy.type) {
2053 case ixgbe_phy_x550em_kx4:
2054 phy->ops.setup_link = ixgbe_setup_kx4_x550em;
2055 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2056 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2057 break;
2058 case ixgbe_phy_x550em_kr:
2059 phy->ops.setup_link = ixgbe_setup_kr_x550em;
2060 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
2061 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
2062 break;
2063 case ixgbe_phy_x550em_ext_t:
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002064 /* Save NW management interface connected on board. This is used
2065 * to determine internal PHY mode
2066 */
2067 phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
2068
2069 /* If internal link mode is XFI, then setup iXFI internal link,
2070 * else setup KR now.
2071 */
Mark Rustadf164b842015-10-16 13:27:49 -07002072 phy->ops.setup_internal_link =
2073 ixgbe_setup_internal_phy_t_x550em;
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002074
Don Skidmore6ac74392015-06-17 17:34:31 -04002075 /* setup SW LPLU only for first revision */
Mark Rustad3ca2b252015-11-20 13:12:17 -08002076 if (hw->mac.type == ixgbe_mac_X550EM_x &&
2077 !(IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)) &
2078 IXGBE_FUSES0_REV_MASK))
Don Skidmore6ac74392015-06-17 17:34:31 -04002079 phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
2080
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002081 phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
Don Skidmoref4410d22015-06-09 16:29:51 -07002082 phy->ops.reset = ixgbe_reset_phy_t_X550em;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002083 break;
2084 default:
2085 break;
2086 }
Don Skidmorec3dc4c02015-06-09 16:26:44 -07002087
Don Skidmore6a14ee02014-12-05 03:59:50 +00002088 return ret_val;
2089}
2090
2091/** ixgbe_get_media_type_X550em - Get media type
2092 * @hw: pointer to hardware structure
2093 *
2094 * Returns the media type (fiber, copper, backplane)
2095 *
2096 */
Don Skidmore7ddbde32014-12-06 05:59:21 +00002097static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00002098{
2099 enum ixgbe_media_type media_type;
2100
2101 /* Detect if there is a copper PHY attached. */
2102 switch (hw->device_id) {
2103 case IXGBE_DEV_ID_X550EM_X_KR:
2104 case IXGBE_DEV_ID_X550EM_X_KX4:
2105 media_type = ixgbe_media_type_backplane;
2106 break;
2107 case IXGBE_DEV_ID_X550EM_X_SFP:
2108 media_type = ixgbe_media_type_fiber;
2109 break;
2110 case IXGBE_DEV_ID_X550EM_X_1G_T:
2111 case IXGBE_DEV_ID_X550EM_X_10G_T:
2112 media_type = ixgbe_media_type_copper;
2113 break;
2114 default:
2115 media_type = ixgbe_media_type_unknown;
2116 break;
2117 }
2118 return media_type;
2119}
2120
2121/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
2122 ** @hw: pointer to hardware structure
2123 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00002124static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00002125{
Mark Rustada1e869d2015-04-10 10:36:36 -07002126 s32 status;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002127 u16 reg;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002128
Don Skidmore6a14ee02014-12-05 03:59:50 +00002129 status = hw->phy.ops.read_reg(hw,
Don Skidmoree2261bc2015-06-09 17:02:35 -07002130 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002131 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
2132 &reg);
2133 if (status)
2134 return status;
2135
Don Skidmoree2261bc2015-06-09 17:02:35 -07002136 /* If PHY FW reset completed bit is set then this is the first
2137 * SW instance after a power on so the PHY FW must be un-stalled.
2138 */
2139 if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
2140 status = hw->phy.ops.read_reg(hw,
2141 IXGBE_MDIO_GLOBAL_RES_PR_10,
2142 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2143 &reg);
2144 if (status)
2145 return status;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002146
Don Skidmoree2261bc2015-06-09 17:02:35 -07002147 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002148
Don Skidmoree2261bc2015-06-09 17:02:35 -07002149 status = hw->phy.ops.write_reg(hw,
2150 IXGBE_MDIO_GLOBAL_RES_PR_10,
2151 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
2152 reg);
2153 if (status)
2154 return status;
2155 }
Don Skidmore6a14ee02014-12-05 03:59:50 +00002156
Don Skidmore6a14ee02014-12-05 03:59:50 +00002157 return status;
2158}
2159
2160/** ixgbe_reset_hw_X550em - Perform hardware reset
2161 ** @hw: pointer to hardware structure
2162 **
2163 ** Resets the hardware by resetting the transmit and receive units, masks
2164 ** and clears all interrupts, perform a PHY reset, and perform a link (MAC)
2165 ** reset.
2166 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00002167static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00002168{
2169 ixgbe_link_speed link_speed;
2170 s32 status;
2171 u32 ctrl = 0;
2172 u32 i;
Don Skidmorededa5622015-06-09 17:39:46 -07002173 u32 hlreg0;
Don Skidmore6a14ee02014-12-05 03:59:50 +00002174 bool link_up = false;
2175
2176 /* Call adapter stop to disable Tx/Rx and clear interrupts */
2177 status = hw->mac.ops.stop_adapter(hw);
2178 if (status)
2179 return status;
2180
2181 /* flush pending Tx transactions */
2182 ixgbe_clear_tx_pending(hw);
2183
2184 /* PHY ops must be identified and initialized prior to reset */
2185
2186 /* Identify PHY and related function pointers */
2187 status = hw->phy.ops.init(hw);
2188
2189 /* start the external PHY */
2190 if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
2191 status = ixgbe_init_ext_t_x550em(hw);
2192 if (status)
2193 return status;
2194 }
2195
2196 /* Setup SFP module if there is one present. */
2197 if (hw->phy.sfp_setup_needed) {
2198 status = hw->mac.ops.setup_sfp(hw);
2199 hw->phy.sfp_setup_needed = false;
2200 }
2201
2202 /* Reset PHY */
2203 if (!hw->phy.reset_disable && hw->phy.ops.reset)
2204 hw->phy.ops.reset(hw);
2205
2206mac_reset_top:
2207 /* Issue global reset to the MAC. Needs to be SW reset if link is up.
2208 * If link reset is used when link is up, it might reset the PHY when
2209 * mng is using it. If link is down or the flag to force full link
2210 * reset is set, then perform link reset.
2211 */
2212 ctrl = IXGBE_CTRL_LNK_RST;
2213
2214 if (!hw->force_full_reset) {
2215 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
2216 if (link_up)
2217 ctrl = IXGBE_CTRL_RST;
2218 }
2219
2220 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
2221 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
2222 IXGBE_WRITE_FLUSH(hw);
Mark Rustadefff2e02015-10-27 13:23:14 -07002223 usleep_range(1000, 1200);
Don Skidmore6a14ee02014-12-05 03:59:50 +00002224
2225 /* Poll for reset bit to self-clear meaning reset is complete */
2226 for (i = 0; i < 10; i++) {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002227 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
2228 if (!(ctrl & IXGBE_CTRL_RST_MASK))
2229 break;
Mark Rustadefff2e02015-10-27 13:23:14 -07002230 udelay(1);
Don Skidmore6a14ee02014-12-05 03:59:50 +00002231 }
2232
2233 if (ctrl & IXGBE_CTRL_RST_MASK) {
2234 status = IXGBE_ERR_RESET_FAILED;
2235 hw_dbg(hw, "Reset polling failed to complete.\n");
2236 }
2237
2238 msleep(50);
2239
2240 /* Double resets are required for recovery from certain error
2241 * clear the multicast table. Also reset num_rar_entries to 128,
2242 * since we modify this value when programming the SAN MAC address.
2243 */
2244 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
2245 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2246 goto mac_reset_top;
2247 }
2248
2249 /* Store the permanent mac address */
2250 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
2251
2252 /* Store MAC address from RAR0, clear receive address registers, and
2253 * clear the multicast table. Also reset num_rar_entries to 128,
2254 * since we modify this value when programming the SAN MAC address.
2255 */
2256 hw->mac.num_rar_entries = 128;
2257 hw->mac.ops.init_rx_addrs(hw);
2258
Don Skidmorededa5622015-06-09 17:39:46 -07002259 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
2260 hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
2261 hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
2262 IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
2263 }
2264
Don Skidmoreab5fe0c2015-06-09 16:18:56 -07002265 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
2266 ixgbe_setup_mux_ctl(hw);
2267
Don Skidmore6a14ee02014-12-05 03:59:50 +00002268 return status;
2269}
2270
Don Skidmore5b7f0002015-01-28 07:03:38 +00002271/** ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype
2272 * anti-spoofing
2273 * @hw: pointer to hardware structure
2274 * @enable: enable or disable switch for Ethertype anti-spoofing
2275 * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
2276 **/
Don Skidmorebc035fc2015-03-13 14:03:25 -07002277static void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
2278 bool enable, int vf)
Don Skidmore5b7f0002015-01-28 07:03:38 +00002279{
2280 int vf_target_reg = vf >> 3;
2281 int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
2282 u32 pfvfspoof;
2283
2284 pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
2285 if (enable)
2286 pfvfspoof |= (1 << vf_target_shift);
2287 else
2288 pfvfspoof &= ~(1 << vf_target_shift);
2289
2290 IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
2291}
2292
Don Skidmore6d4c96a2015-04-09 22:03:23 -07002293/** ixgbe_set_source_address_pruning_X550 - Enable/Disbale src address pruning
2294 * @hw: pointer to hardware structure
2295 * @enable: enable or disable source address pruning
2296 * @pool: Rx pool to set source address pruning for
2297 **/
2298static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
2299 bool enable,
2300 unsigned int pool)
2301{
2302 u64 pfflp;
2303
2304 /* max rx pool is 63 */
2305 if (pool > 63)
2306 return;
2307
2308 pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
2309 pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
2310
2311 if (enable)
2312 pfflp |= (1ULL << pool);
2313 else
2314 pfflp &= ~(1ULL << pool);
2315
2316 IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
2317 IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
2318}
2319
Mark Rustad449e21a2015-08-08 16:18:53 -07002320/**
2321 * ixgbe_set_mux - Set mux for port 1 access with CS4227
2322 * @hw: pointer to hardware structure
2323 * @state: set mux if 1, clear if 0
2324 */
2325static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
2326{
2327 u32 esdp;
2328
2329 if (!hw->bus.lan_id)
2330 return;
2331 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
2332 if (state)
2333 esdp |= IXGBE_ESDP_SDP1;
2334 else
2335 esdp &= ~IXGBE_ESDP_SDP1;
2336 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
2337 IXGBE_WRITE_FLUSH(hw);
2338}
2339
2340/**
2341 * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
2342 * @hw: pointer to hardware structure
2343 * @mask: Mask to specify which semaphore to acquire
2344 *
2345 * Acquires the SWFW semaphore and sets the I2C MUX
2346 */
2347static s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
2348{
2349 s32 status;
2350
2351 status = ixgbe_acquire_swfw_sync_X540(hw, mask);
2352 if (status)
2353 return status;
2354
2355 if (mask & IXGBE_GSSR_I2C_MASK)
2356 ixgbe_set_mux(hw, 1);
2357
2358 return 0;
2359}
2360
2361/**
2362 * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
2363 * @hw: pointer to hardware structure
2364 * @mask: Mask to specify which semaphore to release
2365 *
2366 * Releases the SWFW semaphore and sets the I2C MUX
2367 */
2368static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
2369{
2370 if (mask & IXGBE_GSSR_I2C_MASK)
2371 ixgbe_set_mux(hw, 0);
2372
2373 ixgbe_release_swfw_sync_X540(hw, mask);
2374}
2375
Don Skidmore6a14ee02014-12-05 03:59:50 +00002376#define X550_COMMON_MAC \
2377 .init_hw = &ixgbe_init_hw_generic, \
2378 .start_hw = &ixgbe_start_hw_X540, \
2379 .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, \
2380 .enable_rx_dma = &ixgbe_enable_rx_dma_generic, \
2381 .get_mac_addr = &ixgbe_get_mac_addr_generic, \
2382 .get_device_caps = &ixgbe_get_device_caps_generic, \
2383 .stop_adapter = &ixgbe_stop_adapter_generic, \
Don Skidmore6a14ee02014-12-05 03:59:50 +00002384 .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, \
2385 .read_analog_reg8 = NULL, \
2386 .write_analog_reg8 = NULL, \
2387 .set_rxpba = &ixgbe_set_rxpba_generic, \
2388 .check_link = &ixgbe_check_mac_link_generic, \
2389 .led_on = &ixgbe_led_on_generic, \
2390 .led_off = &ixgbe_led_off_generic, \
2391 .blink_led_start = &ixgbe_blink_led_start_X540, \
2392 .blink_led_stop = &ixgbe_blink_led_stop_X540, \
2393 .set_rar = &ixgbe_set_rar_generic, \
2394 .clear_rar = &ixgbe_clear_rar_generic, \
2395 .set_vmdq = &ixgbe_set_vmdq_generic, \
2396 .set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic, \
2397 .clear_vmdq = &ixgbe_clear_vmdq_generic, \
2398 .init_rx_addrs = &ixgbe_init_rx_addrs_generic, \
2399 .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, \
2400 .enable_mc = &ixgbe_enable_mc_generic, \
2401 .disable_mc = &ixgbe_disable_mc_generic, \
2402 .clear_vfta = &ixgbe_clear_vfta_generic, \
2403 .set_vfta = &ixgbe_set_vfta_generic, \
2404 .fc_enable = &ixgbe_fc_enable_generic, \
2405 .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, \
2406 .init_uta_tables = &ixgbe_init_uta_tables_generic, \
2407 .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \
2408 .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \
Don Skidmore6d4c96a2015-04-09 22:03:23 -07002409 .set_source_address_pruning = \
2410 &ixgbe_set_source_address_pruning_X550, \
Don Skidmore5b7f0002015-01-28 07:03:38 +00002411 .set_ethertype_anti_spoofing = \
2412 &ixgbe_set_ethertype_anti_spoofing_X550, \
Don Skidmore6a14ee02014-12-05 03:59:50 +00002413 .disable_rx_buff = &ixgbe_disable_rx_buff_generic, \
2414 .enable_rx_buff = &ixgbe_enable_rx_buff_generic, \
2415 .get_thermal_sensor_data = NULL, \
2416 .init_thermal_sensor_thresh = NULL, \
Don Skidmore1f9ac572015-03-13 13:54:30 -07002417 .enable_rx = &ixgbe_enable_rx_generic, \
2418 .disable_rx = &ixgbe_disable_rx_x550, \
Don Skidmore6a14ee02014-12-05 03:59:50 +00002419
Mark Rustad37689012016-01-07 10:13:03 -08002420static const struct ixgbe_mac_operations mac_ops_X550 = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002421 X550_COMMON_MAC
2422 .reset_hw = &ixgbe_reset_hw_X540,
2423 .get_media_type = &ixgbe_get_media_type_X540,
2424 .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
2425 .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
2426 .setup_link = &ixgbe_setup_mac_link_X540,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002427 .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic,
Don Skidmore454c65d2015-06-17 20:59:59 -04002428 .get_bus_info = &ixgbe_get_bus_info_generic,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002429 .setup_sfp = NULL,
Mark Rustad449e21a2015-08-08 16:18:53 -07002430 .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540,
2431 .release_swfw_sync = &ixgbe_release_swfw_sync_X540,
Don Skidmoredbd15b82016-03-09 16:45:00 -05002432 .init_swfw_sync = &ixgbe_init_swfw_sync_X540,
Mark Rustadafdc71e2016-01-25 16:32:10 -08002433 .prot_autoc_read = prot_autoc_read_generic,
2434 .prot_autoc_write = prot_autoc_write_generic,
2435 .setup_fc = ixgbe_setup_fc_generic,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002436};
2437
Mark Rustad37689012016-01-07 10:13:03 -08002438static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002439 X550_COMMON_MAC
2440 .reset_hw = &ixgbe_reset_hw_X550em,
2441 .get_media_type = &ixgbe_get_media_type_X550em,
2442 .get_san_mac_addr = NULL,
2443 .get_wwn_prefix = NULL,
2444 .setup_link = NULL, /* defined later */
2445 .get_link_capabilities = &ixgbe_get_link_capabilities_X550em,
Don Skidmore454c65d2015-06-17 20:59:59 -04002446 .get_bus_info = &ixgbe_get_bus_info_X550em,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002447 .setup_sfp = ixgbe_setup_sfp_modules_X550em,
Mark Rustad449e21a2015-08-08 16:18:53 -07002448 .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X550em,
2449 .release_swfw_sync = &ixgbe_release_swfw_sync_X550em,
Don Skidmoredbd15b82016-03-09 16:45:00 -05002450 .init_swfw_sync = &ixgbe_init_swfw_sync_X540,
Mark Rustadafdc71e2016-01-25 16:32:10 -08002451 .setup_fc = NULL, /* defined later */
Don Skidmore6a14ee02014-12-05 03:59:50 +00002452};
2453
2454#define X550_COMMON_EEP \
2455 .read = &ixgbe_read_ee_hostif_X550, \
2456 .read_buffer = &ixgbe_read_ee_hostif_buffer_X550, \
2457 .write = &ixgbe_write_ee_hostif_X550, \
2458 .write_buffer = &ixgbe_write_ee_hostif_buffer_X550, \
2459 .validate_checksum = &ixgbe_validate_eeprom_checksum_X550, \
2460 .update_checksum = &ixgbe_update_eeprom_checksum_X550, \
2461 .calc_checksum = &ixgbe_calc_eeprom_checksum_X550, \
2462
Mark Rustad37689012016-01-07 10:13:03 -08002463static const struct ixgbe_eeprom_operations eeprom_ops_X550 = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002464 X550_COMMON_EEP
2465 .init_params = &ixgbe_init_eeprom_params_X550,
2466};
2467
Mark Rustad37689012016-01-07 10:13:03 -08002468static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002469 X550_COMMON_EEP
2470 .init_params = &ixgbe_init_eeprom_params_X540,
2471};
2472
2473#define X550_COMMON_PHY \
2474 .identify_sfp = &ixgbe_identify_module_generic, \
2475 .reset = NULL, \
2476 .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, \
2477 .read_i2c_byte = &ixgbe_read_i2c_byte_generic, \
2478 .write_i2c_byte = &ixgbe_write_i2c_byte_generic, \
2479 .read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic, \
2480 .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, \
2481 .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, \
Don Skidmorebef23de2015-06-09 17:36:53 -07002482 .read_reg = &ixgbe_read_phy_reg_generic, \
2483 .write_reg = &ixgbe_write_phy_reg_generic, \
2484 .setup_link = &ixgbe_setup_phy_link_generic, \
Don Skidmoreb5529ef2015-06-10 20:42:30 -04002485 .set_phy_power = NULL, \
Don Skidmore6a14ee02014-12-05 03:59:50 +00002486 .check_overtemp = &ixgbe_tn_check_overtemp, \
2487 .get_firmware_version = &ixgbe_get_phy_firmware_version_generic,
2488
Mark Rustad37689012016-01-07 10:13:03 -08002489static const struct ixgbe_phy_operations phy_ops_X550 = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002490 X550_COMMON_PHY
2491 .init = NULL,
2492 .identify = &ixgbe_identify_phy_generic,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002493};
2494
Mark Rustad37689012016-01-07 10:13:03 -08002495static const struct ixgbe_phy_operations phy_ops_X550EM_x = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002496 X550_COMMON_PHY
2497 .init = &ixgbe_init_phy_ops_X550em,
2498 .identify = &ixgbe_identify_phy_x550em,
Mark Rustad4f9e3a32015-08-08 16:17:57 -07002499 .read_i2c_combined = &ixgbe_read_i2c_combined_generic,
2500 .write_i2c_combined = &ixgbe_write_i2c_combined_generic,
Mark Rustadbb5ce9a52015-08-08 16:18:02 -07002501 .read_i2c_combined_unlocked = &ixgbe_read_i2c_combined_generic_unlocked,
2502 .write_i2c_combined_unlocked =
2503 &ixgbe_write_i2c_combined_generic_unlocked,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002504};
2505
Don Skidmore9a900ec2015-06-09 17:15:01 -07002506static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = {
2507 IXGBE_MVALS_INIT(X550)
2508};
2509
2510static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
2511 IXGBE_MVALS_INIT(X550EM_x)
2512};
2513
Mark Rustad37689012016-01-07 10:13:03 -08002514const struct ixgbe_info ixgbe_X550_info = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002515 .mac = ixgbe_mac_X550,
2516 .get_invariants = &ixgbe_get_invariants_X540,
2517 .mac_ops = &mac_ops_X550,
2518 .eeprom_ops = &eeprom_ops_X550,
2519 .phy_ops = &phy_ops_X550,
2520 .mbx_ops = &mbx_ops_generic,
Don Skidmore9a900ec2015-06-09 17:15:01 -07002521 .mvals = ixgbe_mvals_X550,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002522};
2523
Mark Rustad37689012016-01-07 10:13:03 -08002524const struct ixgbe_info ixgbe_X550EM_x_info = {
Don Skidmore6a14ee02014-12-05 03:59:50 +00002525 .mac = ixgbe_mac_X550EM_x,
Don Skidmoreb5529ef2015-06-10 20:42:30 -04002526 .get_invariants = &ixgbe_get_invariants_X550_x,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002527 .mac_ops = &mac_ops_X550EM_x,
2528 .eeprom_ops = &eeprom_ops_X550EM_x,
2529 .phy_ops = &phy_ops_X550EM_x,
2530 .mbx_ops = &mbx_ops_generic,
Don Skidmore9a900ec2015-06-09 17:15:01 -07002531 .mvals = ixgbe_mvals_X550EM_x,
Don Skidmore6a14ee02014-12-05 03:59:50 +00002532};