aboutsummaryrefslogtreecommitdiff
path: root/hw/net/e1000x_common.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2023-02-23 19:20:18 +0900
committerJason Wang <jasowang@redhat.com>2023-03-10 15:35:38 +0800
commit5fb7d149953f469381a11e486d66dc56af2c0f21 (patch)
tree2edce2f323419178882b9bcd31f1d67851aedf09 /hw/net/e1000x_common.c
parent69ff5ef8474575556997dbe7f7f9bd28c4aee5de (diff)
e1000e: Implement system clock
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> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net/e1000x_common.c')
-rw-r--r--hw/net/e1000x_common.c25
1 files changed, 25 insertions, 0 deletions
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;
+}