diff options
author | Akeem G. Abodunrin <akeem.g.abodunrin@intel.com> | 2013-04-24 12:54:50 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-05-21 05:37:36 -0400 |
commit | 641ac5c0cd46919dc9be4c933f95edae1e4e4163 (patch) | |
tree | 619b915cb706cd74cb0057b7dbf6a9e215906d4d /drivers/net/ethernet/intel/igb | |
parent | 20a48412281732ddb75e0ac7d9e0b5406f1b6669 (diff) |
igb: Support for SFP modules discovery
This patch adds support for SFP modules media type discovery for
SGMII, which will enable driver to detect supported external PHYs,
including 100baseFXSFP module.
Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb')
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_82575.c | 120 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_defines.h | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_phy.c | 124 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_phy.h | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 34 |
6 files changed, 291 insertions, 39 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index ff6a17cb1362..f21a91a299a2 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -401,12 +401,82 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw) | |||
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | /** | ||
405 | * igb_set_sfp_media_type_82575 - derives SFP module media type. | ||
406 | * @hw: pointer to the HW structure | ||
407 | * | ||
408 | * The media type is chosen based on SFP module. | ||
409 | * compatibility flags retrieved from SFP ID EEPROM. | ||
410 | **/ | ||
411 | static s32 igb_set_sfp_media_type_82575(struct e1000_hw *hw) | ||
412 | { | ||
413 | s32 ret_val = E1000_ERR_CONFIG; | ||
414 | u32 ctrl_ext = 0; | ||
415 | struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; | ||
416 | struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags; | ||
417 | u8 tranceiver_type = 0; | ||
418 | s32 timeout = 3; | ||
419 | |||
420 | /* Turn I2C interface ON and power on sfp cage */ | ||
421 | ctrl_ext = rd32(E1000_CTRL_EXT); | ||
422 | ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA; | ||
423 | wr32(E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA); | ||
424 | |||
425 | wrfl(); | ||
426 | |||
427 | /* Read SFP module data */ | ||
428 | while (timeout) { | ||
429 | ret_val = igb_read_sfp_data_byte(hw, | ||
430 | E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET), | ||
431 | &tranceiver_type); | ||
432 | if (ret_val == 0) | ||
433 | break; | ||
434 | msleep(100); | ||
435 | timeout--; | ||
436 | } | ||
437 | if (ret_val != 0) | ||
438 | goto out; | ||
439 | |||
440 | ret_val = igb_read_sfp_data_byte(hw, | ||
441 | E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET), | ||
442 | (u8 *)eth_flags); | ||
443 | if (ret_val != 0) | ||
444 | goto out; | ||
445 | |||
446 | /* Check if there is some SFP module plugged and powered */ | ||
447 | if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) || | ||
448 | (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) { | ||
449 | dev_spec->module_plugged = true; | ||
450 | if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) { | ||
451 | hw->phy.media_type = e1000_media_type_internal_serdes; | ||
452 | } else if (eth_flags->e100_base_fx) { | ||
453 | dev_spec->sgmii_active = true; | ||
454 | hw->phy.media_type = e1000_media_type_internal_serdes; | ||
455 | } else if (eth_flags->e1000_base_t) { | ||
456 | dev_spec->sgmii_active = true; | ||
457 | hw->phy.media_type = e1000_media_type_copper; | ||
458 | } else { | ||
459 | hw->phy.media_type = e1000_media_type_unknown; | ||
460 | hw_dbg("PHY module has not been recognized\n"); | ||
461 | goto out; | ||
462 | } | ||
463 | } else { | ||
464 | hw->phy.media_type = e1000_media_type_unknown; | ||
465 | } | ||
466 | ret_val = 0; | ||
467 | out: | ||
468 | /* Restore I2C interface setting */ | ||
469 | wr32(E1000_CTRL_EXT, ctrl_ext); | ||
470 | return ret_val; | ||
471 | } | ||
472 | |||
404 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) | 473 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) |
405 | { | 474 | { |
406 | struct e1000_mac_info *mac = &hw->mac; | 475 | struct e1000_mac_info *mac = &hw->mac; |
407 | struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575; | 476 | struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575; |
408 | s32 ret_val; | 477 | s32 ret_val; |
409 | u32 ctrl_ext = 0; | 478 | u32 ctrl_ext = 0; |
479 | u32 link_mode = 0; | ||
410 | 480 | ||
411 | switch (hw->device_id) { | 481 | switch (hw->device_id) { |
412 | case E1000_DEV_ID_82575EB_COPPER: | 482 | case E1000_DEV_ID_82575EB_COPPER: |
@@ -470,16 +540,56 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
470 | */ | 540 | */ |
471 | hw->phy.media_type = e1000_media_type_copper; | 541 | hw->phy.media_type = e1000_media_type_copper; |
472 | dev_spec->sgmii_active = false; | 542 | dev_spec->sgmii_active = false; |
543 | dev_spec->module_plugged = false; | ||
473 | 544 | ||
474 | ctrl_ext = rd32(E1000_CTRL_EXT); | 545 | ctrl_ext = rd32(E1000_CTRL_EXT); |
475 | switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) { | 546 | |
476 | case E1000_CTRL_EXT_LINK_MODE_SGMII: | 547 | link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK; |
477 | dev_spec->sgmii_active = true; | 548 | switch (link_mode) { |
478 | break; | ||
479 | case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: | 549 | case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: |
480 | case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: | ||
481 | hw->phy.media_type = e1000_media_type_internal_serdes; | 550 | hw->phy.media_type = e1000_media_type_internal_serdes; |
482 | break; | 551 | break; |
552 | case E1000_CTRL_EXT_LINK_MODE_SGMII: | ||
553 | /* Get phy control interface type set (MDIO vs. I2C)*/ | ||
554 | if (igb_sgmii_uses_mdio_82575(hw)) { | ||
555 | hw->phy.media_type = e1000_media_type_copper; | ||
556 | dev_spec->sgmii_active = true; | ||
557 | break; | ||
558 | } | ||
559 | /* fall through for I2C based SGMII */ | ||
560 | case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: | ||
561 | /* read media type from SFP EEPROM */ | ||
562 | ret_val = igb_set_sfp_media_type_82575(hw); | ||
563 | if ((ret_val != 0) || | ||
564 | (hw->phy.media_type == e1000_media_type_unknown)) { | ||
565 | /* If media type was not identified then return media | ||
566 | * type defined by the CTRL_EXT settings. | ||
567 | */ | ||
568 | hw->phy.media_type = e1000_media_type_internal_serdes; | ||
569 | |||
570 | if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) { | ||
571 | hw->phy.media_type = e1000_media_type_copper; | ||
572 | dev_spec->sgmii_active = true; | ||
573 | } | ||
574 | |||
575 | break; | ||
576 | } | ||
577 | |||
578 | /* do not change link mode for 100BaseFX */ | ||
579 | if (dev_spec->eth_flags.e100_base_fx) | ||
580 | break; | ||
581 | |||
582 | /* change current link mode setting */ | ||
583 | ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK; | ||
584 | |||
585 | if (hw->phy.media_type == e1000_media_type_copper) | ||
586 | ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII; | ||
587 | else | ||
588 | ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; | ||
589 | |||
590 | wr32(E1000_CTRL_EXT, ctrl_ext); | ||
591 | |||
592 | break; | ||
483 | default: | 593 | default: |
484 | break; | 594 | break; |
485 | } | 595 | } |
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index aa176490ddbc..aa201abb8ad2 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h | |||
@@ -61,20 +61,22 @@ | |||
61 | /* Clear Interrupt timers after IMS clear */ | 61 | /* Clear Interrupt timers after IMS clear */ |
62 | /* packet buffer parity error detection enabled */ | 62 | /* packet buffer parity error detection enabled */ |
63 | /* descriptor FIFO parity error detection enable */ | 63 | /* descriptor FIFO parity error detection enable */ |
64 | #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ | 64 | #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ |
65 | #define E1000_I2CCMD_REG_ADDR_SHIFT 16 | 65 | #define E1000_I2CCMD_REG_ADDR_SHIFT 16 |
66 | #define E1000_I2CCMD_PHY_ADDR_SHIFT 24 | 66 | #define E1000_I2CCMD_PHY_ADDR_SHIFT 24 |
67 | #define E1000_I2CCMD_OPCODE_READ 0x08000000 | 67 | #define E1000_I2CCMD_OPCODE_READ 0x08000000 |
68 | #define E1000_I2CCMD_OPCODE_WRITE 0x00000000 | 68 | #define E1000_I2CCMD_OPCODE_WRITE 0x00000000 |
69 | #define E1000_I2CCMD_READY 0x20000000 | 69 | #define E1000_I2CCMD_READY 0x20000000 |
70 | #define E1000_I2CCMD_ERROR 0x80000000 | 70 | #define E1000_I2CCMD_ERROR 0x80000000 |
71 | #define E1000_MAX_SGMII_PHY_REG_ADDR 255 | 71 | #define E1000_I2CCMD_SFP_DATA_ADDR(a) (0x0000 + (a)) |
72 | #define E1000_I2CCMD_PHY_TIMEOUT 200 | 72 | #define E1000_I2CCMD_SFP_DIAG_ADDR(a) (0x0100 + (a)) |
73 | #define E1000_IVAR_VALID 0x80 | 73 | #define E1000_MAX_SGMII_PHY_REG_ADDR 255 |
74 | #define E1000_GPIE_NSICR 0x00000001 | 74 | #define E1000_I2CCMD_PHY_TIMEOUT 200 |
75 | #define E1000_GPIE_MSIX_MODE 0x00000010 | 75 | #define E1000_IVAR_VALID 0x80 |
76 | #define E1000_GPIE_EIAME 0x40000000 | 76 | #define E1000_GPIE_NSICR 0x00000001 |
77 | #define E1000_GPIE_PBA 0x80000000 | 77 | #define E1000_GPIE_MSIX_MODE 0x00000010 |
78 | #define E1000_GPIE_EIAME 0x40000000 | ||
79 | #define E1000_GPIE_PBA 0x80000000 | ||
78 | 80 | ||
79 | /* Receive Descriptor bit definitions */ | 81 | /* Receive Descriptor bit definitions */ |
80 | #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ | 82 | #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ |
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h index 488abb24a54f..94d7866b9c20 100644 --- a/drivers/net/ethernet/intel/igb/e1000_hw.h +++ b/drivers/net/ethernet/intel/igb/e1000_hw.h | |||
@@ -528,6 +528,8 @@ struct e1000_dev_spec_82575 { | |||
528 | bool global_device_reset; | 528 | bool global_device_reset; |
529 | bool eee_disable; | 529 | bool eee_disable; |
530 | bool clear_semaphore_once; | 530 | bool clear_semaphore_once; |
531 | struct e1000_sfp_flags eth_flags; | ||
532 | bool module_plugged; | ||
531 | }; | 533 | }; |
532 | 534 | ||
533 | struct e1000_hw { | 535 | struct e1000_hw { |
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index 115b0da6e013..1d6a401cc5d4 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c | |||
@@ -341,6 +341,130 @@ s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) | |||
341 | } | 341 | } |
342 | 342 | ||
343 | /** | 343 | /** |
344 | * igb_read_sfp_data_byte - Reads SFP module data. | ||
345 | * @hw: pointer to the HW structure | ||
346 | * @offset: byte location offset to be read | ||
347 | * @data: read data buffer pointer | ||
348 | * | ||
349 | * Reads one byte from SFP module data stored | ||
350 | * in SFP resided EEPROM memory or SFP diagnostic area. | ||
351 | * Function should be called with | ||
352 | * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access | ||
353 | * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters | ||
354 | * access | ||
355 | **/ | ||
356 | s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data) | ||
357 | { | ||
358 | u32 i = 0; | ||
359 | u32 i2ccmd = 0; | ||
360 | u32 data_local = 0; | ||
361 | |||
362 | if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) { | ||
363 | hw_dbg("I2CCMD command address exceeds upper limit\n"); | ||
364 | return -E1000_ERR_PHY; | ||
365 | } | ||
366 | |||
367 | /* Set up Op-code, EEPROM Address,in the I2CCMD | ||
368 | * register. The MAC will take care of interfacing with the | ||
369 | * EEPROM to retrieve the desired data. | ||
370 | */ | ||
371 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
372 | E1000_I2CCMD_OPCODE_READ); | ||
373 | |||
374 | wr32(E1000_I2CCMD, i2ccmd); | ||
375 | |||
376 | /* Poll the ready bit to see if the I2C read completed */ | ||
377 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
378 | udelay(50); | ||
379 | data_local = rd32(E1000_I2CCMD); | ||
380 | if (data_local & E1000_I2CCMD_READY) | ||
381 | break; | ||
382 | } | ||
383 | if (!(data_local & E1000_I2CCMD_READY)) { | ||
384 | hw_dbg("I2CCMD Read did not complete\n"); | ||
385 | return -E1000_ERR_PHY; | ||
386 | } | ||
387 | if (data_local & E1000_I2CCMD_ERROR) { | ||
388 | hw_dbg("I2CCMD Error bit set\n"); | ||
389 | return -E1000_ERR_PHY; | ||
390 | } | ||
391 | *data = (u8) data_local & 0xFF; | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * e1000_write_sfp_data_byte - Writes SFP module data. | ||
398 | * @hw: pointer to the HW structure | ||
399 | * @offset: byte location offset to write to | ||
400 | * @data: data to write | ||
401 | * | ||
402 | * Writes one byte to SFP module data stored | ||
403 | * in SFP resided EEPROM memory or SFP diagnostic area. | ||
404 | * Function should be called with | ||
405 | * E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access | ||
406 | * E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters | ||
407 | * access | ||
408 | **/ | ||
409 | s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data) | ||
410 | { | ||
411 | u32 i = 0; | ||
412 | u32 i2ccmd = 0; | ||
413 | u32 data_local = 0; | ||
414 | |||
415 | if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) { | ||
416 | hw_dbg("I2CCMD command address exceeds upper limit\n"); | ||
417 | return -E1000_ERR_PHY; | ||
418 | } | ||
419 | /* The programming interface is 16 bits wide | ||
420 | * so we need to read the whole word first | ||
421 | * then update appropriate byte lane and write | ||
422 | * the updated word back. | ||
423 | */ | ||
424 | /* Set up Op-code, EEPROM Address,in the I2CCMD | ||
425 | * register. The MAC will take care of interfacing | ||
426 | * with an EEPROM to write the data given. | ||
427 | */ | ||
428 | i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
429 | E1000_I2CCMD_OPCODE_READ); | ||
430 | /* Set a command to read single word */ | ||
431 | wr32(E1000_I2CCMD, i2ccmd); | ||
432 | for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { | ||
433 | udelay(50); | ||
434 | /* Poll the ready bit to see if lastly | ||
435 | * launched I2C operation completed | ||
436 | */ | ||
437 | i2ccmd = rd32(E1000_I2CCMD); | ||
438 | if (i2ccmd & E1000_I2CCMD_READY) { | ||
439 | /* Check if this is READ or WRITE phase */ | ||
440 | if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) == | ||
441 | E1000_I2CCMD_OPCODE_READ) { | ||
442 | /* Write the selected byte | ||
443 | * lane and update whole word | ||
444 | */ | ||
445 | data_local = i2ccmd & 0xFF00; | ||
446 | data_local |= data; | ||
447 | i2ccmd = ((offset << | ||
448 | E1000_I2CCMD_REG_ADDR_SHIFT) | | ||
449 | E1000_I2CCMD_OPCODE_WRITE | data_local); | ||
450 | wr32(E1000_I2CCMD, i2ccmd); | ||
451 | } else { | ||
452 | break; | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | if (!(i2ccmd & E1000_I2CCMD_READY)) { | ||
457 | hw_dbg("I2CCMD Write did not complete\n"); | ||
458 | return -E1000_ERR_PHY; | ||
459 | } | ||
460 | if (i2ccmd & E1000_I2CCMD_ERROR) { | ||
461 | hw_dbg("I2CCMD Error bit set\n"); | ||
462 | return -E1000_ERR_PHY; | ||
463 | } | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /** | ||
344 | * igb_read_phy_reg_igp - Read igp PHY register | 468 | * igb_read_phy_reg_igp - Read igp PHY register |
345 | * @hw: pointer to the HW structure | 469 | * @hw: pointer to the HW structure |
346 | * @offset: register offset to be read | 470 | * @offset: register offset to be read |
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h index 784fd1c40989..6a0873f2095a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.h +++ b/drivers/net/ethernet/intel/igb/e1000_phy.h | |||
@@ -69,6 +69,8 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); | |||
69 | s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); | 69 | s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); |
70 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); | 70 | s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data); |
71 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); | 71 | s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data); |
72 | s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data); | ||
73 | s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data); | ||
72 | s32 igb_copper_link_setup_82580(struct e1000_hw *hw); | 74 | s32 igb_copper_link_setup_82580(struct e1000_hw *hw); |
73 | s32 igb_get_phy_info_82580(struct e1000_hw *hw); | 75 | s32 igb_get_phy_info_82580(struct e1000_hw *hw); |
74 | s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw); | 76 | s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw); |
@@ -157,4 +159,22 @@ s32 igb_check_polarity_m88(struct e1000_hw *hw); | |||
157 | #define GS40G_CS_POWER_DOWN 0x0002 | 159 | #define GS40G_CS_POWER_DOWN 0x0002 |
158 | #define GS40G_LINE_LB 0x4000 | 160 | #define GS40G_LINE_LB 0x4000 |
159 | 161 | ||
162 | /* SFP modules ID memory locations */ | ||
163 | #define E1000_SFF_IDENTIFIER_OFFSET 0x00 | ||
164 | #define E1000_SFF_IDENTIFIER_SFF 0x02 | ||
165 | #define E1000_SFF_IDENTIFIER_SFP 0x03 | ||
166 | |||
167 | #define E1000_SFF_ETH_FLAGS_OFFSET 0x06 | ||
168 | /* Flags for SFP modules compatible with ETH up to 1Gb */ | ||
169 | struct e1000_sfp_flags { | ||
170 | u8 e1000_base_sx:1; | ||
171 | u8 e1000_base_lx:1; | ||
172 | u8 e1000_base_cx:1; | ||
173 | u8 e1000_base_t:1; | ||
174 | u8 e100_base_lx:1; | ||
175 | u8 e100_base_fx:1; | ||
176 | u8 e10_base_bx10:1; | ||
177 | u8 e10_base_px:1; | ||
178 | }; | ||
179 | |||
160 | #endif | 180 | #endif |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 7876240fa74e..4e54f847ac92 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -142,6 +142,8 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
142 | { | 142 | { |
143 | struct igb_adapter *adapter = netdev_priv(netdev); | 143 | struct igb_adapter *adapter = netdev_priv(netdev); |
144 | struct e1000_hw *hw = &adapter->hw; | 144 | struct e1000_hw *hw = &adapter->hw; |
145 | struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; | ||
146 | struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags; | ||
145 | u32 status; | 147 | u32 status; |
146 | 148 | ||
147 | if (hw->phy.media_type == e1000_media_type_copper) { | 149 | if (hw->phy.media_type == e1000_media_type_copper) { |
@@ -181,30 +183,22 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
181 | ecmd->phy_address = hw->phy.addr; | 183 | ecmd->phy_address = hw->phy.addr; |
182 | ecmd->transceiver = XCVR_INTERNAL; | 184 | ecmd->transceiver = XCVR_INTERNAL; |
183 | } else { | 185 | } else { |
184 | ecmd->supported = (SUPPORTED_1000baseT_Full | | 186 | ecmd->supported = (SUPPORTED_FIBRE | |
185 | SUPPORTED_100baseT_Full | | ||
186 | SUPPORTED_FIBRE | | ||
187 | SUPPORTED_Autoneg | | 187 | SUPPORTED_Autoneg | |
188 | SUPPORTED_Pause); | 188 | SUPPORTED_Pause); |
189 | if (hw->mac.type == e1000_i354) | ||
190 | ecmd->supported |= SUPPORTED_2500baseX_Full; | ||
191 | |||
192 | ecmd->advertising = ADVERTISED_FIBRE; | 189 | ecmd->advertising = ADVERTISED_FIBRE; |
193 | 190 | if (hw->mac.type == e1000_i354) { | |
194 | switch (adapter->link_speed) { | 191 | ecmd->supported |= SUPPORTED_2500baseX_Full; |
195 | case SPEED_2500: | 192 | ecmd->advertising |= ADVERTISED_2500baseX_Full; |
196 | ecmd->advertising = ADVERTISED_2500baseX_Full; | 193 | } |
197 | break; | 194 | if ((eth_flags->e1000_base_lx) || (eth_flags->e1000_base_sx)) { |
198 | case SPEED_1000: | 195 | ecmd->supported |= SUPPORTED_1000baseT_Full; |
199 | ecmd->advertising = ADVERTISED_1000baseT_Full; | 196 | ecmd->advertising |= ADVERTISED_1000baseT_Full; |
200 | break; | 197 | } |
201 | case SPEED_100: | 198 | if (eth_flags->e100_base_fx) { |
202 | ecmd->advertising = ADVERTISED_100baseT_Full; | 199 | ecmd->supported |= SUPPORTED_100baseT_Full; |
203 | break; | 200 | ecmd->advertising |= ADVERTISED_100baseT_Full; |
204 | default: | ||
205 | break; | ||
206 | } | 201 | } |
207 | |||
208 | if (hw->mac.autoneg == 1) | 202 | if (hw->mac.autoneg == 1) |
209 | ecmd->advertising |= ADVERTISED_Autoneg; | 203 | ecmd->advertising |= ADVERTISED_Autoneg; |
210 | 204 | ||