EmbeddedPkg/Lan9118Dxe: use MemoryFence

When reviewing my LAN9118 driver PCD patch [1], Ard Biesheuvel noted
that most calls to gBS->Stall() in this driver seem to be used to
prevent timing issues between the device updating data and the host
reading the values.  And that replacing most of these calls with a
MemoryFence() would be more robust.

The only exceptions are the stalls that are enclosed inside retry loops:

 - in the AutoNegotiate() function.
   This stall is waiting for the link to negotiate, which may require
   stalling until it is ready.

 - in the Lan9118Initialize() function.
   These two stalls are waiting for devices and time out after a number
   of retries.

 - in the SoftReset() function.
   This stall is inside a loop where the comment states:
   "If time taken exceeds 100us, then there was an error condition"

In these instances, I kept the stall, but also added a MemoryFence().

[1] http://article.gmane.org/gmane.comp.bios.edk2.devel/7389

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ryan Harkin <ryan.harkin@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
This commit is contained in:
Ryan Harkin 2016-02-09 08:52:32 +00:00 committed by Ard Biesheuvel
parent 7d0f92e8fd
commit a4626006bb
2 changed files with 26 additions and 23 deletions

View File

@ -307,8 +307,7 @@ SnpInitialize (
// Write the current configuration to the register // Write the current configuration to the register
MmioWrite32 (LAN9118_PMT_CTRL, PmConf); MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
gBS->Stall (LAN9118_STALL); MemoryFence();
gBS->Stall (LAN9118_STALL);
// Configure GPIO and HW // Configure GPIO and HW
Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp); Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp);
@ -431,7 +430,7 @@ SnpReset (
// Write the current configuration to the register // Write the current configuration to the register
MmioWrite32 (LAN9118_PMT_CTRL, PmConf); MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
gBS->Stall (LAN9118_STALL); MemoryFence();
// Reactivate the LEDs // Reactivate the LEDs
Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp); Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp);
@ -446,7 +445,7 @@ SnpReset (
HwConf |= HW_CFG_TX_FIFO_SIZE(gTxBuffer); // assign size chosen in SnpInitialize HwConf |= HW_CFG_TX_FIFO_SIZE(gTxBuffer); // assign size chosen in SnpInitialize
MmioWrite32 (LAN9118_HW_CFG, HwConf); // Write the conf MmioWrite32 (LAN9118_HW_CFG, HwConf); // Write the conf
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
// Enable the receiver and transmitter and clear their contents // Enable the receiver and transmitter and clear their contents
@ -701,7 +700,7 @@ SnpReceiveFilters (
// Write the options to the MAC_CSR // Write the options to the MAC_CSR
// //
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCSRValue); IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCSRValue);
gBS->Stall (LAN9118_STALL); MemoryFence();
// //
// If we have to retrieve something, start packet reception. // If we have to retrieve something, start packet reception.

View File

@ -236,7 +236,7 @@ IndirectEEPROMRead32 (
// Write to Eeprom command register // Write to Eeprom command register
MmioWrite32 (LAN9118_E2P_CMD, EepromCmd); MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
gBS->Stall (LAN9118_STALL); MemoryFence();
// Wait until operation has completed // Wait until operation has completed
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY); while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
@ -284,7 +284,7 @@ IndirectEEPROMWrite32 (
// Write to Eeprom command register // Write to Eeprom command register
MmioWrite32 (LAN9118_E2P_CMD, EepromCmd); MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
gBS->Stall (LAN9118_STALL); MemoryFence();
// Wait until operation has completed // Wait until operation has completed
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY); while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
@ -362,13 +362,14 @@ Lan9118Initialize (
if (((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PM_MODE_MASK) >> 12) != 0) { if (((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PM_MODE_MASK) >> 12) != 0) {
DEBUG ((DEBUG_NET, "Waking from reduced power state.\n")); DEBUG ((DEBUG_NET, "Waking from reduced power state.\n"));
MmioWrite32 (LAN9118_BYTE_TEST, 0xFFFFFFFF); MmioWrite32 (LAN9118_BYTE_TEST, 0xFFFFFFFF);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
// Check that device is active // Check that device is active
Timeout = 20; Timeout = 20;
while ((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_READY) == 0 && --Timeout) { while ((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_READY) == 0 && --Timeout) {
gBS->Stall (LAN9118_STALL); gBS->Stall (LAN9118_STALL);
MemoryFence();
} }
if (!Timeout) { if (!Timeout) {
return EFI_TIMEOUT; return EFI_TIMEOUT;
@ -378,6 +379,7 @@ Lan9118Initialize (
Timeout = 20; Timeout = 20;
while ((MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY) && --Timeout){ while ((MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY) && --Timeout){
gBS->Stall (LAN9118_STALL); gBS->Stall (LAN9118_STALL);
MemoryFence();
} }
if (!Timeout) { if (!Timeout) {
return EFI_TIMEOUT; return EFI_TIMEOUT;
@ -447,11 +449,12 @@ SoftReset (
// Write the configuration // Write the configuration
MmioWrite32 (LAN9118_HW_CFG, HwConf); MmioWrite32 (LAN9118_HW_CFG, HwConf);
gBS->Stall (LAN9118_STALL); MemoryFence();
// Wait for reset to complete // Wait for reset to complete
while (MmioRead32 (LAN9118_HW_CFG) & HWCFG_SRST) { while (MmioRead32 (LAN9118_HW_CFG) & HWCFG_SRST) {
MemoryFence();
gBS->Stall (LAN9118_STALL); gBS->Stall (LAN9118_STALL);
ResetTime += 1; ResetTime += 1;
@ -500,7 +503,7 @@ PhySoftReset (
// Wait for completion // Wait for completion
while (MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PHY_RST) { while (MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PHY_RST) {
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
// PHY Basic Control Register reset // PHY Basic Control Register reset
} else if (Flags & PHY_RESET_BCR) { } else if (Flags & PHY_RESET_BCR) {
@ -508,7 +511,7 @@ PhySoftReset (
// Wait for completion // Wait for completion
while (IndirectPHYRead32 (PHY_INDEX_BASIC_CTRL) & PHYCR_RESET) { while (IndirectPHYRead32 (PHY_INDEX_BASIC_CTRL) & PHYCR_RESET) {
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
} }
@ -542,7 +545,7 @@ ConfigureHardware (
// Write the configuration // Write the configuration
MmioWrite32 (LAN9118_GPIO_CFG, GpioConf); MmioWrite32 (LAN9118_GPIO_CFG, GpioConf);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -585,6 +588,7 @@ AutoNegotiate (
// Wait until it is up or until Time Out // Wait until it is up or until Time Out
TimeOut = 2000; TimeOut = 2000;
while ((IndirectPHYRead32 (PHY_INDEX_BASIC_STATUS) & PHYSTS_LINK_STS) == 0) { while ((IndirectPHYRead32 (PHY_INDEX_BASIC_STATUS) & PHYSTS_LINK_STS) == 0) {
MemoryFence();
gBS->Stall (LAN9118_STALL); gBS->Stall (LAN9118_STALL);
TimeOut--; TimeOut--;
if (!TimeOut) { if (!TimeOut) {
@ -671,7 +675,7 @@ StopTx (
TxCfg = MmioRead32 (LAN9118_TX_CFG); TxCfg = MmioRead32 (LAN9118_TX_CFG);
TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP; TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP;
MmioWrite32 (LAN9118_TX_CFG, TxCfg); MmioWrite32 (LAN9118_TX_CFG, TxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
// Check if already stopped // Check if already stopped
@ -690,7 +694,7 @@ StopTx (
if (TxCfg & TXCFG_TX_ON) { if (TxCfg & TXCFG_TX_ON) {
TxCfg |= TXCFG_STOP_TX; TxCfg |= TXCFG_STOP_TX;
MmioWrite32 (LAN9118_TX_CFG, TxCfg); MmioWrite32 (LAN9118_TX_CFG, TxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
// Wait for Tx to finish transmitting // Wait for Tx to finish transmitting
while (MmioRead32 (LAN9118_TX_CFG) & TXCFG_STOP_TX); while (MmioRead32 (LAN9118_TX_CFG) & TXCFG_STOP_TX);
@ -725,7 +729,7 @@ StopRx (
RxCfg = MmioRead32 (LAN9118_RX_CFG); RxCfg = MmioRead32 (LAN9118_RX_CFG);
RxCfg |= RXCFG_RX_DUMP; RxCfg |= RXCFG_RX_DUMP;
MmioWrite32 (LAN9118_RX_CFG, RxCfg); MmioWrite32 (LAN9118_RX_CFG, RxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP); while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
} }
@ -751,28 +755,28 @@ StartTx (
TxCfg = MmioRead32 (LAN9118_TX_CFG); TxCfg = MmioRead32 (LAN9118_TX_CFG);
TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP; TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP;
MmioWrite32 (LAN9118_TX_CFG, TxCfg); MmioWrite32 (LAN9118_TX_CFG, TxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
// Check if tx was started from MAC and enable if not // Check if tx was started from MAC and enable if not
if (Flags & START_TX_MAC) { if (Flags & START_TX_MAC) {
MacCsr = IndirectMACRead32 (INDIRECT_MAC_INDEX_CR); MacCsr = IndirectMACRead32 (INDIRECT_MAC_INDEX_CR);
gBS->Stall (LAN9118_STALL); MemoryFence();
if ((MacCsr & MACCR_TX_EN) == 0) { if ((MacCsr & MACCR_TX_EN) == 0) {
MacCsr |= MACCR_TX_EN; MacCsr |= MACCR_TX_EN;
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr); IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
} }
// Check if tx was started from TX_CFG and enable if not // Check if tx was started from TX_CFG and enable if not
if (Flags & START_TX_CFG) { if (Flags & START_TX_CFG) {
TxCfg = MmioRead32 (LAN9118_TX_CFG); TxCfg = MmioRead32 (LAN9118_TX_CFG);
gBS->Stall (LAN9118_STALL); MemoryFence();
if ((TxCfg & TXCFG_TX_ON) == 0) { if ((TxCfg & TXCFG_TX_ON) == 0) {
TxCfg |= TXCFG_TX_ON; TxCfg |= TXCFG_TX_ON;
MmioWrite32 (LAN9118_TX_CFG, TxCfg); MmioWrite32 (LAN9118_TX_CFG, TxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
} }
@ -802,14 +806,14 @@ StartRx (
RxCfg = MmioRead32 (LAN9118_RX_CFG); RxCfg = MmioRead32 (LAN9118_RX_CFG);
RxCfg |= RXCFG_RX_DUMP; RxCfg |= RXCFG_RX_DUMP;
MmioWrite32 (LAN9118_RX_CFG, RxCfg); MmioWrite32 (LAN9118_RX_CFG, RxCfg);
gBS->Stall (LAN9118_STALL); MemoryFence();
while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP); while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
} }
MacCsr |= MACCR_RX_EN; MacCsr |= MACCR_RX_EN;
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr); IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr);
gBS->Stall (LAN9118_STALL); MemoryFence();
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -999,7 +1003,7 @@ ChangeFifoAllocation (
HwConf &= ~(0xF0000); HwConf &= ~(0xF0000);
HwConf |= ((TxFifoOption & 0xF) << 16); HwConf |= ((TxFifoOption & 0xF) << 16);
MmioWrite32 (LAN9118_HW_CFG, HwConf); MmioWrite32 (LAN9118_HW_CFG, HwConf);
gBS->Stall (LAN9118_STALL); MemoryFence();
return EFI_SUCCESS; return EFI_SUCCESS;
} }