@@ -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:
@@ -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
@@ -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);
@@ -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
@@ -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:
@@ -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 ********************/