public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: edk2-devel@lists.01.org
Cc: leif.lindholm@linaro.org, Masahisa KOJIMA <masahisa.kojima@linaro.org>
Subject: [PATCH edk2-platforms 1/5] Silicon/SynQuacer/NetsecDxe: Add polling function to reinitialize GMAC
Date: Fri, 27 Apr 2018 13:37:44 +0200	[thread overview]
Message-ID: <20180427113748.21663-2-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <20180427113748.21663-1-ard.biesheuvel@linaro.org>

From: Masahisa KOJIMA <masahisa.kojima@linaro.org>

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:
- 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>
---
 Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c | 108 ++++++++++++++++++++
 Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.h |   4 +
 2 files changed, 112 insertions(+)

diff --git a/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c b/Silicon/Socionext/SynQuacer/Drivers/Net/NetsecDxe/NetsecDxe.c
index 764c44bb3c87..fa8ae79da28e 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,99 @@ NotifyExitBoot (
   gBS->CloseEvent (Event);
 }
 
+/**
+  Polling function to check the physical link status with GMAC
+
+  @param[in]  Timer              Event
+  @param[in]  Context            Pointer to the Snp structure
+
+**/
+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));
+    return;
+  }
+
+  // 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));
+    return;
+  }
+
+  // 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));
+      return;
+    }
+  }
+
+  // Start GMAC when GMAC is stopped and physical link is up
+  if (!RxRunningFlag && !TxRunningFlag && phy_link_status.up_flag) {
+    ZeroMem (&ogma_gmac_mode, sizeof (ogma_gmac_mode_t));
+    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));
+      return;
+    }
+
+    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));
+    }
+  }
+}
+
 /*
  *  UEFI Start() function
  */
@@ -450,6 +547,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 6aa7f1a1d107..f09fb609ba5a 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
-- 
2.17.0



  reply	other threads:[~2018-04-27 11:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-27 11:37 [PATCH edk2-platforms 0/5] assorted SynQuacer updates Ard Biesheuvel
2018-04-27 11:37 ` Ard Biesheuvel [this message]
2018-04-27 11:37 ` [PATCH edk2-platforms 2/5] Platform/Socionext/DeveloperBox: add SNP driver Ard Biesheuvel
2018-05-22 15:04   ` Leif Lindholm
2018-04-27 11:37 ` [PATCH edk2-platforms 3/5] Platform/SynQuacer: add 'acpiview' shell command to build Ard Biesheuvel
2018-04-27 11:37 ` [PATCH edk2-platforms 4/5] Silicon/SynQuacer/PlatformDxe: depex on gEfiVariableArchProtocolGuid Ard Biesheuvel
2018-04-27 11:37 ` [PATCH edk2-platforms 5/5] Silicon/SynQuacer: drop BEFORE depex for varstore formatting Ard Biesheuvel
2018-05-22 15:41 ` [PATCH edk2-platforms 0/5] assorted SynQuacer updates Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180427113748.21663-2-ard.biesheuvel@linaro.org \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox