Skip to contentSkip to conversation

ixgbe: Firmware-controlled PHY enablement

PATCH Superseded Mark D Rustad 2 participants 6 messages Dec 13, 2016

Subsystems (2)

v6 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v6 cover ixgbe: Firmware-controlled PHY enablement

The following patches enable firmware-controlled PHYs. The first two patches resolve some issues uncovered while working on the other patches. The third adds the firmware interface for controlling PHYs. The last patch implements everything else for the new devices.

---
Changes in V2:
- Fixed some oversights related to the 10M link speed Changes in V3:
- Use correct ops for LED control
Changes in V4:
- Actually get the V3 changes into the patch. Sorry for the error. Changes in V5:
- Properly indicate FC autoneg support
Changes in V6:
- Add missing thermal interrupt support

---

Mark D Rustad (4):
ixgbe: Fix issues with EEPROM access
ixgbe: Remove unused firmware version functions and method
ixgbe: Implement firmware interface to access some PHYs
ixgbe: Implement support for firmware-controlled PHYs

 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c   |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c   |    2 
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c  |  106 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h  |    3 
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |  156 ++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |   64 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c     |   37 --
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h     |    4 
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |   74 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c    |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c    |  529 ++++++++++++++++++++--
 12 files changed, 849 insertions(+), 133 deletions(-)
Signature · 1 line
Mark Rustad, Network Division, Intel Corporation
#1 lore raw

PATCH v6 1/4 ixgbe: Fix issues with EEPROM access

There are two problems with EEPROM access. One is that it needs to hold the semaphore until the entire response is read or else the response can be corrupted by other firmware accesses. The second problem is that acquiring and releasing the semaphore is slow, so it should be taken and released once when multiple EEPROM accesses will be done.

Both of these issues can be solved by adding a new function, ixgbe_hic_unlocked, to issue firmware commands that will assume that the caller has acquired the needed semaphore.

---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |   97 +++++++++++++++--------
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    1 
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c   |   75 +++++++-----------
 3 files changed, 91 insertions(+), 82 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +62 -35
index 8832df3eba25..743be6af49fb 100644
@@ -3593,43 +3593,29 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
 }
 
 /**
- *  ixgbe_host_interface_command - Issue command to manageability block
+ *  ixgbe_hic_unlocked - Issue command to manageability block unlocked
  *  @hw: pointer to the HW structure
- *  @buffer: contains the command to write and where the return status will
- *           be placed
+ *  @buffer: command to write and where the return status will be placed
  *  @length: length of buffer, must be multiple of 4 bytes
  *  @timeout: time in ms to wait for command completion
- *  @return_data: read and return data from the buffer (true) or not (false)
- *  Needed because FW structures are big endian and decoding of
- *  these fields can be 8 bit or 16 bit based on command. Decoding
- *  is not easily understood without making a table of commands.
- *  So we will leave this up to the caller to read back the data
- *  in these cases.
  *
- *  Communicates with the manageability block.  On success return 0
- *  else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
+ *  Communicates with the manageability block. On success return 0
+ *  else returns semaphore error when encountering an error acquiring
+ *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
+ *
+ *  This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held
+ *  by the caller.
  **/
-s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer,
-				 u32 length, u32 timeout,
-				 bool return_data)
+s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length,
+		       u32 timeout)
 {
-	u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
-	u32 hicr, i, bi, fwsts;
-	u16 buf_len, dword_len;
-	union {
-		struct ixgbe_hic_hdr hdr;
-		u32 u32arr[1];
-	} *bp = buffer;
-	s32 status;
+	u32 hicr, i, fwsts;
+	u16 dword_len;
 
 	if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
 		hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
 		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
 	}
-	/* Take management host interface semaphore */
-	status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
-	if (status)
-		return status;
 
 	/* Set bit 9 of FWSTS clearing FW reset indication */
 	fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
@@ -3639,15 +3625,13 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer,
 	hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
 	if (!(hicr & IXGBE_HICR_EN)) {
 		hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n");
-		status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-		goto rel_out;
+		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
 	}
 
 	/* Calculate length in DWORDs. We must be DWORD aligned */
 	if (length % sizeof(u32)) {
 		hw_dbg(hw, "Buffer length failure, not aligned to dword");
-		status = IXGBE_ERR_INVALID_ARGUMENT;
-		goto rel_out;
+		return IXGBE_ERR_INVALID_ARGUMENT;
 	}
 
 	dword_len = length >> 2;
@@ -3657,7 +3641,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer,
 	 */
 	for (i = 0; i < dword_len; i++)
 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_FLEX_MNG,
-				      i, cpu_to_le32(bp->u32arr[i]));
+				      i, cpu_to_le32(buffer[i]));
 
 	/* Setting this bit tells the ARC that a new command is pending. */
 	IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
@@ -3671,11 +3655,54 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer,
 
 	/* Check command successful completion. */
 	if ((timeout && i == timeout) ||
-	    !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
-		hw_dbg(hw, "Command has failed with no status valid.\n");
-		status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-		goto rel_out;
+	    !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))
+		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
+
+	return 0;
+}
+
+/**
+ *  ixgbe_host_interface_command - Issue command to manageability block
+ *  @hw: pointer to the HW structure
+ *  @buffer: contains the command to write and where the return status will
+ *           be placed
+ *  @length: length of buffer, must be multiple of 4 bytes
+ *  @timeout: time in ms to wait for command completion
+ *  @return_data: read and return data from the buffer (true) or not (false)
+ *  Needed because FW structures are big endian and decoding of
+ *  these fields can be 8 bit or 16 bit based on command. Decoding
+ *  is not easily understood without making a table of commands.
+ *  So we will leave this up to the caller to read back the data
+ *  in these cases.
+ *
+ *  Communicates with the manageability block.  On success return 0
+ *  else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
+ **/
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer,
+				 u32 length, u32 timeout,
+				 bool return_data)
+{
+	u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
+	union {
+		struct ixgbe_hic_hdr hdr;
+		u32 u32arr[1];
+	} *bp = buffer;
+	u16 buf_len, dword_len;
+	s32 status;
+	u32 bi;
+
+	if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
+		hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
+		return IXGBE_ERR_HOST_INTERFACE_COMMAND;
 	}
+	/* Take management host interface semaphore */
+	status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
+	if (status)
+		return status;
+
+	status = ixgbe_hic_unlocked(hw, buffer, length, timeout);
+	if (status)
+		goto rel_out;
 
 	if (!return_data)
 		goto rel_out;
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +1 -0
index 5b3e3c65927e..1d3434ce3ddc 100644
@@ -114,6 +114,7 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
 				 u8 build, u8 ver);
 s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *, u32 length,
 				 u32 timeout, bool return_data);
+s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 len, u32 timeout);
 void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
 bool ixgbe_mng_present(struct ixgbe_hw *hw);
 bool ixgbe_mng_enabled(struct ixgbe_hw *hw);
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +28 -47

114 lines not on this page · raw message

#2 lore raw

PATCH v6 1/4 ixgbe: Fix issues with EEPROM access

Quoted 11 lines · Mark D Rustad

There are two problems with EEPROM access. One is that it needs to hold the semaphore until the entire response is read or else the response can be corrupted by other firmware accesses. The second problem is that acquiring and releasing the semaphore is slow, so it should be taken and released once when multiple EEPROM accesses will be done.

Both of these issues can be solved by adding a new function, ixgbe_hic_unlocked, to issue firmware commands that will assume that the caller has acquired the needed semaphore.

Quoted 8 lines

---
?drivers/net/ethernet/intel/ixgbe/ixgbe_common.c |?? 97 +++++++++++++++
--------
?drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |??? 1? ?drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c?? |?? 75 +++++++--------
---
?3 files changed, 91 insertions(+), 82 deletions(-)

I am unable to apply the first patch of the series:

?Applying .apply/V6-1-4-ixgbe-Fix-issues-with-EEPROM-access.patch ... Checking for changes in the working directory ... done Importing patch "V6-1-4-ixgbe-Fix-issues-with-EEPROM-access.patch" ...
error: patch failed: drivers/net/ethernet/intel/ixgbe/ixgbe_common.h:114
error: drivers/net/ethernet/intel/ixgbe/ixgbe_common.h: patch does not apply
stg import: Diff does not apply cleanly

Looks like, v7 is needed to update the patches so they will actually apply
to my next-queue tree (please make sure you are using my dev-queue branch). -------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20161213/1d0b75ed/attachment.asc>

#3 lore raw

PATCH v6 2/4 ixgbe: Remove unused firmware version functions and method

In reply to Mark D Rustad

The firmware version method and functions are not used anywhere, so remove them all.

---
 drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c |    2 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c |    2 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c   |   34 ------------------------
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h   |    4 ---
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |    1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c  |    1 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c  |    3 +-
 7 files changed, 1 insertion(+), 46 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +0 -2
index 805ab319e578..523f9d05a810 100644
@@ -139,8 +139,6 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
 	case ixgbe_phy_tn:
 		phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
 		phy->ops.check_link = &ixgbe_check_phy_link_tnx;
-		phy->ops.get_firmware_version =
-			     &ixgbe_get_phy_firmware_version_tnx;
 		break;
 	case ixgbe_phy_nl:
 		phy->ops.reset = &ixgbe_reset_phy_nl;
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +0 -2
index e00aaeb91827..30535e6b68f0 100644
@@ -331,8 +331,6 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
 	case ixgbe_phy_tn:
 		phy->ops.check_link = &ixgbe_check_phy_link_tnx;
 		phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
-		phy->ops.get_firmware_version =
-			     &ixgbe_get_phy_firmware_version_tnx;
 		break;
 	default:
 		break;
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +0 -34
index 3b8362085f57..65b527928c92 100644
@@ -960,40 +960,6 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
- *  @hw: pointer to hardware structure
- *  @firmware_version: pointer to the PHY Firmware Version
- **/
-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
-				       u16 *firmware_version)
-{
-	s32 status;
-
-	status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
-				      MDIO_MMD_VEND1,
-				      firmware_version);
-
-	return status;
-}
-
-/**
- *  ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version
- *  @hw: pointer to hardware structure
- *  @firmware_version: pointer to the PHY Firmware Version
- **/
-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
-					   u16 *firmware_version)
-{
-	s32 status;
-
-	status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
-				      MDIO_MMD_VEND1,
-				      firmware_version);
-
-	return status;
-}
-
-/**
  *  ixgbe_reset_phy_nl - Performs a PHY reset
  *  @hw: pointer to hardware structure
  **/
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +0 -4
index ecf05f838fc5..5aa2c3cf7aec 100644
@@ -168,10 +168,6 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
 			     ixgbe_link_speed *speed,
 			     bool *link_up);
 s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw);
-s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
-				       u16 *firmware_version);
-s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
-					   u16 *firmware_version);
 
 s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw);
 s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on);
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +0 -1
index cf21273db201..3898458ab264 100644
@@ -3392,7 +3392,6 @@ struct ixgbe_phy_operations {
 	s32 (*setup_internal_link)(struct ixgbe_hw *);
 	s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool);
 	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
-	s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
 	s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
 	s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
 	s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +0 -1
index e2ff823ee202..72049fa23616 100644
@@ -913,7 +913,6 @@ static const struct ixgbe_phy_operations phy_ops_X540 = {
 	.write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic,
 	.check_overtemp         = &ixgbe_tn_check_overtemp,
 	.set_phy_power          = &ixgbe_set_copper_phy_power,
-	.get_firmware_version   = &ixgbe_get_phy_firmware_version_generic,
 };
 
 static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = {
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +1 -2
index acb2be945215..23365d287080 100644
@@ -3366,8 +3366,7 @@ static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
 	.write_i2c_eeprom	= &ixgbe_write_i2c_eeprom_generic, \
 	.setup_link		= &ixgbe_setup_phy_link_generic, \
 	.set_phy_power		= NULL, \
-	.check_overtemp		= &ixgbe_tn_check_overtemp, \
-	.get_firmware_version	= &ixgbe_get_phy_firmware_version_generic,
+	.check_overtemp		= &ixgbe_tn_check_overtemp,
 
 static const struct ixgbe_phy_operations phy_ops_X550 = {
 	X550_COMMON_PHY
#4 lore raw

PATCH v6 3/4 ixgbe: Implement firmware interface to access some PHYs

In reply to Mark D Rustad

Implement new interface for firmware commands to access some PHYs.

---
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.h |    2 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h   |   66 +++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c   |   45 ++++++++++++++++
 3 files changed, 113 insertions(+)
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +2 -0
index 1d3434ce3ddc..95fb4cfaccc6 100644
@@ -115,6 +115,8 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
 s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *, u32 length,
 				 u32 timeout, bool return_data);
 s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 len, u32 timeout);
+s32 ixgbe_fw_phy_activity(struct ixgbe_hw *hw, u16 activity,
+			  u32 (*data)[FW_PHY_ACT_DATA_COUNT]);
 void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
 bool ixgbe_mng_present(struct ixgbe_hw *hw);
 bool ixgbe_mng_enabled(struct ixgbe_hw *hw);
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +66 -0

78 lines not on this page · raw message

drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +45 -0

51 lines not on this page · raw message

#5 lore raw

PATCH v6 4/4 ixgbe: Implement support for firmware-controlled PHYs

In reply to Mark D Rustad

Implement support for devices that have firmware-controlled PHYs.

---
Changes in V2:
- Fixed some oversights primarily related to 10M support Changes in V3:
- Use the correct ops to blink the LED
Changes in V4:
- Actually get the right content into the patch Changes in V5:
- Properly indicate FC autoneg support
Changes in V6:
- Add missing thermal interrupt support

---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c  |    9 
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |  156 ++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |   64 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c     |    3 
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |    7 
 drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c    |  408 ++++++++++++++++++++++
 7 files changed, 645 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +4 -0
index ef81c3d8c295..53fb427b1c29 100644
@@ -661,6 +661,8 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_PHY_INTERRUPT		BIT(11)
 #define IXGBE_FLAG2_UDP_TUN_REREG_NEEDED	BIT(12)
 #define IXGBE_FLAG2_VLAN_PROMISC		BIT(13)
+#define IXGBE_FLAG2_EEE_CAPABLE			BIT(14)
+#define IXGBE_FLAG2_EEE_ENABLED			BIT(15)
 
 	/* Tx fast path data */
 	int num_tx_queues;
@@ -862,6 +864,7 @@ enum ixgbe_boards {
 	board_X550,
 	board_X550EM_x,
 	board_x550em_a,
+	board_x550em_a_fw,
 };
 
 extern const struct ixgbe_info ixgbe_82598_info;
@@ -870,6 +873,7 @@ extern const struct ixgbe_info ixgbe_X540_info;
 extern const struct ixgbe_info ixgbe_X550_info;
 extern const struct ixgbe_info ixgbe_X550EM_x_info;
 extern const struct ixgbe_info ixgbe_x550em_a_info;
+extern const struct ixgbe_info ixgbe_x550em_a_fw_info;
 #ifdef CONFIG_IXGBE_DCB
 extern const struct dcbnl_rtnl_ops dcbnl_ops;
 #endif
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +9 -0
index 743be6af49fb..18dc591a290a 100644
@@ -100,6 +100,8 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
 		case IXGBE_DEV_ID_X550T1:
 		case IXGBE_DEV_ID_X550EM_X_10G_T:
 		case IXGBE_DEV_ID_X550EM_A_10G_T:
+		case IXGBE_DEV_ID_X550EM_A_1G_T:
+		case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 			supported = true;
 			break;
 		default:
@@ -3382,6 +3384,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 		else
 			*speed = IXGBE_LINK_SPEED_100_FULL;
 		break;
+	case IXGBE_LINKS_SPEED_10_X550EM_A:
+		*speed = IXGBE_LINK_SPEED_UNKNOWN;
+		if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
+		    hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
+			*speed = IXGBE_LINK_SPEED_10_FULL;
+		}
+		break;
 	default:
 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
 	}
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +153 -3

216 lines not on this page · raw message

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +64 -0

136 lines not on this page · raw message

drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +3 -0
index 65b527928c92..6c9cb8657d19 100644
@@ -767,6 +767,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
 	if (speed & IXGBE_LINK_SPEED_100_FULL)
 		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
 
+	if (speed & IXGBE_LINK_SPEED_10_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10_FULL;
+
 	/* Setup link based on the new speed settings */
 	hw->phy.ops.setup_link(hw);
 
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +7 -0
index 69cb6c10eb03..42813fc94f4a 100644
@@ -92,6 +92,8 @@
 #define IXGBE_DEV_ID_X550EM_A_SGMII_L	0x15C7
 #define IXGBE_DEV_ID_X550EM_A_10G_T	0x15C8
 #define IXGBE_DEV_ID_X550EM_A_SFP	0x15CE
+#define IXGBE_DEV_ID_X550EM_A_1G_T	0x15E4
+#define IXGBE_DEV_ID_X550EM_A_1G_T_L	0x15E5
 
 /* VF Device IDs */
 #define IXGBE_DEV_ID_82599_VF		0x10ED
@@ -1914,6 +1916,7 @@ enum {
 #define IXGBE_LINKS_SPEED_10G_82599 0x30000000
 #define IXGBE_LINKS_SPEED_1G_82599  0x20000000
 #define IXGBE_LINKS_SPEED_100_82599 0x10000000
+#define IXGBE_LINKS_SPEED_10_X550EM_A 0
 #define IXGBE_LINK_UP_TIME      90 /* 9.0 Seconds */
 #define IXGBE_AUTO_NEG_TIME     45 /* 4.5 Seconds */
 
@@ -2915,6 +2918,7 @@ typedef u32 ixgbe_autoneg_advertised;
 /* Link speed */
 typedef u32 ixgbe_link_speed;
 #define IXGBE_LINK_SPEED_UNKNOWN	0
+#define IXGBE_LINK_SPEED_10_FULL	0x0002
 #define IXGBE_LINK_SPEED_100_FULL	0x0008
 #define IXGBE_LINK_SPEED_1GB_FULL	0x0020
 #define IXGBE_LINK_SPEED_2_5GB_FULL	0x0400
@@ -3130,6 +3134,7 @@ enum ixgbe_phy_type {
 	ixgbe_phy_qsfp_unknown,
 	ixgbe_phy_sfp_unsupported,
 	ixgbe_phy_sgmii,
+	ixgbe_phy_fw,
 	ixgbe_phy_generic
 };
 
@@ -3543,6 +3548,8 @@ struct ixgbe_phy_info {
 	bool                            reset_disable;
 	ixgbe_autoneg_advertised        autoneg_advertised;
 	ixgbe_link_speed		speeds_supported;
+	ixgbe_link_speed		eee_speeds_supported;
+	ixgbe_link_speed		eee_speeds_advertised;
 	enum ixgbe_smart_speed          smart_speed;
 	bool                            smart_speed_active;
 	bool                            multispeed_fiber;
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +405 -3

504 lines not on this page · raw message