All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akihiko Odaki <akihiko.odaki@daynix.com>
Cc: Jason Wang <jasowang@redhat.com>,
	Dmitry Fleytman <dmitry.fleytman@gmail.com>,
	Thomas Huth <thuth@redhat.com>,
	Laurent Vivier <lvivier@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	qemu-devel@nongnu.org, qemu-ppc@nongnu.org,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Yan Vugenfirer <yvugenfi@redhat.com>,
	Yuri Benditovich <yuri.benditovich@daynix.com>,
	Sriram Yagnaraman <sriram.yagnaraman@est.tech>,
	Alexander Bulekov <alxndr@bu.edu>,
	Akihiko Odaki <akihiko.odaki@daynix.com>
Subject: [PATCH v6 34/34] e1000e: Implement system clock
Date: Thu, 23 Feb 2023 19:20:18 +0900	[thread overview]
Message-ID: <20230223102018.141748-35-akihiko.odaki@daynix.com> (raw)
In-Reply-To: <20230223102018.141748-1-akihiko.odaki@daynix.com>

The system clock is necessary to implement PTP features. While we are
not implementing PTP features for e1000e yet, we do have a plan to
implement them for igb, a new network device derived from e1000e,
so add system clock to the common base first.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 hw/core/machine.c      |  1 +
 hw/net/e1000_regs.h    | 27 +++++++++++++++++++++++++++
 hw/net/e1000e.c        | 11 +++++++++++
 hw/net/e1000e_core.c   | 39 ++++++++++++++++++++++++++++++++++-----
 hw/net/e1000e_core.h   |  2 ++
 hw/net/e1000x_common.c | 25 +++++++++++++++++++++++++
 hw/net/e1000x_common.h |  3 +++
 7 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f73fc4c45c..d438bfcd5b 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -41,6 +41,7 @@
 #include "hw/virtio/virtio-pci.h"
 
 GlobalProperty hw_compat_7_2[] = {
+    { "e1000e", "migrate-timadj", "off" },
     { "virtio-mem", "x-early-migration", "false" },
 };
 const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
index 4545fe25a6..77144cb617 100644
--- a/hw/net/e1000_regs.h
+++ b/hw/net/e1000_regs.h
@@ -908,6 +908,33 @@
 #define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
 #define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP            0x40000000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC           0x80000000 /* initiate sync */
+
+#define E1000_TSYNCTXCTL_VALID                0x00000001 /* Tx timestamp valid */
+#define E1000_TSYNCTXCTL_ENABLED              0x00000010 /* enable Tx timestamping */
+
+#define E1000_TSYNCRXCTL_VALID                0x00000001 /* Rx timestamp valid */
+#define E1000_TSYNCRXCTL_TYPE_MASK            0x0000000E /* Rx type mask */
+#define E1000_TSYNCRXCTL_TYPE_L2_V2           0x00
+#define E1000_TSYNCRXCTL_TYPE_L4_V1           0x02
+#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2        0x04
+#define E1000_TSYNCRXCTL_TYPE_ALL             0x08
+#define E1000_TSYNCRXCTL_TYPE_EVENT_V2        0x0A
+#define E1000_TSYNCRXCTL_ENABLED              0x00000010 /* enable Rx timestamping */
+#define E1000_TSYNCRXCTL_SYSCFI               0x00000020 /* Sys clock frequency */
+
+#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE      0x00000000
+#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
+
+#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE      0x00000000
+#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
+
+#define E1000_TIMINCA_INCPERIOD_SHIFT         24
+#define E1000_TIMINCA_INCVALUE_MASK           0x00FFFFFF
+
 /* PCI Express Control */
 /* 3GIO Control Register - GCR (0x05B00; RW) */
 #define E1000_L0S_ADJUST              (1 << 9)
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index ec274319c4..78c07a8f8e 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -82,6 +82,7 @@ struct E1000EState {
 
     E1000ECore core;
     bool init_vet;
+    bool timadj;
 };
 
 #define E1000E_MMIO_IDX     0
@@ -554,6 +555,12 @@ static int e1000e_post_load(void *opaque, int version_id)
     return e1000e_core_post_load(&s->core);
 }
 
+static bool e1000e_migrate_timadj(void *opaque, int version_id)
+{
+    E1000EState *s = opaque;
+    return s->timadj;
+}
+
 static const VMStateDescription e1000e_vmstate_tx = {
     .name = "e1000e-tx",
     .version_id = 1,
@@ -645,6 +652,9 @@ static const VMStateDescription e1000e_vmstate = {
 
         VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0,
                              e1000e_vmstate_tx, struct e1000e_tx),
+
+        VMSTATE_INT64_TEST(core.timadj, E1000EState, e1000e_migrate_timadj),
+
         VMSTATE_END_OF_LIST()
     }
 };
@@ -663,6 +673,7 @@ static Property e1000e_properties[] = {
     DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0,
                         e1000e_prop_subsys, uint16_t),
     DEFINE_PROP_BOOL("init-vet", E1000EState, init_vet, true),
+    DEFINE_PROP_BOOL("migrate-timadj", E1000EState, timadj, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index a2974631ef..e8d466b33e 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2902,6 +2902,35 @@ e1000e_set_gcr(E1000ECore *core, int index, uint32_t val)
     core->mac[GCR] = (val & ~E1000_GCR_RO_BITS) | ro_bits;
 }
 
+static uint32_t e1000e_get_systiml(E1000ECore *core, int index)
+{
+    e1000x_timestamp(core->mac, core->timadj, SYSTIML, SYSTIMH);
+    return core->mac[SYSTIML];
+}
+
+static uint32_t e1000e_get_rxsatrh(E1000ECore *core, int index)
+{
+    core->mac[TSYNCRXCTL] &= ~E1000_TSYNCRXCTL_VALID;
+    return core->mac[RXSATRH];
+}
+
+static uint32_t e1000e_get_txstmph(E1000ECore *core, int index)
+{
+    core->mac[TSYNCTXCTL] &= ~E1000_TSYNCTXCTL_VALID;
+    return core->mac[TXSTMPH];
+}
+
+static void e1000e_set_timinca(E1000ECore *core, int index, uint32_t val)
+{
+    e1000x_set_timinca(core->mac, &core->timadj, val);
+}
+
+static void e1000e_set_timadjh(E1000ECore *core, int index, uint32_t val)
+{
+    core->mac[TIMADJH] = val;
+    core->timadj += core->mac[TIMADJL] | ((int64_t)core->mac[TIMADJH] << 32);
+}
+
 #define e1000e_getreg(x)    [x] = e1000e_mac_readreg
 typedef uint32_t (*readops)(E1000ECore *, int);
 static const readops e1000e_macreg_readops[] = {
@@ -2957,7 +2986,6 @@ static const readops e1000e_macreg_readops[] = {
     e1000e_getreg(GSCL_2),
     e1000e_getreg(RDBAH1),
     e1000e_getreg(FLSWDATA),
-    e1000e_getreg(RXSATRH),
     e1000e_getreg(TIPG),
     e1000e_getreg(FLMNGCTL),
     e1000e_getreg(FLMNGCNT),
@@ -2998,7 +3026,6 @@ static const readops e1000e_macreg_readops[] = {
     e1000e_getreg(FLSWCTL),
     e1000e_getreg(RXDCTL1),
     e1000e_getreg(RXSATRL),
-    e1000e_getreg(SYSTIML),
     e1000e_getreg(RXUDP),
     e1000e_getreg(TORL),
     e1000e_getreg(TDLEN1),
@@ -3038,7 +3065,6 @@ static const readops e1000e_macreg_readops[] = {
     e1000e_getreg(FLOL),
     e1000e_getreg(RXDCTL),
     e1000e_getreg(RXSTMPL),
-    e1000e_getreg(TXSTMPH),
     e1000e_getreg(TIMADJH),
     e1000e_getreg(FCRTL),
     e1000e_getreg(TDBAH),
@@ -3087,6 +3113,9 @@ static const readops e1000e_macreg_readops[] = {
     [TARC1]   = e1000e_get_tarc,
     [SWSM]    = e1000e_mac_swsm_read,
     [IMS]     = e1000e_mac_ims_read,
+    [SYSTIML] = e1000e_get_systiml,
+    [RXSATRH] = e1000e_get_rxsatrh,
+    [TXSTMPH] = e1000e_get_txstmph,
 
     [CRCERRS ... MPC]      = e1000e_mac_readreg,
     [IP6AT ... IP6AT + 3]  = e1000e_mac_readreg,
@@ -3125,7 +3154,6 @@ static const writeops e1000e_macreg_writeops[] = {
     e1000e_putreg(WUS),
     e1000e_putreg(IPAV),
     e1000e_putreg(TDBAH1),
-    e1000e_putreg(TIMINCA),
     e1000e_putreg(IAM),
     e1000e_putreg(EIAC),
     e1000e_putreg(IVAR),
@@ -3168,7 +3196,6 @@ static const writeops e1000e_macreg_writeops[] = {
     e1000e_putreg(SYSTIML),
     e1000e_putreg(SYSTIMH),
     e1000e_putreg(TIMADJL),
-    e1000e_putreg(TIMADJH),
     e1000e_putreg(RXUDP),
     e1000e_putreg(RXCFGL),
     e1000e_putreg(TSYNCRXCTL),
@@ -3241,6 +3268,8 @@ static const writeops e1000e_macreg_writeops[] = {
     [CTRL_DUP] = e1000e_set_ctrl,
     [RFCTL]    = e1000e_set_rfctl,
     [RA + 1]   = e1000e_mac_setmacaddr,
+    [TIMINCA]  = e1000e_set_timinca,
+    [TIMADJH]  = e1000e_set_timadjh,
 
     [IP6AT ... IP6AT + 3]    = e1000e_mac_writereg,
     [IP4AT ... IP4AT + 6]    = e1000e_mac_writereg,
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
index d0a14b4523..213a70530d 100644
--- a/hw/net/e1000e_core.h
+++ b/hw/net/e1000e_core.h
@@ -112,6 +112,8 @@ struct E1000Core {
     void (*owner_start_recv)(PCIDevice *d);
 
     uint32_t msi_causes_pending;
+
+    int64_t timadj;
 };
 
 void
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
index e6387dde53..c497923806 100644
--- a/hw/net/e1000x_common.c
+++ b/hw/net/e1000x_common.c
@@ -267,3 +267,28 @@ e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
     props->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
     props->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
 }
+
+void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi)
+{
+    int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint32_t timinca = mac[TIMINCA];
+    uint32_t incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
+    uint32_t incperiod = MAX(timinca >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
+    int64_t timestamp = timadj + muldiv64(ns, incvalue, incperiod * 16);
+
+    mac[lo] = timestamp & 0xffffffff;
+    mac[hi] = timestamp >> 32;
+}
+
+void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val)
+{
+    int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint32_t old_val = mac[TIMINCA];
+    uint32_t old_incvalue = old_val & E1000_TIMINCA_INCVALUE_MASK;
+    uint32_t old_incperiod = MAX(old_val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
+    uint32_t incvalue = val & E1000_TIMINCA_INCVALUE_MASK;
+    uint32_t incperiod = MAX(val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
+
+    mac[TIMINCA] = val;
+    *timadj += (muldiv64(ns, incvalue, incperiod) - muldiv64(ns, old_incvalue, old_incperiod)) / 16;
+}
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
index 86a31b69f8..72b744b782 100644
--- a/hw/net/e1000x_common.h
+++ b/hw/net/e1000x_common.h
@@ -213,4 +213,7 @@ typedef struct e1000x_txd_props {
 void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
                               e1000x_txd_props *props);
 
+void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi);
+void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val);
+
 #endif
-- 
2.39.1



      parent reply	other threads:[~2023-02-23 10:25 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-23 10:19 [PATCH v6 00/34] e1000x cleanups (preliminary for IGB) Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 01/34] e1000e: Fix the code style Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 02/34] hw/net: Add more MII definitions Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 03/34] fsl_etsec: Use hw/net/mii.h Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 04/34] e1000: " Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 05/34] e1000: Mask registers when writing Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 06/34] e1000e: Introduce E1000E_LOW_BITS_SET_FUNC Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 07/34] e1000e: Mask registers when writing Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 08/34] e1000: Use more constant definitions Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 09/34] e1000e: " Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 10/34] e1000: Use memcpy to intialize registers Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 11/34] e1000e: " Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 12/34] e1000e: Remove pending interrupt flags Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 13/34] e1000e: Improve software reset Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 14/34] e1000: Configure ResettableClass Akihiko Odaki
2023-02-23 10:19 ` [PATCH v6 15/34] e1000e: " Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 16/34] e1000e: Introduce e1000_rx_desc_union Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 17/34] e1000e: Set MII_ANER_NWAY Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 18/34] e1000e: Remove extra pointer indirection Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 19/34] net: Check L4 header size Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 20/34] e1000x: Alter the signature of e1000x_is_vlan_packet Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 21/34] net: Strip virtio-net header when dumping Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 22/34] hw/net/net_tx_pkt: Automatically determine if virtio-net header is used Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 23/34] hw/net/net_rx_pkt: Remove net_rx_pkt_has_virt_hdr Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 24/34] e1000e: Perform software segmentation for loopback Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 25/34] hw/net/net_tx_pkt: Implement TCP segmentation Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 26/34] hw/net/net_tx_pkt: Check the payload length Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 27/34] e1000e: Do not assert when MSI-X is disabled later Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 28/34] MAINTAINERS: Add Akihiko Odaki as a e1000e reviewer Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 29/34] MAINTAINERS: Add e1000e test files Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 30/34] e1000e: Combine rx traces Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 31/34] e1000: Count CRC in Tx statistics Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 32/34] e1000e: " Akihiko Odaki
2023-02-23 10:20 ` [PATCH v6 33/34] net/eth: Report if headers are actually present Akihiko Odaki
2023-02-23 10:20 ` Akihiko Odaki [this message]

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-all 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=20230223102018.141748-35-akihiko.odaki@daynix.com \
    --to=akihiko.odaki@daynix.com \
    --cc=alxndr@bu.edu \
    --cc=dmitry.fleytman@gmail.com \
    --cc=jasowang@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=sriram.yagnaraman@est.tech \
    --cc=thuth@redhat.com \
    --cc=yuri.benditovich@daynix.com \
    --cc=yvugenfi@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.