diff options
author | Masahisa KOJIMA <masahisa.kojima@linaro.org> | 2018-04-19 10:23:57 +0900 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2018-04-26 12:07:33 +0200 |
commit | 83efbe23bb4d1b178b42b5ef00f929a89e2aa804 (patch) | |
tree | c303afd77a021abac34829847a92dc7fd0eed74f | |
parent | cb16d2b5add58b25b62c3078d3c18fc0404c36e3 (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.c | 109 | ||||
-rw-r--r-- | Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h | 4 |
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
|