[dpdk-dev] [PATCH v1] Add support for I217 and I218 Intel 1G chipsets.

Jayakumar, Muthurajan muthurajan.jayakumar at intel.com
Fri Sep 25 01:31:11 CEST 2015


Thank you Ravi. 
This has great utility.
With all the latest laptop having this NIC in the chipset, the portability makes DPDK development on laptops very useful.
We have seen cases where with this patch, DPDK development and demonstration was very portable and beneficial for developers.

Kindly requesting to acknowledge  

Thanks, 
M Jay
-----Original Message-----
From: Ravi Kerur [mailto:rkerur at gmail.com] 
Sent: Thursday, September 24, 2015 3:15 PM
To: dev at dpdk.org
Cc: Jayakumar, Muthurajan; Ravi Kerur
Subject: [PATCH v1] Add support for I217 and I218 Intel 1G chipsets.

This patch adds I217 and I218 Intel chipsets.

Compiled for:
    > i686-native-linuxapp-gcc
    > x86_64-native-linuxapp-clang
    > x86_64-native-linuxapp-gcc
    > x86_x32-native-linuxapp-gcc

Tested on:
    > x86_64 Ubuntu 14.04 with Intel I218-V and I217-LM chipsets.

Signed-off-by: Ravi Kerur <rkerur at gmail.com>
---
 drivers/net/e1000/base/e1000_api.c              |  1 +
 drivers/net/e1000/base/e1000_hw.h               |  1 +
 drivers/net/e1000/base/e1000_ich8lan.c          | 30 +++++++-----------------
 drivers/net/e1000/base/e1000_osdep.h            | 24 +++++++++++++++----
 drivers/net/e1000/em_ethdev.c                   | 31 ++++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_pci_dev_ids.h |  6 +++++
 6 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c
index a064565..018a9a3 100644
--- a/drivers/net/e1000/base/e1000_api.c
+++ b/drivers/net/e1000/base/e1000_api.c
@@ -292,6 +292,7 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
 	case E1000_DEV_ID_PCH_LPT_I217_V:
 	case E1000_DEV_ID_PCH_LPTLP_I218_LM:
 	case E1000_DEV_ID_PCH_LPTLP_I218_V:
+	case E1000_DEV_ID_PCH_LPTLP_I218_V2:
 		mac->type = e1000_pch_lpt;
 		break;
 	case E1000_DEV_ID_82575EB_COPPER:
diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h
index 4dd92a3..c4b6212 100644
--- a/drivers/net/e1000/base/e1000_hw.h
+++ b/drivers/net/e1000/base/e1000_hw.h
@@ -132,6 +132,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_PCH_LPT_I217_V		0x153B
 #define E1000_DEV_ID_PCH_LPTLP_I218_LM		0x155A
 #define E1000_DEV_ID_PCH_LPTLP_I218_V		0x1559
+#define E1000_DEV_ID_PCH_LPTLP_I218_V2		0x15A1
 #define E1000_DEV_ID_82576			0x10C9
 #define E1000_DEV_ID_82576_FIBER		0x10E6
 #define E1000_DEV_ID_82576_SERDES		0x10E7
diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c
index 3b1627b..c7fa1ad 100644
--- a/drivers/net/e1000/base/e1000_ich8lan.c
+++ b/drivers/net/e1000/base/e1000_ich8lan.c
@@ -1386,29 +1386,15 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	if (!mac->get_link_status)
 		return E1000_SUCCESS;
 
-	if ((hw->mac.type < e1000_pch_lpt) ||
-	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) ||
-	    (hw->device_id == E1000_DEV_ID_PCH_LPT_I217_V)) {
-		/* First we want to see if the MII Status Register reports
-		 * link.  If so, then we want to get the current speed/duplex
-		 * of the PHY.
-		 */
-		ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
-		if (ret_val)
-			return ret_val;
-	} else {
-		/* Check the MAC's STATUS register to determine link state
-		 * since the PHY could be inaccessible while in ULP mode.
-		 */
-		link = !!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU);
-		if (link)
-			ret_val = e1000_disable_ulp_lpt_lp(hw, false);
-		else
-			ret_val = e1000_enable_ulp_lpt_lp(hw, false);
+	/* First we want to see if the MII Status Register reports
+	 * link.  If so, then we want to get the current speed/duplex
+	 * of the PHY.
+	 */
+	ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link);
+	if (ret_val)
+		return ret_val;
 
-		if (ret_val)
-			return ret_val;
-	}
+	DEBUGOUT1("After phy_has_link_generic link state is %d\n", link);
 
 	if (hw->mac.type == e1000_pchlan) {
 		ret_val = e1000_k1_gig_workaround_hv(hw, link); diff --git a/drivers/net/e1000/base/e1000_osdep.h b/drivers/net/e1000/base/e1000_osdep.h
index d04ec73..3255d37 100644
--- a/drivers/net/e1000/base/e1000_osdep.h
+++ b/drivers/net/e1000/base/e1000_osdep.h
@@ -96,13 +96,22 @@ typedef int		bool;
 
 #define E1000_PCI_REG(reg) (*((volatile uint32_t *)(reg)))
 
+#define E1000_PCI_REG16(reg) (*((volatile uint16_t *)(reg)))
+
 #define E1000_PCI_REG_WRITE(reg, value) do { \
 	E1000_PCI_REG((reg)) = (rte_cpu_to_le_32(value)); \  } while (0)
 
+#define E1000_PCI_REG_WRITE16(reg, value) do { \
+	E1000_PCI_REG16((reg)) = (value); \
+} while (0)
+
 #define E1000_PCI_REG_ADDR(hw, reg) \
 	((volatile uint32_t *)((char *)(hw)->hw_addr + (reg)))
 
+#define E1000_PCI_REG_FLASH_ADDR(hw, reg) \
+	((volatile uint32_t *)((char *)(hw)->flash_address + (reg)))
+
 #define E1000_PCI_REG_ARRAY_ADDR(hw, reg, index) \
 	E1000_PCI_REG_ADDR((hw), (reg) + ((index) << 2))
 
@@ -111,6 +120,11 @@ static inline uint32_t e1000_read_addr(volatile void* addr)
 	return rte_le_to_cpu_32(E1000_PCI_REG(addr));
 }
 
+static inline uint16_t e1000_read_addr16(volatile void* addr) {
+	return rte_le_to_cpu_16(E1000_PCI_REG16(addr));
+}
+
 /* Necessary defines */
 #define E1000_MRQC_ENABLE_MASK                  0x00000007
 #define E1000_MRQC_RSS_FIELD_IPV6_EX		0x00080000
@@ -156,20 +170,20 @@ static inline uint32_t e1000_read_addr(volatile void* addr)
 	E1000_WRITE_REG(hw, reg, value)
 
 /*
- * Not implemented.
+ * Tested on I217/I218 chipset.
  */
 
 #define E1000_READ_FLASH_REG(hw, reg) \
-	(E1000_ACCESS_PANIC(E1000_READ_FLASH_REG, hw, reg, 0), 0)
+	e1000_read_addr(E1000_PCI_REG_FLASH_ADDR((hw), (reg)))
 
 #define E1000_READ_FLASH_REG16(hw, reg)  \
-	(E1000_ACCESS_PANIC(E1000_READ_FLASH_REG16, hw, reg, 0), 0)
+	e1000_read_addr16(E1000_PCI_REG_FLASH_ADDR((hw), (reg)))
 
 #define E1000_WRITE_FLASH_REG(hw, reg, value)  \
-	E1000_ACCESS_PANIC(E1000_WRITE_FLASH_REG, hw, reg, value)
+	E1000_PCI_REG_WRITE(E1000_PCI_REG_FLASH_ADDR((hw), (reg)), (value))
 
 #define E1000_WRITE_FLASH_REG16(hw, reg, value) \
-	E1000_ACCESS_PANIC(E1000_WRITE_FLASH_REG16, hw, reg, value)
+	E1000_PCI_REG_WRITE16(E1000_PCI_REG_FLASH_ADDR((hw), (reg)), (value))
 
 #define STATIC static
 
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c index 912f5dd..1f7015e 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -220,6 +220,28 @@ rte_em_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/**
+ *  eth_em_dev_is_ich8 - Check for ICH8 device
+ *  @hw: pointer to the HW structure
+ *
+ *  return TRUE for ICH8, otherwise FALSE  **/ static bool 
+eth_em_dev_is_ich8(struct e1000_hw *hw) {
+	DEBUGFUNC("eth_em_dev_is_ich8");
+	switch (hw->device_id) {
+	case E1000_DEV_ID_PCH_LPT_I217_LM:
+	case E1000_DEV_ID_PCH_LPT_I217_V:
+	case E1000_DEV_ID_PCH_LPTLP_I218_LM:
+	case E1000_DEV_ID_PCH_LPTLP_I218_V:
+	case E1000_DEV_ID_PCH_LPTLP_I218_V2:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static int
 eth_em_dev_init(struct rte_eth_dev *eth_dev)  { @@ -251,6 +273,8 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
 	adapter->stopped = 0;
 
 	/* For ICH8 support we'll need to map the flash memory BAR */
+	if (eth_em_dev_is_ich8(hw))
+		hw->flash_address = (void *)pci_dev->mem_resource[1].addr;
 
 	if (e1000_setup_init_funcs(hw, TRUE) != E1000_SUCCESS ||
 			em_hw_init(hw) != 0) {
@@ -476,6 +500,7 @@ em_set_pba(struct e1000_hw *hw)
 			break;
 		case e1000_pchlan:
 		case e1000_pch2lan:
+		case e1000_pch_lpt:
 			pba = E1000_PBA_26K;
 			break;
 		default:
@@ -724,7 +749,8 @@ em_hardware_init(struct e1000_hw *hw)
 		hw->fc.requested_mode = e1000_fc_none;
 
 	/* Workaround: no TX flow ctrl for PCH */
-	if (hw->mac.type == e1000_pchlan)
+	if (hw->mac.type == e1000_pchlan ||
+		hw->mac.type == e1000_pch_lpt)
 		hw->fc.requested_mode = e1000_fc_rx_pause;
 
 	/* Override - settings for PCH2LAN, ya its magic :) */ @@ -733,6 +759,8 @@ em_hardware_init(struct e1000_hw *hw)
 		hw->fc.low_water = 0x5048;
 		hw->fc.pause_time = 0x0650;
 		hw->fc.refresh_time = 0x0400;
+	} else if (hw->mac.type == e1000_pch_lpt) {
+		hw->fc.requested_mode = e1000_fc_full;
 	}
 
 	diag = e1000_init_hw(hw);
@@ -891,6 +919,7 @@ em_get_max_pktlen(const struct e1000_hw *hw)
 	case e1000_ich9lan:
 	case e1000_ich10lan:
 	case e1000_pch2lan:
+	case e1000_pch_lpt:
 	case e1000_82574:
 	case e1000_80003es2lan: /* 9K Jumbo Frame size */
 	case e1000_82583:
diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index cf2cf70..e0d69e8 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -272,6 +272,7 @@
 #define E1000_DEV_ID_PCH_LPT_I217_V           0x153B
 #define E1000_DEV_ID_PCH_LPTLP_I218_LM	      0x155A
 #define E1000_DEV_ID_PCH_LPTLP_I218_V	      0x1559
+#define E1000_DEV_ID_PCH_LPTLP_I218_V2	      0x15A1
 
 /*
  * Tested (supported) on VM emulated HW.
@@ -305,6 +306,11 @@ RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, E1000_DEV_ID_82573L)  RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, E1000_DEV_ID_82574L)  RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, E1000_DEV_ID_82574LA)  RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, E1000_DEV_ID_82583V)
+RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, 
+E1000_DEV_ID_PCH_LPT_I217_LM) 
+RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, 
+E1000_DEV_ID_PCH_LPT_I217_V) 
+RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, 
+E1000_DEV_ID_PCH_LPTLP_I218_LM) 
+RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, 
+E1000_DEV_ID_PCH_LPTLP_I218_V) 
+RTE_PCI_DEV_ID_DECL_EM(PCI_VENDOR_ID_INTEL, 
+E1000_DEV_ID_PCH_LPTLP_I218_V2)
 
 /******************** Physical IGB devices from e1000_hw.h ********************/
 
--
1.9.1



More information about the dev mailing list