]> git.proxmox.com Git - mirror_edk2.git/commitdiff
EmbeddedPkg/Lan9118Dxe: add LAN9118 MMIO wrappers
authorMark Rutland <mark.rutland@arm.com>
Fri, 6 May 2016 17:19:07 +0000 (18:19 +0100)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 10 May 2016 12:48:48 +0000 (14:48 +0200)
As described in the LAN9118 datasheet, delays are necessary after some
reads and writes in order to ensure subsequent reads do not see stale
data.

This patch adds helpers to provide these delays automatically, by
performing dummy reads of the BYTE_TEST register (as recommended in the
LAN9118 datasheet). This approach allows the device register file itself
to provide the required delay, avoiding issues with early write
acknowledgement, or re-ordering of MMIO accesses aganist other
instructions (e.g. the delay loop).

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ryan Harkin <ryan.harkin@linaro.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeHw.h
EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.c
EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118DxeUtil.h

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