1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 
10 #include <rte_common.h>
11 #include <rte_eal.h>
12 #include <rte_lcore.h>
13 #include <rte_mempool.h>
14 
15 #include <rte_rawdev.h>
16 #include <rte_rawdev_pmd.h>
17 
18 #include "otx2_common.h"
19 #include "otx2_ep_rawdev.h"
20 
21 #define SDP_IOQ_NUM_BUFS   (4 * 1024)
22 #define SDP_IOQ_BUF_SIZE   (2 * 1024)
23 
24 #define SDP_TEST_PKT_FSZ   (0)
25 #define SDP_TEST_PKT_SIZE  (1024)
26 
27 static int
sdp_validate_data(struct sdp_droq_pkt * oq_pkt,uint8_t * iq_pkt,uint32_t pkt_len)28 sdp_validate_data(struct sdp_droq_pkt *oq_pkt, uint8_t *iq_pkt,
29 		  uint32_t pkt_len)
30 {
31 	if (!oq_pkt)
32 		return -EINVAL;
33 
34 	if (pkt_len != oq_pkt->len) {
35 		otx2_err("Invalid packet length");
36 		return -EINVAL;
37 	}
38 
39 	if (memcmp(oq_pkt->data, iq_pkt, pkt_len) != 0) {
40 		otx2_err("Data validation failed");
41 		return -EINVAL;
42 	}
43 	otx2_sdp_dbg("Data validation successful");
44 
45 	return 0;
46 }
47 
48 static void
sdp_ioq_buffer_fill(uint8_t * addr,uint32_t len)49 sdp_ioq_buffer_fill(uint8_t *addr, uint32_t len)
50 {
51 	uint32_t idx;
52 
53 	memset(addr, 0, len);
54 
55 	for (idx = 0; idx < len; idx++)
56 		addr[idx] = idx;
57 }
58 
59 static struct rte_mempool*
sdp_ioq_mempool_create(void)60 sdp_ioq_mempool_create(void)
61 {
62 	struct rte_mempool *mpool;
63 
64 	mpool = rte_mempool_create("ioqbuf_pool",
65 				   SDP_IOQ_NUM_BUFS /*num elt*/,
66 				   SDP_IOQ_BUF_SIZE /*elt size*/,
67 				   0 /*cache_size*/,
68 				   0 /*private_data_size*/,
69 				   NULL /*mp_init*/,
70 				   NULL /*mp_init arg*/,
71 				   NULL /*obj_init*/,
72 				   NULL /*obj_init arg*/,
73 				   rte_socket_id() /*socket id*/,
74 				   (MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET));
75 
76 	return mpool;
77 }
78 
79 
80 int
sdp_rawdev_selftest(uint16_t dev_id)81 sdp_rawdev_selftest(uint16_t dev_id)
82 {
83 	struct sdp_rawdev_info app_info = {0};
84 	struct rte_rawdev_info dev_info = {0};
85 
86 	struct rte_rawdev_buf *d_buf[1];
87 	struct sdp_droq_pkt oq_pkt;
88 	struct sdp_soft_instr si;
89 	struct sdp_device sdpvf;
90 
91 	uint32_t buf_size;
92 	int ret = 0;
93 	void *buf;
94 
95 	otx2_info("SDP RAWDEV Self Test: Started");
96 
97 	memset(&oq_pkt, 0x00, sizeof(oq_pkt));
98 	d_buf[0] = (struct rte_rawdev_buf *)&oq_pkt;
99 
100 	struct rte_mempool *ioq_mpool = sdp_ioq_mempool_create();
101 	if (!ioq_mpool) {
102 		otx2_err("IOQ mpool creation failed");
103 		return -ENOMEM;
104 	}
105 
106 	app_info.enqdeq_mpool = ioq_mpool;
107 	app_info.app_conf = NULL; /* Use default conf */
108 
109 	dev_info.dev_private = &app_info;
110 
111 	ret = rte_rawdev_configure(dev_id, &dev_info, sizeof(app_info));
112 	if (ret) {
113 		otx2_err("Unable to configure SDP_VF %d", dev_id);
114 		rte_mempool_free(ioq_mpool);
115 		return -ENOMEM;
116 	}
117 	otx2_info("SDP VF rawdev[%d] configured successfully", dev_id);
118 
119 	memset(&si, 0x00, sizeof(si));
120 	memset(&sdpvf, 0x00, sizeof(sdpvf));
121 
122 	buf_size = SDP_TEST_PKT_SIZE;
123 
124 	si.q_no = 0;
125 	si.reqtype = SDP_REQTYPE_NORESP;
126 	si.rptr = NULL;
127 
128 	si.ih.fsz = SDP_TEST_PKT_FSZ;
129 	si.ih.tlen = buf_size;
130 	si.ih.gather = 0;
131 
132 	/* Enqueue raw pkt data */
133 	rte_mempool_get(ioq_mpool, &buf);
134 	if (!buf) {
135 		otx2_err("Buffer allocation failed");
136 		rte_mempool_free(ioq_mpool);
137 		rte_rawdev_close(dev_id);
138 		return -ENOMEM;
139 	}
140 
141 	sdp_ioq_buffer_fill(buf, buf_size);
142 	si.dptr = (uint8_t *)buf;
143 
144 	rte_rawdev_enqueue_buffers(dev_id, NULL, 1, &si);
145 	usleep(10000);
146 
147 	/* Dequeue raw pkt data */
148 	ret = 0;
149 	while (ret < 1) {
150 		ret = rte_rawdev_dequeue_buffers(dev_id, &d_buf[0], 1, &si);
151 		rte_pause();
152 	}
153 
154 	/* Validate the dequeued raw pkt data */
155 	if (sdp_validate_data((struct sdp_droq_pkt *)d_buf[0],
156 			      buf, buf_size) != 0) {
157 		otx2_err("Data invalid");
158 		rte_mempool_put(ioq_mpool,
159 				((struct sdp_droq_pkt *)d_buf[0])->data);
160 		rte_mempool_free(ioq_mpool);
161 		rte_rawdev_close(dev_id);
162 		return -EINVAL;
163 	}
164 
165 	rte_mempool_put(ioq_mpool, ((struct sdp_droq_pkt *)d_buf[0])->data);
166 	rte_mempool_free(ioq_mpool);
167 	rte_rawdev_close(dev_id);
168 
169 	otx2_info("SDP RAWDEV Self Test: Successful");
170 
171 	return 0;
172 }
173