[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 36/40] igb: Implement Rx PTP2 timestamp
From: |
Akihiko Odaki |
Subject: |
[PATCH 36/40] igb: Implement Rx PTP2 timestamp |
Date: |
Fri, 14 Apr 2023 20:37:33 +0900 |
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/igb_common.h | 16 +++---
hw/net/igb_core.c | 129 ++++++++++++++++++++++++++++++++------------
hw/net/igb_regs.h | 23 ++++++++
3 files changed, 127 insertions(+), 41 deletions(-)
diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h
index f2a9065791..5c261ba9d3 100644
--- a/hw/net/igb_common.h
+++ b/hw/net/igb_common.h
@@ -51,7 +51,7 @@
defreg_indexeda(x, 0), defreg_indexeda(x, 1), \
defreg_indexeda(x, 2), defreg_indexeda(x, 3)
-#define defregv(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \
+#define defreg8(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \
defreg_indexed(x, 2), defreg_indexed(x, 3), \
defreg_indexed(x, 4), defreg_indexed(x, 5), \
defreg_indexed(x, 6), defreg_indexed(x, 7)
@@ -122,6 +122,8 @@ enum {
defreg(EICS), defreg(EIMS), defreg(EIMC), defreg(EIAM),
defreg(EICR), defreg(IVAR_MISC), defreg(GPIE),
+ defreg(TSYNCRXCFG), defreg8(ETQF),
+
defreg(RXPBS), defregd(RDBAL), defregd(RDBAH),
defregd(RDLEN),
defregd(SRRCTL), defregd(RDH), defregd(RDT),
defregd(RXDCTL), defregd(RXCTL), defregd(RQDPC), defreg(RA2),
@@ -133,15 +135,15 @@ enum {
defreg(VT_CTL),
- defregv(P2VMAILBOX), defregv(V2PMAILBOX), defreg(MBVFICR),
defreg(MBVFIMR),
+ defreg8(P2VMAILBOX), defreg8(V2PMAILBOX), defreg(MBVFICR),
defreg(MBVFIMR),
defreg(VFLRE), defreg(VFRE), defreg(VFTE), defreg(WVBR),
defreg(QDE), defreg(DTXSWC), defreg_indexed(VLVF, 0),
- defregv(VMOLR), defreg(RPLOLR), defregv(VMBMEM),
defregv(VMVIR),
+ defreg8(VMOLR), defreg(RPLOLR), defreg8(VMBMEM),
defreg8(VMVIR),
- defregv(PVTCTRL), defregv(PVTEICS), defregv(PVTEIMS),
defregv(PVTEIMC),
- defregv(PVTEIAC), defregv(PVTEIAM), defregv(PVTEICR),
defregv(PVFGPRC),
- defregv(PVFGPTC), defregv(PVFGORC), defregv(PVFGOTC),
defregv(PVFMPRC),
- defregv(PVFGPRLBC), defregv(PVFGPTLBC), defregv(PVFGORLBC),
defregv(PVFGOTLBC),
+ defreg8(PVTCTRL), defreg8(PVTEICS), defreg8(PVTEIMS),
defreg8(PVTEIMC),
+ defreg8(PVTEIAC), defreg8(PVTEIAM), defreg8(PVTEICR),
defreg8(PVFGPRC),
+ defreg8(PVFGPTC), defreg8(PVFGORC), defreg8(PVFGOTC),
defreg8(PVFMPRC),
+ defreg8(PVFGPRLBC), defreg8(PVFGPTLBC), defreg8(PVFGORLBC),
defreg8(PVFGOTLBC),
defreg(MTA_A),
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
index 70acc86834..c716f400fd 100644
--- a/hw/net/igb_core.c
+++ b/hw/net/igb_core.c
@@ -72,6 +72,24 @@ typedef struct L2Header {
struct vlan_header vlan[2];
} L2Header;
+typedef struct PTP2 {
+ uint8_t message_id_transport_specific;
+ uint8_t version_ptp;
+ uint16_t message_length;
+ uint8_t subdomain_number;
+ uint8_t reserved0;
+ uint16_t flags;
+ uint64_t correction;
+ uint8_t reserved1[5];
+ uint8_t source_communication_technology;
+ uint32_t source_uuid_lo;
+ uint16_t source_uuid_hi;
+ uint16_t source_port_id;
+ uint16_t sequence_id;
+ uint8_t control;
+ uint8_t log_message_period;
+} PTP2;
+
static ssize_t
igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
bool has_vnet, bool *external_tx);
@@ -989,9 +1007,11 @@ static bool igb_rx_is_oversized(IGBCore *core, const
struct eth_header *ehdr,
return size > 1518;
}
-static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
- size_t size, E1000E_RSSInfo *rss_info,
- bool *external_tx)
+static uint16_t igb_receive_assign(IGBCore *core, const struct iovec *iov,
+ size_t iovcnt, size_t iov_ofs,
+ const L2Header *l2_header, size_t size,
+ E1000E_RSSInfo *rss_info,
+ uint16_t *etqf, bool *ts, bool *external_tx)
{
static const int ta_shift[] = { 4, 3, 2, 0 };
const struct eth_header *ehdr = &l2_header->eth;
@@ -999,11 +1019,13 @@ static uint16_t igb_receive_assign(IGBCore *core, const
L2Header *l2_header,
uint16_t queues = 0;
uint16_t oversized = 0;
uint16_t vid = be16_to_cpu(l2_header->vlan[0].h_tci) & VLAN_VID_MASK;
+ PTP2 ptp2;
bool lpe;
uint16_t rlpml;
int i;
memset(rss_info, 0, sizeof(E1000E_RSSInfo));
+ *ts = false;
if (external_tx) {
*external_tx = true;
@@ -1017,6 +1039,26 @@ static uint16_t igb_receive_assign(IGBCore *core, const
L2Header *l2_header,
return queues;
}
+ for (*etqf = 0; *etqf < 8; (*etqf)++) {
+ if ((core->mac[ETQF0 + *etqf] & E1000_ETQF_FILTER_ENABLE) &&
+ be16_to_cpu(ehdr->h_proto) == (core->mac[ETQF0 + *etqf] &
E1000_ETQF_ETYPE_MASK)) {
+ if ((core->mac[ETQF0 + *etqf] & E1000_ETQF_1588) &&
+ (core->mac[TSYNCRXCTL] & E1000_TSYNCRXCTL_ENABLED) &&
+ !(core->mac[TSYNCRXCTL] & E1000_TSYNCRXCTL_VALID) &&
+ iov_to_buf(iov, iovcnt, iov_ofs + ETH_HLEN, &ptp2,
sizeof(ptp2)) >= sizeof(ptp2) &&
+ (ptp2.version_ptp & 15) == 2 &&
+ ptp2.message_id_transport_specific == ((core->mac[TSYNCRXCFG]
>> 8) & 255)) {
+ e1000x_timestamp(core->mac, core->timadj, RXSTMPL, RXSTMPH);
+ *ts = true;
+ core->mac[TSYNCRXCTL] |= E1000_TSYNCRXCTL_VALID;
+ core->mac[RXSATRL] = le32_to_cpu(ptp2.source_uuid_lo);
+ core->mac[RXSATRH] = le16_to_cpu(ptp2.source_uuid_hi) |
+ (le16_to_cpu(ptp2.sequence_id) << 16);
+ }
+ break;
+ }
+ }
+
if (core->mac[CTRL_EXT] & BIT(26)) {
if (be16_to_cpu(ehdr->h_proto) == core->mac[VET] >> 16 &&
be16_to_cpu(l2_header->vlan[0].h_proto) == (core->mac[VET] &
0xffff) &&
@@ -1232,7 +1274,7 @@ static void
igb_build_rx_metadata(IGBCore *core,
struct NetRxPkt *pkt,
bool is_eop,
- const E1000E_RSSInfo *rss_info,
+ const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
uint16_t *pkt_info, uint16_t *hdr_info,
uint32_t *rss,
uint32_t *status_flags,
@@ -1283,29 +1325,33 @@ igb_build_rx_metadata(IGBCore *core,
if (pkt_info) {
*pkt_info = rss_info->enabled ? rss_info->type : 0;
- if (hasip4) {
- *pkt_info |= BIT(4);
- }
+ if (etqf < 8) {
+ *pkt_info |= BIT(11) | (etqf << 4);
+ } else {
+ if (hasip4) {
+ *pkt_info |= BIT(4);
+ }
- if (hasip6) {
- *pkt_info |= BIT(6);
- }
+ if (hasip6) {
+ *pkt_info |= BIT(6);
+ }
- switch (l4hdr_proto) {
- case ETH_L4_HDR_PROTO_TCP:
- *pkt_info |= BIT(8);
- break;
+ switch (l4hdr_proto) {
+ case ETH_L4_HDR_PROTO_TCP:
+ *pkt_info |= BIT(8);
+ break;
- case ETH_L4_HDR_PROTO_UDP:
- *pkt_info |= BIT(9);
- break;
+ case ETH_L4_HDR_PROTO_UDP:
+ *pkt_info |= BIT(9);
+ break;
- case ETH_L4_HDR_PROTO_SCTP:
- *pkt_info |= BIT(10);
- break;
+ case ETH_L4_HDR_PROTO_SCTP:
+ *pkt_info |= BIT(10);
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
}
@@ -1313,6 +1359,10 @@ igb_build_rx_metadata(IGBCore *core,
*hdr_info = 0;
}
+ if (ts) {
+ *status_flags |= BIT(16);
+ }
+
/* RX CSO information */
if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
trace_e1000e_rx_metadata_ipv6_sum_disabled();
@@ -1368,7 +1418,7 @@ func_exit:
static inline void
igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
struct NetRxPkt *pkt,
- const E1000E_RSSInfo *rss_info,
+ const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
uint16_t length)
{
uint32_t status_flags, rss;
@@ -1379,7 +1429,7 @@ igb_write_lgcy_rx_descr(IGBCore *core, struct
e1000_rx_desc *desc,
desc->csum = 0;
igb_build_rx_metadata(core, pkt, pkt != NULL,
- rss_info,
+ rss_info, etqf, ts,
NULL, NULL, &rss,
&status_flags, &ip_id,
&desc->special);
@@ -1390,7 +1440,7 @@ igb_write_lgcy_rx_descr(IGBCore *core, struct
e1000_rx_desc *desc,
static inline void
igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
struct NetRxPkt *pkt,
- const E1000E_RSSInfo *rss_info,
+ const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
uint16_t length)
{
memset(&desc->wb, 0, sizeof(desc->wb));
@@ -1398,7 +1448,7 @@ igb_write_adv_rx_descr(IGBCore *core, union
e1000_adv_rx_desc *desc,
desc->wb.upper.length = cpu_to_le16(length);
igb_build_rx_metadata(core, pkt, pkt != NULL,
- rss_info,
+ rss_info, etqf, ts,
&desc->wb.lower.lo_dword.pkt_info,
&desc->wb.lower.lo_dword.hdr_info,
&desc->wb.lower.hi_dword.rss,
@@ -1409,12 +1459,15 @@ igb_write_adv_rx_descr(IGBCore *core, union
e1000_adv_rx_desc *desc,
static inline void
igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
-struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, uint16_t length)
+ struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
+ uint16_t etqf, bool ts, uint16_t length)
{
if (igb_rx_use_legacy_descriptor(core)) {
- igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
+ igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
+ etqf, ts, length);
} else {
- igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info, length);
+ igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info,
+ etqf, ts, length);
}
}
@@ -1491,7 +1544,8 @@ igb_rx_descr_threshold_hit(IGBCore *core, const
E1000E_RingInfo *rxi)
static void
igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
const E1000E_RxRing *rxr,
- const E1000E_RSSInfo *rss_info)
+ const E1000E_RSSInfo *rss_info,
+ uint16_t etqf, bool ts)
{
PCIDevice *d;
dma_addr_t base;
@@ -1573,7 +1627,7 @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt
*pkt,
}
igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
- rss_info, written);
+ rss_info, etqf, ts, written);
igb_pci_dma_write_rx_desc(core, d, base, &desc, core->rx_desc_len);
igb_ring_advance(core, rxi, core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
@@ -1628,6 +1682,8 @@ igb_receive_internal(IGBCore *core, const struct iovec
*iov, int iovcnt,
size_t iov_ofs = 0;
E1000E_RxRing rxr;
E1000E_RSSInfo rss_info;
+ uint16_t etqf;
+ bool ts;
size_t total_size;
int strip_vlan_index;
int i;
@@ -1671,8 +1727,9 @@ igb_receive_internal(IGBCore *core, const struct iovec
*iov, int iovcnt,
get_eth_packet_type(&min_buf.l2_header.eth));
net_rx_pkt_set_protocols(core->rx_pkt, iov, iovcnt, iov_ofs);
- queues = igb_receive_assign(core, &min_buf.l2_header, size,
- &rss_info, external_tx);
+ queues = igb_receive_assign(core, iov, iovcnt, iov_ofs,
+ &min_buf.l2_header, size,
+ &rss_info, &etqf, &ts, external_tx);
if (!queues) {
trace_e1000e_rx_flt_dropped();
return orig_size;
@@ -1711,7 +1768,7 @@ igb_receive_internal(IGBCore *core, const struct iovec
*iov, int iovcnt,
n |= E1000_ICR_RXDW;
igb_rx_fix_l4_csum(core, core->rx_pkt);
- igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info);
+ igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info, etqf,
ts);
/* Check if receive descriptor minimum threshold hit */
if (igb_rx_descr_threshold_hit(core, rxr.i)) {
@@ -3304,6 +3361,8 @@ static const readops igb_macreg_readops[] = {
[EIAM] = igb_mac_readreg,
[IVAR0 ... IVAR0 + 7] = igb_mac_readreg,
igb_getreg(IVAR_MISC),
+ igb_getreg(TSYNCRXCFG),
+ [ETQF0 ... ETQF0 + 7] = igb_mac_readreg,
igb_getreg(VT_CTL),
[P2VMAILBOX0 ... P2VMAILBOX7] = igb_mac_readreg,
[V2PMAILBOX0 ... V2PMAILBOX7] = igb_mac_vfmailbox_read,
@@ -3711,6 +3770,8 @@ static const writeops igb_macreg_writeops[] = {
[EIMS] = igb_set_eims,
[IVAR0 ... IVAR0 + 7] = igb_mac_writereg,
igb_putreg(IVAR_MISC),
+ igb_putreg(TSYNCRXCFG),
+ [ETQF0 ... ETQF0 + 7] = igb_mac_writereg,
igb_putreg(VT_CTL),
[P2VMAILBOX0 ... P2VMAILBOX7] = igb_set_pfmailbox,
[V2PMAILBOX0 ... V2PMAILBOX7] = igb_set_vfmailbox,
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
index 03486edb2e..b88dc9f1f1 100644
--- a/hw/net/igb_regs.h
+++ b/hw/net/igb_regs.h
@@ -210,6 +210,15 @@ union e1000_adv_rx_desc {
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+/* ETQF register bit definitions */
+#define E1000_ETQF_FILTER_ENABLE BIT(26)
+#define E1000_ETQF_1588 BIT(30)
+#define E1000_ETQF_IMM_INT BIT(29)
+#define E1000_ETQF_QUEUE_ENABLE BIT(31)
+#define E1000_ETQF_QUEUE_SHIFT 16
+#define E1000_ETQF_QUEUE_MASK 0x00070000
+#define E1000_ETQF_ETYPE_MASK 0x0000FFFF
+
#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control
*/
#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
@@ -384,6 +393,20 @@ union e1000_adv_rx_desc {
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
+#define E1000_TSYNCRXCFG 0x05F50 /* Time Sync Rx Configuration - RW */
+
+/* Filtering Registers */
+#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
+#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
+#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
+#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
+#define E1000_SAQF0 E1000_SAQF(0)
+#define E1000_DAQF0 E1000_DAQF(0)
+#define E1000_SPQF0 E1000_SPQF(0)
+#define E1000_FTQF0 E1000_FTQF(0)
+#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
+#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+
#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
--
2.40.0
- RE: [PATCH 31/40] igb: Use UDP for RSS hash, (continued)
- [PATCH 38/40] vmxnet3: Do not depend on PC, Akihiko Odaki, 2023/04/14
- [PATCH 37/40] igb: Implement Tx timestamp, Akihiko Odaki, 2023/04/14
- [PATCH 33/40] igb: Implement Tx SCTP CSO, Akihiko Odaki, 2023/04/14
- [PATCH 39/40] MAINTAINERS: Add a reviewer for network packet abstractions, Akihiko Odaki, 2023/04/14
- [PATCH 34/40] igb: Strip the second VLAN tag for extended VLAN, Akihiko Odaki, 2023/04/14
- [PATCH 40/40] docs/system/devices/igb: Note igb is tested for DPDK, Akihiko Odaki, 2023/04/14
- [PATCH 36/40] igb: Implement Rx PTP2 timestamp,
Akihiko Odaki <=
- [PATCH 32/40] igb: Implement Rx SCTP CSO, Akihiko Odaki, 2023/04/14
- [PATCH 35/40] igb: Filter with the second VLAN tag for extended VLAN, Akihiko Odaki, 2023/04/14