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 13:14:34 +0200
commit10edf82dcb23c1fb919652d9f7d94d0a4dcd9d6f (patch)
tree0c155d277f826ca9949e4035cc2e527c651af6c4
parentcb16d2b5add58b25b62c3078d3c18fc0404c36e3 (diff)
Silicon/SynQuacer/NetsecDxe: Add polling function to reinitialize GMACbuild35-10edf82d
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 reinitializa GMAC. When the GMAC is running and physical link is down, stop GMAC. When the GMAC is stopped and physical link is up, start 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.c113
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h4
2 files changed, 117 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..a30ebd93 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,104 @@ 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;
+ ogma_phy_link_status_t phy_link_status;
+ ogma_gmac_mode_t ogma_gmac_mode;
+ ogma_err_t ogma_err;
+ BOOLEAN ValidFlag;
+ ogma_gmac_mode_t GmacMode;
+ BOOLEAN RxRunningFlag;
+ BOOLEAN TxRunningFlag;
+
+ Snp = (EFI_SIMPLE_NETWORK_PROTOCOL *) Context;
+ if (Snp == NULL) {
+ DEBUG((DEBUG_ERROR, "NETSEC: PollPhyStatus() invalid Snp\n"));
+ return;
+ }
+ LanDriver = INSTANCE_FROM_SNP_THIS (Snp);
+
+ // 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 Exit;
+ }
+
+ // Update the GMAC status
+ ogma_err = ogma_get_gmac_status (LanDriver->Handle, &ValidFlag, &GmacMode,
+ &RxRunningFlag, &TxRunningFlag);
+ if (ogma_err != OGMA_ERR_OK) {
+ DEBUG ((DEBUG_ERROR,
+ "NETSEC: ogma_get_gmac_status failed with error code: %d\n",
+ (INT32)ogma_err));
+ goto Exit;
+ }
+
+ // Stop GMAC when GMAC is running and physical link is down
+ if ( (RxRunningFlag) && (TxRunningFlag) && (!phy_link_status.up_flag) ) {
+ 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 Exit;
+ }
+ }
+
+ // Start GMAC when GMAC is stopped and physical link is up
+ if ( (!RxRunningFlag) && (!TxRunningFlag) && (phy_link_status.up_flag) ) {
+ 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 Exit;
+ }
+
+ 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 Exit;
+ }
+ }
+
+Exit:
+ return;
+}
+
/*
* UEFI Start() function
*/
@@ -450,6 +552,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