blob: fcba952af6e206274f64680ba601ceef7c7cc4d3 [file] [log] [blame]
Don Skidmore6a14ee02014-12-05 03:59:50 +00001/*******************************************************************************
2 *
3 * Intel 10 Gigabit PCI Express Linux driver
4 * Copyright(c) 1999 - 2014 Intel Corporation.
5 *
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
29/** ixgbe_identify_phy_x550em - Get PHY type based on device id
30 * @hw: pointer to hardware structure
31 *
32 * Returns error code
33 */
34static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
35{
36 u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
37
38 switch (hw->device_id) {
39 case IXGBE_DEV_ID_X550EM_X_SFP:
40 /* set up for CS4227 usage */
41 hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
42 if (hw->bus.lan_id) {
43 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
44 esdp |= IXGBE_ESDP_SDP1_DIR;
45 }
46 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
47 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
48
49 return ixgbe_identify_module_generic(hw);
50 case IXGBE_DEV_ID_X550EM_X_KX4:
51 hw->phy.type = ixgbe_phy_x550em_kx4;
52 break;
53 case IXGBE_DEV_ID_X550EM_X_KR:
54 hw->phy.type = ixgbe_phy_x550em_kr;
55 break;
56 case IXGBE_DEV_ID_X550EM_X_1G_T:
57 case IXGBE_DEV_ID_X550EM_X_10G_T:
58 return ixgbe_identify_phy_generic(hw);
59 default:
60 break;
61 }
62 return 0;
63}
64
65static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
66 u32 device_type, u16 *phy_data)
67{
68 return IXGBE_NOT_IMPLEMENTED;
69}
70
71static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
72 u32 device_type, u16 phy_data)
73{
74 return IXGBE_NOT_IMPLEMENTED;
75}
76
77/** ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
78 * @hw: pointer to hardware structure
79 *
80 * Initializes the EEPROM parameters ixgbe_eeprom_info within the
81 * ixgbe_hw struct in order to set up EEPROM access.
82 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +000083static s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +000084{
85 struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
86 u32 eec;
87 u16 eeprom_size;
88
89 if (eeprom->type == ixgbe_eeprom_uninitialized) {
90 eeprom->semaphore_delay = 10;
91 eeprom->type = ixgbe_flash;
92
93 eec = IXGBE_READ_REG(hw, IXGBE_EEC);
94 eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
95 IXGBE_EEC_SIZE_SHIFT);
96 eeprom->word_size = 1 << (eeprom_size +
97 IXGBE_EEPROM_WORD_SIZE_SHIFT);
98
99 hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
100 eeprom->type, eeprom->word_size);
101 }
102
103 return 0;
104}
105
106/** ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the
107 * IOSF device
108 * @hw: pointer to hardware structure
109 * @reg_addr: 32 bit PHY register to write
110 * @device_type: 3 bit device type
111 * @phy_data: Pointer to read data from the register
112 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000113static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
114 u32 device_type, u32 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000115{
116 u32 i, command, error;
117
118 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
119 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
120
121 /* Write IOSF control register */
122 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
123
124 /* Check every 10 usec to see if the address cycle completed.
125 * The SB IOSF BUSY bit will clear when the operation is
126 * complete
127 */
128 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
129 usleep_range(10, 20);
130
131 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
132 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
133 break;
134 }
135
136 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
137 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
138 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
139 hw_dbg(hw, "Failed to read, error %x\n", error);
140 return IXGBE_ERR_PHY;
141 }
142
143 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
144 hw_dbg(hw, "Read timed out\n");
145 return IXGBE_ERR_PHY;
146 }
147
148 *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
149
150 return 0;
151}
152
153/** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface
154 * command assuming that the semaphore is already obtained.
155 * @hw: pointer to hardware structure
156 * @offset: offset of word in the EEPROM to read
157 * @data: word read from the EEPROM
158 *
159 * Reads a 16 bit word from the EEPROM using the hostif.
160 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000161static s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
162 u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000163{
164 s32 status;
165 struct ixgbe_hic_read_shadow_ram buffer;
166
167 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
168 buffer.hdr.req.buf_lenh = 0;
169 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
170 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
171
172 /* convert offset from words to bytes */
173 buffer.address = cpu_to_be32(offset * 2);
174 /* one word */
175 buffer.length = cpu_to_be16(sizeof(u16));
176
177 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
178 sizeof(buffer),
179 IXGBE_HI_COMMAND_TIMEOUT, false);
180 if (status)
181 return status;
182
183 *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
184 FW_NVM_DATA_OFFSET);
185
186 return 0;
187}
188
189/** ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
190 * @hw: pointer to hardware structure
191 * @offset: offset of word in the EEPROM to read
192 * @words: number of words
193 * @data: word(s) read from the EEPROM
194 *
195 * Reads a 16 bit word(s) from the EEPROM using the hostif.
196 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000197static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
198 u16 offset, u16 words, u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000199{
200 struct ixgbe_hic_read_shadow_ram buffer;
201 u32 current_word = 0;
202 u16 words_to_read;
203 s32 status;
204 u32 i;
205
206 /* Take semaphore for the entire operation. */
207 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
208 if (status) {
209 hw_dbg(hw, "EEPROM read buffer - semaphore failed\n");
210 return status;
211 }
212
213 while (words) {
214 if (words > FW_MAX_READ_BUFFER_SIZE / 2)
215 words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
216 else
217 words_to_read = words;
218
219 buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
220 buffer.hdr.req.buf_lenh = 0;
221 buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
222 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
223
224 /* convert offset from words to bytes */
225 buffer.address = cpu_to_be32((offset + current_word) * 2);
226 buffer.length = cpu_to_be16(words_to_read * 2);
227
228 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
229 sizeof(buffer),
230 IXGBE_HI_COMMAND_TIMEOUT,
231 false);
232 if (status) {
233 hw_dbg(hw, "Host interface command failed\n");
234 goto out;
235 }
236
237 for (i = 0; i < words_to_read; i++) {
238 u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
239 2 * i;
240 u32 value = IXGBE_READ_REG(hw, reg);
241
242 data[current_word] = (u16)(value & 0xffff);
243 current_word++;
244 i++;
245 if (i < words_to_read) {
246 value >>= 16;
247 data[current_word] = (u16)(value & 0xffff);
248 current_word++;
249 }
250 }
251 words -= words_to_read;
252 }
253
254out:
255 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
256 return status;
257}
258
259/** ixgbe_checksum_ptr_x550 - Checksum one pointer region
260 * @hw: pointer to hardware structure
261 * @ptr: pointer offset in eeprom
262 * @size: size of section pointed by ptr, if 0 first word will be used as size
263 * @csum: address of checksum to update
264 *
265 * Returns error status for any failure
266 **/
267static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
268 u16 size, u16 *csum, u16 *buffer,
269 u32 buffer_size)
270{
271 u16 buf[256];
272 s32 status;
273 u16 length, bufsz, i, start;
274 u16 *local_buffer;
275
276 bufsz = sizeof(buf) / sizeof(buf[0]);
277
278 /* Read a chunk at the pointer location */
279 if (!buffer) {
280 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
281 if (status) {
282 hw_dbg(hw, "Failed to read EEPROM image\n");
283 return status;
284 }
285 local_buffer = buf;
286 } else {
287 if (buffer_size < ptr)
288 return IXGBE_ERR_PARAM;
289 local_buffer = &buffer[ptr];
290 }
291
292 if (size) {
293 start = 0;
294 length = size;
295 } else {
296 start = 1;
297 length = local_buffer[0];
298
299 /* Skip pointer section if length is invalid. */
300 if (length == 0xFFFF || length == 0 ||
301 (ptr + length) >= hw->eeprom.word_size)
302 return 0;
303 }
304
305 if (buffer && ((u32)start + (u32)length > buffer_size))
306 return IXGBE_ERR_PARAM;
307
308 for (i = start; length; i++, length--) {
309 if (i == bufsz && !buffer) {
310 ptr += bufsz;
311 i = 0;
312 if (length < bufsz)
313 bufsz = length;
314
315 /* Read a chunk at the pointer location */
316 status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
317 bufsz, buf);
318 if (status) {
319 hw_dbg(hw, "Failed to read EEPROM image\n");
320 return status;
321 }
322 }
323 *csum += local_buffer[i];
324 }
325 return 0;
326}
327
328/** ixgbe_calc_checksum_X550 - Calculates and returns the checksum
329 * @hw: pointer to hardware structure
330 * @buffer: pointer to buffer containing calculated checksum
331 * @buffer_size: size of buffer
332 *
333 * Returns a negative error code on error, or the 16-bit checksum
334 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000335static s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer,
336 u32 buffer_size)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000337{
338 u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
339 u16 *local_buffer;
340 s32 status;
341 u16 checksum = 0;
342 u16 pointer, i, size;
343
344 hw->eeprom.ops.init_params(hw);
345
346 if (!buffer) {
347 /* Read pointer area */
348 status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
349 IXGBE_EEPROM_LAST_WORD + 1,
350 eeprom_ptrs);
351 if (status) {
352 hw_dbg(hw, "Failed to read EEPROM image\n");
353 return status;
354 }
355 local_buffer = eeprom_ptrs;
356 } else {
357 if (buffer_size < IXGBE_EEPROM_LAST_WORD)
358 return IXGBE_ERR_PARAM;
359 local_buffer = buffer;
360 }
361
362 /* For X550 hardware include 0x0-0x41 in the checksum, skip the
363 * checksum word itself
364 */
365 for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
366 if (i != IXGBE_EEPROM_CHECKSUM)
367 checksum += local_buffer[i];
368
369 /* Include all data from pointers 0x3, 0x6-0xE. This excludes the
370 * FW, PHY module, and PCIe Expansion/Option ROM pointers.
371 */
372 for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
373 if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
374 continue;
375
376 pointer = local_buffer[i];
377
378 /* Skip pointer section if the pointer is invalid. */
379 if (pointer == 0xFFFF || pointer == 0 ||
380 pointer >= hw->eeprom.word_size)
381 continue;
382
383 switch (i) {
384 case IXGBE_PCIE_GENERAL_PTR:
385 size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
386 break;
387 case IXGBE_PCIE_CONFIG0_PTR:
388 case IXGBE_PCIE_CONFIG1_PTR:
389 size = IXGBE_PCIE_CONFIG_SIZE;
390 break;
391 default:
392 size = 0;
393 break;
394 }
395
396 status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
397 buffer, buffer_size);
398 if (status)
399 return status;
400 }
401
402 checksum = (u16)IXGBE_EEPROM_SUM - checksum;
403
404 return (s32)checksum;
405}
406
407/** ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
408 * @hw: pointer to hardware structure
409 *
410 * Returns a negative error code on error, or the 16-bit checksum
411 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000412static s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000413{
414 return ixgbe_calc_checksum_X550(hw, NULL, 0);
415}
416
417/** ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
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_X550(struct ixgbe_hw *hw, u16 offset, u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000425{
426 s32 status = 0;
427
428 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
429 status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
430 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
431 } else {
432 status = IXGBE_ERR_SWFW_SYNC;
433 }
434
435 return status;
436}
437
438/** ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
439 * @hw: pointer to hardware structure
440 * @checksum_val: calculated checksum
441 *
442 * Performs checksum calculation and validates the EEPROM checksum. If the
443 * caller does not need checksum_val, the value can be NULL.
444 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000445static s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw,
446 u16 *checksum_val)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000447{
448 s32 status;
449 u16 checksum;
450 u16 read_checksum = 0;
451
452 /* Read the first word from the EEPROM. If this times out or fails, do
453 * not continue or we could be in for a very long wait while every
454 * EEPROM read fails
455 */
456 status = hw->eeprom.ops.read(hw, 0, &checksum);
457 if (status) {
458 hw_dbg(hw, "EEPROM read failed\n");
459 return status;
460 }
461
462 status = hw->eeprom.ops.calc_checksum(hw);
463 if (status < 0)
464 return status;
465
466 checksum = (u16)(status & 0xffff);
467
468 status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
469 &read_checksum);
470 if (status)
471 return status;
472
473 /* Verify read checksum from EEPROM is the same as
474 * calculated checksum
475 */
476 if (read_checksum != checksum) {
477 status = IXGBE_ERR_EEPROM_CHECKSUM;
478 hw_dbg(hw, "Invalid EEPROM checksum");
479 }
480
481 /* If the user cares, return the calculated checksum */
482 if (checksum_val)
483 *checksum_val = checksum;
484
485 return status;
486}
487
488/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
489 * @hw: pointer to hardware structure
490 * @offset: offset of word in the EEPROM to write
491 * @data: word write to the EEPROM
492 *
493 * Write a 16 bit word to the EEPROM using the hostif.
494 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000495static s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
496 u16 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000497{
498 s32 status;
499 struct ixgbe_hic_write_shadow_ram buffer;
500
501 buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
502 buffer.hdr.req.buf_lenh = 0;
503 buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
504 buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
505
506 /* one word */
507 buffer.length = cpu_to_be16(sizeof(u16));
508 buffer.data = data;
509 buffer.address = cpu_to_be32(offset * 2);
510
511 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
512 sizeof(buffer),
513 IXGBE_HI_COMMAND_TIMEOUT, false);
514 return status;
515}
516
517/** ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
518 * @hw: pointer to hardware structure
519 * @offset: offset of word in the EEPROM to write
520 * @data: word write to the EEPROM
521 *
522 * Write a 16 bit word to the EEPROM using the hostif.
523 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000524static s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, u16 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000525{
526 s32 status = 0;
527
528 if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
529 status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
530 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
531 } else {
532 hw_dbg(hw, "write ee hostif failed to get semaphore");
533 status = IXGBE_ERR_SWFW_SYNC;
534 }
535
536 return status;
537}
538
539/** ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
540 * @hw: pointer to hardware structure
541 *
542 * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
543 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000544static s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000545{
546 s32 status = 0;
547 union ixgbe_hic_hdr2 buffer;
548
549 buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
550 buffer.req.buf_lenh = 0;
551 buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
552 buffer.req.checksum = FW_DEFAULT_CHECKSUM;
553
554 status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
555 sizeof(buffer),
556 IXGBE_HI_COMMAND_TIMEOUT, false);
557 return status;
558}
559
560/** ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
561 * @hw: pointer to hardware structure
562 *
563 * After writing EEPROM to shadow RAM using EEWR register, software calculates
564 * checksum and updates the EEPROM and instructs the hardware to update
565 * the flash.
566 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000567static s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000568{
569 s32 status;
570 u16 checksum = 0;
571
572 /* Read the first word from the EEPROM. If this times out or fails, do
573 * not continue or we could be in for a very long wait while every
574 * EEPROM read fails
575 */
576 status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
577 if (status) {
578 hw_dbg(hw, "EEPROM read failed\n");
579 return status;
580 }
581
582 status = ixgbe_calc_eeprom_checksum_X550(hw);
583 if (status < 0)
584 return status;
585
586 checksum = (u16)(status & 0xffff);
587
588 status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
589 checksum);
590 if (status)
591 return status;
592
593 status = ixgbe_update_flash_X550(hw);
594
595 return status;
596}
597
598/** ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
599 * @hw: pointer to hardware structure
600 * @offset: offset of word in the EEPROM to write
601 * @words: number of words
602 * @data: word(s) write to the EEPROM
603 *
604 *
605 * Write a 16 bit word(s) to the EEPROM using the hostif.
606 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000607static s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
608 u16 offset, u16 words,
609 u16 *data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000610{
611 s32 status = 0;
612 u32 i = 0;
613
614 /* Take semaphore for the entire operation. */
615 status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
616 if (status) {
617 hw_dbg(hw, "EEPROM write buffer - semaphore failed\n");
618 return status;
619 }
620
621 for (i = 0; i < words; i++) {
622 status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
623 data[i]);
624 if (status) {
625 hw_dbg(hw, "Eeprom buffered write failed\n");
626 break;
627 }
628 }
629
630 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
631
632 return status;
633}
634
635/** ixgbe_init_mac_link_ops_X550em - init mac link function pointers
636 * @hw: pointer to hardware structure
637 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000638static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000639{
640 struct ixgbe_mac_info *mac = &hw->mac;
641
642 /* CS4227 does not support autoneg, so disable the laser control
643 * functions for SFP+ fiber
644 */
645 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
646 mac->ops.disable_tx_laser = NULL;
647 mac->ops.enable_tx_laser = NULL;
648 mac->ops.flap_tx_laser = NULL;
649 }
650}
651
652/** ixgbe_setup_sfp_modules_X550em - Setup SFP module
653 * @hw: pointer to hardware structure
654 */
Don Skidmore7ddbde32014-12-06 05:59:21 +0000655static s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000656{
657 bool setup_linear;
658 u16 reg_slice, edc_mode;
659 s32 ret_val;
660
661 switch (hw->phy.sfp_type) {
662 case ixgbe_sfp_type_unknown:
663 return 0;
664 case ixgbe_sfp_type_not_present:
665 return IXGBE_ERR_SFP_NOT_PRESENT;
666 case ixgbe_sfp_type_da_cu_core0:
667 case ixgbe_sfp_type_da_cu_core1:
668 setup_linear = true;
669 break;
670 case ixgbe_sfp_type_srlr_core0:
671 case ixgbe_sfp_type_srlr_core1:
672 case ixgbe_sfp_type_da_act_lmt_core0:
673 case ixgbe_sfp_type_da_act_lmt_core1:
674 case ixgbe_sfp_type_1g_sx_core0:
675 case ixgbe_sfp_type_1g_sx_core1:
676 setup_linear = false;
677 break;
678 default:
679 return IXGBE_ERR_SFP_NOT_SUPPORTED;
680 }
681
682 ixgbe_init_mac_link_ops_X550em(hw);
683 hw->phy.ops.reset = NULL;
684
685 /* The CS4227 slice address is the base address + the port-pair reg
686 * offset. I.e. Slice 0 = 0x12B0 and slice 1 = 0x22B0.
687 */
688 reg_slice = IXGBE_CS4227_SPARE24_LSB + (hw->bus.lan_id << 12);
689
690 if (setup_linear)
691 edc_mode = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
692 else
693 edc_mode = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
694
695 /* Configure CS4227 for connection type. */
696 ret_val = hw->phy.ops.write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
697 edc_mode);
698
699 if (ret_val)
700 ret_val = hw->phy.ops.write_i2c_combined(hw, 0x80, reg_slice,
701 edc_mode);
702
703 return ret_val;
704}
705
706/** ixgbe_get_link_capabilities_x550em - Determines link capabilities
707 * @hw: pointer to hardware structure
708 * @speed: pointer to link speed
709 * @autoneg: true when autoneg or autotry is enabled
710 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000711static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
712 ixgbe_link_speed *speed,
713 bool *autoneg)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000714{
715 /* SFP */
716 if (hw->phy.media_type == ixgbe_media_type_fiber) {
717 /* CS4227 SFP must not enable auto-negotiation */
718 *autoneg = false;
719
720 if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
721 hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
722 *speed = IXGBE_LINK_SPEED_1GB_FULL;
723 return 0;
724 }
725
726 /* Link capabilities are based on SFP */
727 if (hw->phy.multispeed_fiber)
728 *speed = IXGBE_LINK_SPEED_10GB_FULL |
729 IXGBE_LINK_SPEED_1GB_FULL;
730 else
731 *speed = IXGBE_LINK_SPEED_10GB_FULL;
732 } else {
733 *speed = IXGBE_LINK_SPEED_10GB_FULL |
734 IXGBE_LINK_SPEED_1GB_FULL;
735 *autoneg = true;
736 }
737 return 0;
738}
739
740/** ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the
741 * IOSF device
742 *
743 * @hw: pointer to hardware structure
744 * @reg_addr: 32 bit PHY register to write
745 * @device_type: 3 bit device type
746 * @data: Data to write to the register
747 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000748static s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
749 u32 device_type, u32 data)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000750{
751 u32 i, command, error;
752
753 command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
754 (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
755
756 /* Write IOSF control register */
757 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
758
759 /* Write IOSF data register */
760 IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
761
762 /* Check every 10 usec to see if the address cycle completed.
763 * The SB IOSF BUSY bit will clear when the operation is
764 * complete
765 */
766 for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
767 usleep_range(10, 20);
768
769 command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
770 if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
771 break;
772 }
773
774 if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
775 error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
776 IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
777 hw_dbg(hw, "Failed to write, error %x\n", error);
778 return IXGBE_ERR_PHY;
779 }
780
781 if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
782 hw_dbg(hw, "Write timed out\n");
783 return IXGBE_ERR_PHY;
784 }
785
786 return 0;
787}
788
789/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
790 * @hw: pointer to hardware structure
791 * @speed: the link speed to force
792 *
793 * Configures the integrated KR PHY to use iXFI mode. Used to connect an
794 * internal and external PHY at a specific speed, without autonegotiation.
795 **/
796static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
797{
798 s32 status;
799 u32 reg_val;
800
801 /* Disable AN and force speed to 10G Serial. */
802 status = ixgbe_read_iosf_sb_reg_x550(hw,
803 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
804 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
805 if (status)
806 return status;
807
808 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
809 reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
810
811 /* Select forced link speed for internal PHY. */
812 switch (*speed) {
813 case IXGBE_LINK_SPEED_10GB_FULL:
814 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
815 break;
816 case IXGBE_LINK_SPEED_1GB_FULL:
817 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
818 break;
819 default:
820 /* Other link speeds are not supported by internal KR PHY. */
821 return IXGBE_ERR_LINK_SETUP;
822 }
823
824 status = ixgbe_write_iosf_sb_reg_x550(hw,
825 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
826 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
827 if (status)
828 return status;
829
830 /* Disable training protocol FSM. */
831 status = ixgbe_read_iosf_sb_reg_x550(hw,
832 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
833 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
834 if (status)
835 return status;
836
837 reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
838 status = ixgbe_write_iosf_sb_reg_x550(hw,
839 IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
840 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
841 if (status)
842 return status;
843
844 /* Disable Flex from training TXFFE. */
845 status = ixgbe_read_iosf_sb_reg_x550(hw,
846 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
847 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
848 if (status)
849 return status;
850
851 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
852 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
853 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
854 status = ixgbe_write_iosf_sb_reg_x550(hw,
855 IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
856 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
857 if (status)
858 return status;
859
860 status = ixgbe_read_iosf_sb_reg_x550(hw,
861 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
862 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
863 if (status)
864 return status;
865
866 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
867 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
868 reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
869 status = ixgbe_write_iosf_sb_reg_x550(hw,
870 IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
871 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
872 if (status)
873 return status;
874
875 /* Enable override for coefficients. */
876 status = ixgbe_read_iosf_sb_reg_x550(hw,
877 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
878 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
879 if (status)
880 return status;
881
882 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
883 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
884 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
885 reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
886 status = ixgbe_write_iosf_sb_reg_x550(hw,
887 IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
888 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
889 if (status)
890 return status;
891
892 /* Toggle port SW reset by AN reset. */
893 status = ixgbe_read_iosf_sb_reg_x550(hw,
894 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
895 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
896 if (status)
897 return status;
898
899 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
900 status = ixgbe_write_iosf_sb_reg_x550(hw,
901 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
902 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
903
904 return status;
905}
906
907/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
908 * @hw: pointer to hardware structure
909 *
910 * Configures the integrated KX4 PHY.
911 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000912static s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000913{
914 s32 status;
915 u32 reg_val;
916
917 status = ixgbe_read_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
918 IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
919 hw->bus.lan_id, &reg_val);
920 if (status)
921 return status;
922
923 reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 |
924 IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX);
925
926 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE;
927
928 /* Advertise 10G support. */
929 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
930 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4;
931
932 /* Advertise 1G support. */
933 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
934 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX;
935
936 /* Restart auto-negotiation. */
937 reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART;
938 status = ixgbe_write_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
939 IXGBE_SB_IOSF_TARGET_KX4_PCS0 +
940 hw->bus.lan_id, reg_val);
941
942 return status;
943}
944
945/** ixgbe_setup_kr_x550em - Configure the KR PHY.
946 * @hw: pointer to hardware structure
947 *
948 * Configures the integrated KR PHY.
949 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000950static s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000951{
952 s32 status;
953 u32 reg_val;
954
955 status = ixgbe_read_iosf_sb_reg_x550(hw,
956 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
957 IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
958 if (status)
959 return status;
960
961 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
962 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ;
963 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
964 reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
965 IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
966
967 /* Advertise 10G support. */
968 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
969 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
970
971 /* Advertise 1G support. */
972 if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
973 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
974
975 /* Restart auto-negotiation. */
976 reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
977 status = ixgbe_write_iosf_sb_reg_x550(hw,
978 IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
979 IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
980
981 return status;
982}
983
984/** ixgbe_setup_internal_phy_x550em - Configure integrated KR PHY
985 * @hw: point to hardware structure
986 *
987 * Configures the integrated KR PHY to talk to the external PHY. The base
988 * driver will call this function when it gets notification via interrupt from
989 * the external PHY. This function forces the internal PHY into iXFI mode at
990 * the correct speed.
991 *
992 * A return of a non-zero value indicates an error, and the base driver should
993 * not report link up.
994 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +0000995static s32 ixgbe_setup_internal_phy_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +0000996{
997 u32 status;
998 u16 lasi, autoneg_status, speed;
999 ixgbe_link_speed force_speed;
1000
1001 /* Verify that the external link status has changed */
1002 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_XENPAK_LASI_STATUS,
1003 IXGBE_MDIO_PMA_PMD_DEV_TYPE, &lasi);
1004 if (status)
1005 return status;
1006
1007 /* If there was no change in link status, we can just exit */
1008 if (!(lasi & IXGBE_XENPAK_LASI_LINK_STATUS_ALARM))
1009 return 0;
1010
1011 /* we read this twice back to back to indicate current status */
1012 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1013 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1014 &autoneg_status);
1015 if (status)
1016 return status;
1017
1018 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
1019 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1020 &autoneg_status);
1021 if (status)
1022 return status;
1023
1024 /* If link is not up return an error indicating treat link as down */
1025 if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
1026 return IXGBE_ERR_INVALID_LINK_SETTINGS;
1027
1028 status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
1029 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
1030 &speed);
1031
1032 /* clear everything but the speed and duplex bits */
1033 speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
1034
1035 switch (speed) {
1036 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
1037 force_speed = IXGBE_LINK_SPEED_10GB_FULL;
1038 break;
1039 case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
1040 force_speed = IXGBE_LINK_SPEED_1GB_FULL;
1041 break;
1042 default:
1043 /* Internal PHY does not support anything else */
1044 return IXGBE_ERR_INVALID_LINK_SETTINGS;
1045 }
1046
1047 return ixgbe_setup_ixfi_x550em(hw, &force_speed);
1048}
1049
1050/** ixgbe_init_phy_ops_X550em - PHY/SFP specific init
1051 * @hw: pointer to hardware structure
1052 *
1053 * Initialize any function pointers that were not able to be
1054 * set during init_shared_code because the PHY/SFP type was
1055 * not known. Perform the SFP init if necessary.
1056 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00001057static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001058{
1059 struct ixgbe_phy_info *phy = &hw->phy;
1060 s32 ret_val;
1061 u32 esdp;
1062
1063 if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP) {
1064 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
1065 phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
1066
1067 if (hw->bus.lan_id) {
1068 esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
1069 esdp |= IXGBE_ESDP_SDP1_DIR;
1070 }
1071 esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
1072 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
1073 }
1074
1075 /* Identify the PHY or SFP module */
1076 ret_val = phy->ops.identify(hw);
1077
1078 /* Setup function pointers based on detected SFP module and speeds */
1079 ixgbe_init_mac_link_ops_X550em(hw);
1080 if (phy->sfp_type != ixgbe_sfp_type_unknown)
1081 phy->ops.reset = NULL;
1082
1083 /* Set functions pointers based on phy type */
1084 switch (hw->phy.type) {
1085 case ixgbe_phy_x550em_kx4:
1086 phy->ops.setup_link = ixgbe_setup_kx4_x550em;
1087 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
1088 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
1089 break;
1090 case ixgbe_phy_x550em_kr:
1091 phy->ops.setup_link = ixgbe_setup_kr_x550em;
1092 phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
1093 phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
1094 break;
1095 case ixgbe_phy_x550em_ext_t:
1096 phy->ops.setup_internal_link = ixgbe_setup_internal_phy_x550em;
1097 break;
1098 default:
1099 break;
1100 }
1101 return ret_val;
1102}
1103
1104/** ixgbe_get_media_type_X550em - Get media type
1105 * @hw: pointer to hardware structure
1106 *
1107 * Returns the media type (fiber, copper, backplane)
1108 *
1109 */
Don Skidmore7ddbde32014-12-06 05:59:21 +00001110static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001111{
1112 enum ixgbe_media_type media_type;
1113
1114 /* Detect if there is a copper PHY attached. */
1115 switch (hw->device_id) {
1116 case IXGBE_DEV_ID_X550EM_X_KR:
1117 case IXGBE_DEV_ID_X550EM_X_KX4:
1118 media_type = ixgbe_media_type_backplane;
1119 break;
1120 case IXGBE_DEV_ID_X550EM_X_SFP:
1121 media_type = ixgbe_media_type_fiber;
1122 break;
1123 case IXGBE_DEV_ID_X550EM_X_1G_T:
1124 case IXGBE_DEV_ID_X550EM_X_10G_T:
1125 media_type = ixgbe_media_type_copper;
1126 break;
1127 default:
1128 media_type = ixgbe_media_type_unknown;
1129 break;
1130 }
1131 return media_type;
1132}
1133
1134/** ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
1135 ** @hw: pointer to hardware structure
1136 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00001137static s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001138{
1139 u32 status;
1140 u16 reg;
1141 u32 retries = 2;
1142
1143 do {
1144 /* decrement retries counter and exit if we hit 0 */
1145 if (retries < 1) {
1146 hw_dbg(hw, "External PHY not yet finished resetting.");
1147 return IXGBE_ERR_PHY;
1148 }
1149 retries--;
1150
1151 status = hw->phy.ops.read_reg(hw,
1152 IXGBE_MDIO_TX_VENDOR_ALARMS_3,
1153 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1154 &reg);
1155 if (status)
1156 return status;
1157
1158 /* Verify PHY FW reset has completed */
1159 } while ((reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) != 1);
1160
1161 /* Set port to low power mode */
1162 status = hw->phy.ops.read_reg(hw,
1163 IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
1164 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1165 &reg);
1166 if (status)
1167 return status;
1168
1169 /* Enable the transmitter */
1170 status = hw->phy.ops.read_reg(hw,
1171 IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR,
1172 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1173 &reg);
1174 if (status)
1175 return status;
1176
1177 reg &= ~IXGBE_MDIO_PMD_GLOBAL_TX_DISABLE;
1178
1179 status = hw->phy.ops.write_reg(hw,
1180 IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR,
1181 IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1182 reg);
1183 if (status)
1184 return status;
1185
1186 /* Un-stall the PHY FW */
1187 status = hw->phy.ops.read_reg(hw,
1188 IXGBE_MDIO_GLOBAL_RES_PR_10,
1189 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1190 &reg);
1191 if (status)
1192 return status;
1193
1194 reg &= ~IXGBE_MDIO_POWER_UP_STALL;
1195
1196 status = hw->phy.ops.write_reg(hw,
1197 IXGBE_MDIO_GLOBAL_RES_PR_10,
1198 IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
1199 reg);
1200 return status;
1201}
1202
1203/** ixgbe_reset_hw_X550em - Perform hardware reset
1204 ** @hw: pointer to hardware structure
1205 **
1206 ** Resets the hardware by resetting the transmit and receive units, masks
1207 ** and clears all interrupts, perform a PHY reset, and perform a link (MAC)
1208 ** reset.
1209 **/
Don Skidmore7ddbde32014-12-06 05:59:21 +00001210static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
Don Skidmore6a14ee02014-12-05 03:59:50 +00001211{
1212 ixgbe_link_speed link_speed;
1213 s32 status;
1214 u32 ctrl = 0;
1215 u32 i;
1216 bool link_up = false;
1217
1218 /* Call adapter stop to disable Tx/Rx and clear interrupts */
1219 status = hw->mac.ops.stop_adapter(hw);
1220 if (status)
1221 return status;
1222
1223 /* flush pending Tx transactions */
1224 ixgbe_clear_tx_pending(hw);
1225
1226 /* PHY ops must be identified and initialized prior to reset */
1227
1228 /* Identify PHY and related function pointers */
1229 status = hw->phy.ops.init(hw);
1230
1231 /* start the external PHY */
1232 if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
1233 status = ixgbe_init_ext_t_x550em(hw);
1234 if (status)
1235 return status;
1236 }
1237
1238 /* Setup SFP module if there is one present. */
1239 if (hw->phy.sfp_setup_needed) {
1240 status = hw->mac.ops.setup_sfp(hw);
1241 hw->phy.sfp_setup_needed = false;
1242 }
1243
1244 /* Reset PHY */
1245 if (!hw->phy.reset_disable && hw->phy.ops.reset)
1246 hw->phy.ops.reset(hw);
1247
1248mac_reset_top:
1249 /* Issue global reset to the MAC. Needs to be SW reset if link is up.
1250 * If link reset is used when link is up, it might reset the PHY when
1251 * mng is using it. If link is down or the flag to force full link
1252 * reset is set, then perform link reset.
1253 */
1254 ctrl = IXGBE_CTRL_LNK_RST;
1255
1256 if (!hw->force_full_reset) {
1257 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
1258 if (link_up)
1259 ctrl = IXGBE_CTRL_RST;
1260 }
1261
1262 ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
1263 IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
1264 IXGBE_WRITE_FLUSH(hw);
1265
1266 /* Poll for reset bit to self-clear meaning reset is complete */
1267 for (i = 0; i < 10; i++) {
1268 udelay(1);
1269 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
1270 if (!(ctrl & IXGBE_CTRL_RST_MASK))
1271 break;
1272 }
1273
1274 if (ctrl & IXGBE_CTRL_RST_MASK) {
1275 status = IXGBE_ERR_RESET_FAILED;
1276 hw_dbg(hw, "Reset polling failed to complete.\n");
1277 }
1278
1279 msleep(50);
1280
1281 /* Double resets are required for recovery from certain error
1282 * clear the multicast table. Also reset num_rar_entries to 128,
1283 * since we modify this value when programming the SAN MAC address.
1284 */
1285 if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
1286 hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
1287 goto mac_reset_top;
1288 }
1289
1290 /* Store the permanent mac address */
1291 hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
1292
1293 /* Store MAC address from RAR0, clear receive address registers, and
1294 * clear the multicast table. Also reset num_rar_entries to 128,
1295 * since we modify this value when programming the SAN MAC address.
1296 */
1297 hw->mac.num_rar_entries = 128;
1298 hw->mac.ops.init_rx_addrs(hw);
1299
1300 return status;
1301}
1302
1303#define X550_COMMON_MAC \
1304 .init_hw = &ixgbe_init_hw_generic, \
1305 .start_hw = &ixgbe_start_hw_X540, \
1306 .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, \
1307 .enable_rx_dma = &ixgbe_enable_rx_dma_generic, \
1308 .get_mac_addr = &ixgbe_get_mac_addr_generic, \
1309 .get_device_caps = &ixgbe_get_device_caps_generic, \
1310 .stop_adapter = &ixgbe_stop_adapter_generic, \
1311 .get_bus_info = &ixgbe_get_bus_info_generic, \
1312 .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, \
1313 .read_analog_reg8 = NULL, \
1314 .write_analog_reg8 = NULL, \
1315 .set_rxpba = &ixgbe_set_rxpba_generic, \
1316 .check_link = &ixgbe_check_mac_link_generic, \
1317 .led_on = &ixgbe_led_on_generic, \
1318 .led_off = &ixgbe_led_off_generic, \
1319 .blink_led_start = &ixgbe_blink_led_start_X540, \
1320 .blink_led_stop = &ixgbe_blink_led_stop_X540, \
1321 .set_rar = &ixgbe_set_rar_generic, \
1322 .clear_rar = &ixgbe_clear_rar_generic, \
1323 .set_vmdq = &ixgbe_set_vmdq_generic, \
1324 .set_vmdq_san_mac = &ixgbe_set_vmdq_san_mac_generic, \
1325 .clear_vmdq = &ixgbe_clear_vmdq_generic, \
1326 .init_rx_addrs = &ixgbe_init_rx_addrs_generic, \
1327 .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, \
1328 .enable_mc = &ixgbe_enable_mc_generic, \
1329 .disable_mc = &ixgbe_disable_mc_generic, \
1330 .clear_vfta = &ixgbe_clear_vfta_generic, \
1331 .set_vfta = &ixgbe_set_vfta_generic, \
1332 .fc_enable = &ixgbe_fc_enable_generic, \
1333 .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, \
1334 .init_uta_tables = &ixgbe_init_uta_tables_generic, \
1335 .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \
1336 .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \
1337 .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540, \
1338 .release_swfw_sync = &ixgbe_release_swfw_sync_X540, \
1339 .disable_rx_buff = &ixgbe_disable_rx_buff_generic, \
1340 .enable_rx_buff = &ixgbe_enable_rx_buff_generic, \
1341 .get_thermal_sensor_data = NULL, \
1342 .init_thermal_sensor_thresh = NULL, \
1343 .prot_autoc_read = &prot_autoc_read_generic, \
1344 .prot_autoc_write = &prot_autoc_write_generic, \
1345
1346static struct ixgbe_mac_operations mac_ops_X550 = {
1347 X550_COMMON_MAC
1348 .reset_hw = &ixgbe_reset_hw_X540,
1349 .get_media_type = &ixgbe_get_media_type_X540,
1350 .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
1351 .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic,
1352 .setup_link = &ixgbe_setup_mac_link_X540,
1353 .set_rxpba = &ixgbe_set_rxpba_generic,
1354 .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic,
1355 .setup_sfp = NULL,
1356};
1357
1358static struct ixgbe_mac_operations mac_ops_X550EM_x = {
1359 X550_COMMON_MAC
1360 .reset_hw = &ixgbe_reset_hw_X550em,
1361 .get_media_type = &ixgbe_get_media_type_X550em,
1362 .get_san_mac_addr = NULL,
1363 .get_wwn_prefix = NULL,
1364 .setup_link = NULL, /* defined later */
1365 .get_link_capabilities = &ixgbe_get_link_capabilities_X550em,
1366 .setup_sfp = ixgbe_setup_sfp_modules_X550em,
1367
1368};
1369
1370#define X550_COMMON_EEP \
1371 .read = &ixgbe_read_ee_hostif_X550, \
1372 .read_buffer = &ixgbe_read_ee_hostif_buffer_X550, \
1373 .write = &ixgbe_write_ee_hostif_X550, \
1374 .write_buffer = &ixgbe_write_ee_hostif_buffer_X550, \
1375 .validate_checksum = &ixgbe_validate_eeprom_checksum_X550, \
1376 .update_checksum = &ixgbe_update_eeprom_checksum_X550, \
1377 .calc_checksum = &ixgbe_calc_eeprom_checksum_X550, \
1378
1379static struct ixgbe_eeprom_operations eeprom_ops_X550 = {
1380 X550_COMMON_EEP
1381 .init_params = &ixgbe_init_eeprom_params_X550,
1382};
1383
1384static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
1385 X550_COMMON_EEP
1386 .init_params = &ixgbe_init_eeprom_params_X540,
1387};
1388
1389#define X550_COMMON_PHY \
1390 .identify_sfp = &ixgbe_identify_module_generic, \
1391 .reset = NULL, \
1392 .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, \
1393 .read_i2c_byte = &ixgbe_read_i2c_byte_generic, \
1394 .write_i2c_byte = &ixgbe_write_i2c_byte_generic, \
1395 .read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic, \
1396 .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, \
1397 .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, \
1398 .check_overtemp = &ixgbe_tn_check_overtemp, \
1399 .get_firmware_version = &ixgbe_get_phy_firmware_version_generic,
1400
1401static struct ixgbe_phy_operations phy_ops_X550 = {
1402 X550_COMMON_PHY
1403 .init = NULL,
1404 .identify = &ixgbe_identify_phy_generic,
1405 .read_reg = &ixgbe_read_phy_reg_generic,
1406 .write_reg = &ixgbe_write_phy_reg_generic,
1407 .setup_link = &ixgbe_setup_phy_link_generic,
1408 .read_i2c_combined = &ixgbe_read_i2c_combined_generic,
1409 .write_i2c_combined = &ixgbe_write_i2c_combined_generic,
1410};
1411
1412static struct ixgbe_phy_operations phy_ops_X550EM_x = {
1413 X550_COMMON_PHY
1414 .init = &ixgbe_init_phy_ops_X550em,
1415 .identify = &ixgbe_identify_phy_x550em,
1416 .read_reg = NULL, /* defined later */
1417 .write_reg = NULL, /* defined later */
1418 .setup_link = NULL, /* defined later */
1419};
1420
1421struct ixgbe_info ixgbe_X550_info = {
1422 .mac = ixgbe_mac_X550,
1423 .get_invariants = &ixgbe_get_invariants_X540,
1424 .mac_ops = &mac_ops_X550,
1425 .eeprom_ops = &eeprom_ops_X550,
1426 .phy_ops = &phy_ops_X550,
1427 .mbx_ops = &mbx_ops_generic,
1428};
1429
1430struct ixgbe_info ixgbe_X550EM_x_info = {
1431 .mac = ixgbe_mac_X550EM_x,
1432 .get_invariants = &ixgbe_get_invariants_X540,
1433 .mac_ops = &mac_ops_X550EM_x,
1434 .eeprom_ops = &eeprom_ops_X550EM_x,
1435 .phy_ops = &phy_ops_X550EM_x,
1436 .mbx_ops = &mbx_ops_generic,
1437};