summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasahisa KOJIMA <masahisa.kojima@linaro.org>2018-04-19 10:23:57 +0900
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2018-04-26 12:07:33 +0200
commit83efbe23bb4d1b178b42b5ef00f929a89e2aa804 (patch)
treec303afd77a021abac34829847a92dc7fd0eed74f
parentcb16d2b5add58b25b62c3078d3c18fc0404c36e3 (diff)
Silicon/SynQuacer/NetsecDxe: Add polling function to reinitialize GMACbuild34-83efbe23
GMAC is a Gigabit Ethernet MAC implemented in NETSEC. When the physical link is changed from DOWN to UP, GMAC should be reinitialized properly. We add polling function to check the physical link status and reinitialize GMAC. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Masahisa KOJIMA <masahisa.kojima@linaro.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c109
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h4
2 files changed, 113 insertions, 0 deletions
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c b/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c
index 764c44bb..7280b610 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c
@@ -161,6 +161,10 @@ SnpStop (
gBS->CloseEvent (LanDriver->ExitBootEvent);
+ gBS->SetTimer (LanDriver->PhyStatusEvent, TimerCancel, 0);
+ gBS->CloseEvent (LanDriver->PhyStatusEvent);
+ LanDriver->PhyStatusEvent = NULL;
+
// Change the state
Snp->Mode->State = EfiSimpleNetworkStopped;
Status = EFI_SUCCESS;
@@ -406,6 +410,100 @@ NotifyExitBoot (
gBS->CloseEvent (Event);
}
+/**
+ Polling function to check the physical link status with GMAC
+
+ @param Timer[in] Event
+ @param *Context[in] Pointer to the Snp structure
+
+ @return none
+
+**/
+STATIC
+VOID
+EFIAPI
+NetsecPollPhyStatus (
+ IN EFI_EVENT Timer,
+ IN VOID *Context
+ )
+{
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ NETSEC_DRIVER *LanDriver;
+ EFI_TPL SavedTpl;
+ ogma_phy_link_status_t phy_link_status;
+ ogma_gmac_mode_t ogma_gmac_mode;
+ ogma_err_t ogma_err;
+
+ // initial value is TRUE, because GMAC is already configured
+ // in SnpInitialize(), so it is better to skip at first time
+ static BOOLEAN PrevPhyLinkStatus = TRUE;
+
+ Snp = (EFI_SIMPLE_NETWORK_PROTOCOL *) Context;
+ if (Snp == NULL) {
+ DEBUG((DEBUG_ERROR, "NETSEC: PollPhyStatus() invalid Snp\n"));
+ return;
+ }
+ LanDriver = INSTANCE_FROM_SNP_THIS (Snp);
+
+ // Serialize access to data and registers
+ SavedTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ // Update the media status
+ ogma_err = ogma_get_phy_link_status (LanDriver->Handle, LanDriver->PhyAddress,
+ &phy_link_status);
+ if (ogma_err != OGMA_ERR_OK) {
+ DEBUG ((DEBUG_ERROR,
+ "NETSEC: ogma_get_phy_link_status failed with error code: %d\n",
+ (INT32)ogma_err));
+ goto ExitUnlock;
+ }
+
+ if ( (PrevPhyLinkStatus == FALSE) && (phy_link_status.up_flag == TRUE) ) {
+
+ // Stop and restart the physical link
+ ogma_err = ogma_stop_gmac (LanDriver->Handle, OGMA_TRUE, OGMA_TRUE);
+ if (ogma_err != OGMA_ERR_OK) {
+ DEBUG ((DEBUG_ERROR,
+ "NETSEC: ogma_stop_gmac() failed with error status %d\n",
+ ogma_err));
+ goto ExitUnlock;
+ }
+
+ SetMem (&ogma_gmac_mode, sizeof (ogma_gmac_mode_t), 0);
+ ogma_gmac_mode.link_speed = phy_link_status.link_speed;
+ ogma_gmac_mode.half_duplex_flag = (ogma_bool)phy_link_status.half_duplex_flag;
+ if ((!phy_link_status.half_duplex_flag) && FixedPcdGet8 (PcdFlowCtrl)) {
+ ogma_gmac_mode.flow_ctrl_enable_flag = FixedPcdGet8 (PcdFlowCtrl);
+ ogma_gmac_mode.flow_ctrl_start_threshold = FixedPcdGet16 (PcdFlowCtrlStartThreshold);
+ ogma_gmac_mode.flow_ctrl_stop_threshold = FixedPcdGet16 (PcdFlowCtrlStopThreshold);
+ ogma_gmac_mode.pause_time = FixedPcdGet16 (PcdPauseTime);
+ }
+
+ ogma_err = ogma_set_gmac_mode (LanDriver->Handle, &ogma_gmac_mode);
+ if (ogma_err != OGMA_ERR_OK) {
+ DEBUG ((DEBUG_ERROR,
+ "NETSEC: ogma_set_gmac() failed with error status %d\n",
+ (INT32)ogma_err));
+ goto ExitUnlock;
+ }
+
+ ogma_err = ogma_start_gmac (LanDriver->Handle, OGMA_TRUE, OGMA_TRUE);
+ if (ogma_err != OGMA_ERR_OK) {
+ DEBUG ((DEBUG_ERROR,
+ "NETSEC: ogma_start_gmac() failed with error status %d\n",
+ (INT32)ogma_err));
+ goto ExitUnlock;
+ }
+ }
+
+ PrevPhyLinkStatus = phy_link_status.up_flag;
+
+ExitUnlock:
+ gBS->RestoreTPL (SavedTpl);
+
+ return;
+}
+
/*
* UEFI Start() function
*/
@@ -450,6 +548,17 @@ SnpStart (
NotifyExitBoot, Snp, &LanDriver->ExitBootEvent);
ASSERT_EFI_ERROR (Status);
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ NetsecPollPhyStatus, Snp, &LanDriver->PhyStatusEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->SetTimer (
+ LanDriver->PhyStatusEvent,
+ TimerPeriodic,
+ NETSEC_PHY_STATUS_POLL_INTERVAL
+ );
+ ASSERT_EFI_ERROR (Status);
+
// Change state
Mode->State = EfiSimpleNetworkStarted;
Status = EFI_SUCCESS;
diff --git a/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h b/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h
index 6aa7f1a1..f09fb609 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h
+++ b/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h
@@ -71,6 +71,8 @@ typedef struct {
EFI_EVENT ExitBootEvent;
+ EFI_EVENT PhyStatusEvent;
+
NON_DISCOVERABLE_DEVICE *Dev;
NETSEC_DEVICE_PATH DevicePath;
@@ -115,4 +117,6 @@ NetsecRelease (
#define RXINT_TMR_CNT_US 0
#define RXINT_PKTCNT 1
+#define NETSEC_PHY_STATUS_POLL_INTERVAL (EFI_TIMER_PERIOD_MILLISECONDS (1000))
+
#endif