uint8_t ptp_enabled_port_nb;
static uint8_t ptp_enabled_ports[RTE_MAX_ETHPORTS];
-static const struct rte_eth_conf port_conf_default = {
- .rxmode = {
- .max_rx_pkt_len = ETHER_MAX_LEN,
- },
-};
-
static const struct rte_ether_addr ether_multicast = {
.addr_bytes = {0x01, 0x1b, 0x19, 0x0, 0x0, 0x0}
};
uint16_t sec_msb;
uint32_t sec_lsb;
uint32_t ns;
-} __attribute__((packed));
+} __rte_packed;
struct clock_id {
uint8_t id[8];
struct port_id {
struct clock_id clock_id;
uint16_t port_number;
-} __attribute__((packed));
+} __rte_packed;
struct ptp_header {
uint8_t msg_type;
uint16_t seq_id;
uint8_t control;
int8_t log_message_interval;
-} __attribute__((packed));
+} __rte_packed;
struct sync_msg {
struct ptp_header hdr;
struct tstamp origin_tstamp;
-} __attribute__((packed));
+} __rte_packed;
struct follow_up_msg {
struct ptp_header hdr;
struct tstamp precise_origin_tstamp;
uint8_t suffix[0];
-} __attribute__((packed));
+} __rte_packed;
struct delay_req_msg {
struct ptp_header hdr;
struct tstamp origin_tstamp;
-} __attribute__((packed));
+} __rte_packed;
struct delay_resp_msg {
struct ptp_header hdr;
struct tstamp rx_tstamp;
struct port_id req_port_id;
uint8_t suffix[0];
-} __attribute__((packed));
+} __rte_packed;
struct ptp_message {
union {
struct delay_req_msg delay_req;
struct follow_up_msg follow_up;
struct delay_resp_msg delay_resp;
- } __attribute__((packed));
+ } __rte_packed;
};
struct ptpv2_data_slave_ordinary {
port_init(uint16_t port, struct rte_mempool *mbuf_pool)
{
struct rte_eth_dev_info dev_info;
- struct rte_eth_conf port_conf = port_conf_default;
+ struct rte_eth_conf port_conf;
const uint16_t rx_rings = 1;
const uint16_t tx_rings = 1;
int retval;
if (!rte_eth_dev_is_valid_port(port))
return -1;
- rte_eth_dev_info_get(port, &dev_info);
- if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
+ memset(&port_conf, 0, sizeof(struct rte_eth_conf));
+
+ retval = rte_eth_dev_info_get(port, &dev_info);
+ if (retval != 0) {
+ printf("Error during getting device (port %u) info: %s\n",
+ port, strerror(-retval));
+
+ return retval;
+ }
+
+ if (dev_info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_TIMESTAMP)
+ port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
+
+ if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
port_conf.txmode.offloads |=
- DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
/* Force full Tx path in the driver, required for IEEE1588 */
- port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
+ port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
/* Configure the Ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
/* Allocate and set up 1 RX queue per Ethernet port. */
for (q = 0; q < rx_rings; q++) {
+ struct rte_eth_rxconf *rxconf;
+
+ rxconf = &dev_info.default_rxconf;
+ rxconf->offloads = port_conf.rxmode.offloads;
+
retval = rte_eth_rx_queue_setup(port, q, nb_rxd,
- rte_eth_dev_socket_id(port), NULL, mbuf_pool);
+ rte_eth_dev_socket_id(port), rxconf, mbuf_pool);
if (retval < 0)
return retval;
return retval;
/* Enable timesync timestamping for the Ethernet device */
- rte_eth_timesync_enable(port);
+ retval = rte_eth_timesync_enable(port);
+ if (retval < 0) {
+ printf("Timesync enable failed: %d\n", retval);
+ return retval;
+ }
/* Enable RX in promiscuous mode for the Ethernet device. */
- rte_eth_promiscuous_enable(port);
+ retval = rte_eth_promiscuous_enable(port);
+ if (retval != 0) {
+ printf("Promiscuous mode enable failed: %s\n",
+ rte_strerror(-retval));
+ return retval;
+ }
return 0;
}
}
/*
- * Parse the PTP FOLLOWUP message and send DELAY_REQ to the master clock.
+ * Parse the PTP FOLLOWUP message and send DELAY_REQ to the main clock.
*/
static void
parse_fup(struct ptpv2_data_slave_ordinary *ptp_data)
{
struct rte_ether_hdr *eth_hdr;
+ struct rte_ether_addr eth_addr;
struct ptp_header *ptp_hdr;
struct clock_id *client_clkid;
struct ptp_message *ptp_msg;
size_t pkt_size;
int wait_us;
struct rte_mbuf *m = ptp_data->m;
+ int ret;
eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
ptp_hdr = (struct ptp_header *)(rte_pktmbuf_mtod(m, char *)
(((uint64_t)ntohs(origin_tstamp->sec_msb)) << 32);
if (ptp_data->seqID_FOLLOWUP == ptp_data->seqID_SYNC) {
+ ret = rte_eth_macaddr_get(ptp_data->portid, ð_addr);
+ if (ret != 0) {
+ printf("\nCore %u: port %u failed to get MAC address: %s\n",
+ rte_lcore_id(), ptp_data->portid,
+ rte_strerror(-ret));
+ return;
+ }
created_pkt = rte_pktmbuf_alloc(mbuf_pool);
pkt_size = sizeof(struct rte_ether_hdr) +
created_pkt->data_len = pkt_size;
created_pkt->pkt_len = pkt_size;
eth_hdr = rte_pktmbuf_mtod(created_pkt, struct rte_ether_hdr *);
- rte_eth_macaddr_get(ptp_data->portid, ð_hdr->s_addr);
+ rte_ether_addr_copy(ð_addr, ð_hdr->src_addr);
/* Set multicast address 01-1B-19-00-00-00. */
- rte_ether_addr_copy(ð_multicast, ð_hdr->d_addr);
+ rte_ether_addr_copy(ð_multicast, ð_hdr->dst_addr);
eth_hdr->ether_type = htons(PTP_PROTOCOL);
ptp_msg = (struct ptp_message *)
ptp_msg->delay_req.hdr.ver = 2;
ptp_msg->delay_req.hdr.control = 1;
ptp_msg->delay_req.hdr.log_message_interval = 127;
+ ptp_msg->delay_req.hdr.message_length =
+ htons(sizeof(struct delay_req_msg));
+ ptp_msg->delay_req.hdr.domain_number = ptp_hdr->domain_number;
/* Set up clock id. */
client_clkid =
&ptp_msg->delay_req.hdr.source_port_id.clock_id;
- client_clkid->id[0] = eth_hdr->s_addr.addr_bytes[0];
- client_clkid->id[1] = eth_hdr->s_addr.addr_bytes[1];
- client_clkid->id[2] = eth_hdr->s_addr.addr_bytes[2];
+ client_clkid->id[0] = eth_hdr->src_addr.addr_bytes[0];
+ client_clkid->id[1] = eth_hdr->src_addr.addr_bytes[1];
+ client_clkid->id[2] = eth_hdr->src_addr.addr_bytes[2];
client_clkid->id[3] = 0xFF;
client_clkid->id[4] = 0xFE;
- client_clkid->id[5] = eth_hdr->s_addr.addr_bytes[3];
- client_clkid->id[6] = eth_hdr->s_addr.addr_bytes[4];
- client_clkid->id[7] = eth_hdr->s_addr.addr_bytes[5];
+ client_clkid->id[5] = eth_hdr->src_addr.addr_bytes[3];
+ client_clkid->id[6] = eth_hdr->src_addr.addr_bytes[4];
+ client_clkid->id[7] = eth_hdr->src_addr.addr_bytes[5];
rte_memcpy(&ptp_data->client_clock_id,
client_clkid,
sizeof(struct clock_id));
/* Enable flag for hardware timestamping. */
- created_pkt->ol_flags |= PKT_TX_IEEE1588_TMST;
+ created_pkt->ol_flags |= RTE_MBUF_F_TX_IEEE1588_TMST;
/*Read value from NIC to prevent latching with old value. */
rte_eth_timesync_read_tx_timestamp(ptp_data->portid,
/* This function processes PTP packets, implementing slave PTP IEEE1588 L2
* functionality.
*/
+
+/* Parse ptp frames. 8< */
static void
parse_ptp_frames(uint16_t portid, struct rte_mbuf *m) {
struct ptp_header *ptp_hdr;
}
}
}
+/* >8 End of function processes PTP packets. */
/*
* The lcore main. This is the main thread that does the work, reading from an
* input port and writing to an output port.
*/
-static __attribute__((noreturn)) void
+static __rte_noreturn void
lcore_main(void)
{
uint16_t portid;
unsigned nb_rx;
struct rte_mbuf *m;
- /*
- * Check that the port is on the same NUMA node as the polling thread
- * for best performance.
- */
printf("\nCore %u Waiting for SYNC packets. [Ctrl+C to quit]\n",
rte_lcore_id());
/* Run until the application is quit or killed. */
while (1) {
- /* Read packet from RX queues. */
+ /* Read packet from RX queues. 8< */
for (portid = 0; portid < ptp_enabled_port_nb; portid++) {
portid = ptp_enabled_ports[portid];
if (likely(nb_rx == 0))
continue;
- if (m->ol_flags & PKT_RX_IEEE1588_PTP)
+ /* Packet is parsed to determine which type. 8< */
+ if (m->ol_flags & RTE_MBUF_F_RX_IEEE1588_PTP)
parse_ptp_frames(portid, m);
+ /* >8 End of packet is parsed to determine which type. */
rte_pktmbuf_free(m);
}
+ /* >8 End of read packets from RX queues. */
}
}
pm = strtoul(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
- return -1;
-
- if (pm == 0)
- return -1;
+ return 0;
return pm;
}
uint16_t portid;
- /* Initialize the Environment Abstraction Layer (EAL). */
+ /* Initialize the Environment Abstraction Layer (EAL). 8< */
int ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
+ /* >8 End of initialization of EAL. */
memset(&ptp_data, '\0', sizeof(struct ptpv2_data_slave_ordinary));
+ /* Parse specific arguments. 8< */
argc -= ret;
argv += ret;
ret = ptp_parse_args(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Error with PTP initialization\n");
+ /* >8 End of parsing specific arguments. */
/* Check that there is an even number of ports to send/receive on. */
nb_ports = rte_eth_dev_count_avail();
- /* Creates a new mempool in memory to hold the mbufs. */
+ /* Creates a new mempool in memory to hold the mbufs. 8< */
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+ /* >8 End of a new mempool in memory to hold the mbufs. */
if (mbuf_pool == NULL)
rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
- /* Initialize all ports. */
+ /* Initialize all ports. 8< */
RTE_ETH_FOREACH_DEV(portid) {
if ((ptp_enabled_port_mask & (1 << portid)) != 0) {
if (port_init(portid, mbuf_pool) == 0) {
} else
printf("Skipping disabled port %u\n", portid);
}
+ /* >8 End of initialization of all ports. */
if (ptp_enabled_port_nb == 0) {
rte_exit(EXIT_FAILURE,
if (rte_lcore_count() > 1)
printf("\nWARNING: Too many lcores enabled. Only 1 used.\n");
- /* Call lcore_main on the master core only. */
+ /* Call lcore_main on the main core only. */
lcore_main();
+ /* clean up the EAL */
+ rte_eal_cleanup();
+
return 0;
}