summaryrefslogtreecommitdiffstats
path: root/EmbeddedPkg/Drivers/Lan9118Dxe
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/Drivers/Lan9118Dxe')
-rw-r--r--EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h71
-rw-r--r--EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c48
-rw-r--r--EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h17
3 files changed, 136 insertions, 0 deletions
diff --git a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h
index 9e89d27459..11895849a4 100644
--- a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h
+++ b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h
@@ -57,6 +57,77 @@
#define LAN9118_E2P_CMD (0x000000B0 + LAN9118_BA) // EEPROM Command
#define LAN9118_E2P_DATA (0x000000B4 + LAN9118_BA) // EEPROM Data
+/*
+ * Required delays following write cycles (number of BYTE_TEST reads)
+ * Taken from Table 6.1 in Revision 1.5 (07-11-08) of the LAN9118 datasheet.
+ * Where no delay listed, 0 has been assumed.
+ */
+#define LAN9118_RX_DATA_WR_DELAY 0
+#define LAN9118_RX_STATUS_WR_DELAY 0
+#define LAN9118_RX_STATUS_PEEK_WR_DELAY 0
+#define LAN9118_TX_DATA_WR_DELAY 0
+#define LAN9118_TX_STATUS_WR_DELAY 0
+#define LAN9118_TX_STATUS_PEEK_WR_DELAY 0
+#define LAN9118_ID_REV_WR_DELAY 0
+#define LAN9118_IRQ_CFG_WR_DELAY 3
+#define LAN9118_INT_STS_WR_DELAY 2
+#define LAN9118_INT_EN_WR_DELAY 1
+#define LAN9118_BYTE_TEST_WR_DELAY 0
+#define LAN9118_FIFO_INT_WR_DELAY 1
+#define LAN9118_RX_CFG_WR_DELAY 1
+#define LAN9118_TX_CFG_WR_DELAY 1
+#define LAN9118_HW_CFG_WR_DELAY 1
+#define LAN9118_RX_DP_CTL_WR_DELAY 1
+#define LAN9118_RX_FIFO_INF_WR_DELAY 0
+#define LAN9118_TX_FIFO_INF_WR_DELAY 3
+#define LAN9118_PMT_CTRL_WR_DELAY 7
+#define LAN9118_GPIO_CFG_WR_DELAY 1
+#define LAN9118_GPT_CFG_WR_DELAY 1
+#define LAN9118_GPT_CNT_WR_DELAY 3
+#define LAN9118_WORD_SWAP_WR_DELAY 1
+#define LAN9118_FREE_RUN_WR_DELAY 4
+#define LAN9118_RX_DROP_WR_DELAY 0
+#define LAN9118_MAC_CSR_CMD_WR_DELAY 1
+#define LAN9118_MAC_CSR_DATA_WR_DELAY 1
+#define LAN9118_AFC_CFG_WR_DELAY 1
+#define LAN9118_E2P_CMD_WR_DELAY 1
+#define LAN9118_E2P_DATA_WR_DELAY 1
+
+/*
+ * Required delays following read cycles (number of BYTE_TEST reads)
+ * Taken from Table 6.2 in Revision 1.5 (07-11-08) of the LAN9118 datasheet.
+ * Where no delay listed, 0 has been assumed.
+ */
+#define LAN9118_RX_DATA_RD_DELAY 3
+#define LAN9118_RX_STATUS_RD_DELAY 3
+#define LAN9118_RX_STATUS_PEEK_RD_DELAY 0
+#define LAN9118_TX_DATA_RD_DELAY 0
+#define LAN9118_TX_STATUS_RD_DELAY 3
+#define LAN9118_TX_STATUS_PEEK_RD_DELAY 0
+#define LAN9118_ID_REV_RD_DELAY 0
+#define LAN9118_IRQ_CFG_RD_DELAY 0
+#define LAN9118_INT_STS_RD_DELAY 0
+#define LAN9118_INT_EN_RD_DELAY 0
+#define LAN9118_BYTE_TEST_RD_DELAY 0
+#define LAN9118_FIFO_INT_RD_DELAY 0
+#define LAN9118_RX_CFG_RD_DELAY 0
+#define LAN9118_TX_CFG_RD_DELAY 0
+#define LAN9118_HW_CFG_RD_DELAY 0
+#define LAN9118_RX_DP_CTL_RD_DELAY 0
+#define LAN9118_RX_FIFO_INF_RD_DELAY 0
+#define LAN9118_TX_FIFO_INF_RD_DELAY 0
+#define LAN9118_PMT_CTRL_RD_DELAY 0
+#define LAN9118_GPIO_CFG_RD_DELAY 0
+#define LAN9118_GPT_CFG_RD_DELAY 0
+#define LAN9118_GPT_CNT_RD_DELAY 0
+#define LAN9118_WORD_SWAP_RD_DELAY 0
+#define LAN9118_FREE_RUN_RD_DELAY 0
+#define LAN9118_RX_DROP_RD_DELAY 4
+#define LAN9118_MAC_CSR_CMD_RD_DELAY 0
+#define LAN9118_MAC_CSR_DATA_RD_DELAY 0
+#define LAN9118_AFC_CFG_RD_DELAY 0
+#define LAN9118_E2P_CMD_RD_DELAY 0
+#define LAN9118_E2P_DATA_RD_DELAY 0
// Receiver Status bits
#define RXSTATUS_CRC_ERROR BIT1 // Cyclic Redundancy Check Error
diff --git a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c
index bd20eebd04..002ea203ae 100644
--- a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c
+++ b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c
@@ -115,6 +115,54 @@ IndirectMACRead32 (
return MmioRead32 (LAN9118_MAC_CSR_DATA);
}
+/*
+ * LAN9118 chips have special restrictions on some back-to-back Write/Read or
+ * Read/Read pairs of accesses. After a read or write that changes the state of
+ * the device, there is a period in which stale values may be returned in
+ * response to a read. This period is dependent on the registers accessed.
+ *
+ * We must delay prior reads by this period. This can either be achieved by
+ * timer-based delays, or by performing dummy reads of the BYTE_TEST register,
+ * for which the recommended number of reads is described in the LAN9118 data
+ * sheet. This is required in addition to any memory barriers.
+ *
+ * This function performs a number of dummy reads of the BYTE_TEST register, as
+ * a building block for the above.
+ */
+VOID
+WaitDummyReads (
+ UINTN Count
+ )
+{
+ while (Count--)
+ MmioRead32(LAN9118_BYTE_TEST);
+}
+
+UINT32
+Lan9118RawMmioRead32(
+ UINTN Address,
+ UINTN Delay
+ )
+{
+ UINT32 Value;
+
+ Value = MmioRead32(Address);
+ WaitDummyReads(Delay);
+ return Value;
+}
+
+UINT32
+Lan9118RawMmioWrite32(
+ UINTN Address,
+ UINT32 Value,
+ UINTN Delay
+ )
+{
+ MmioWrite32(Address, Value);
+ WaitDummyReads(Delay);
+ return Value;
+}
+
// Function to write to MAC indirect registers
UINT32
IndirectMACWrite32 (
diff --git a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h
index 424bdc5a85..1a9a940082 100644
--- a/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h
+++ b/EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h
@@ -38,6 +38,23 @@ GenEtherCrc32 (
IN UINT32 AddrLen
);
+UINT32
+Lan9118RawMmioRead32(
+ UINTN Address,
+ UINTN Delay
+ );
+#define Lan9118MmioRead32(a) \
+ Lan9118RawMmioRead32(a, a ## _RD_DELAY)
+
+UINT32
+Lan9118RawMmioWrite32(
+ UINTN Address,
+ UINT32 Value,
+ UINTN Delay
+ );
+#define Lan9118MmioWrite32(a, v) \
+ Lan9118RawMmioWrite32(a, v, a ## _WR_DELAY)
+
/* ------------------ MAC CSR Access ------------------- */
// Read from MAC indirect registers