DPDK logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(C) 2019 Marvell International Ltd.
 */

#ifndef _OTX2_EP_RAWDEV_H_
#define _OTX2_EP_RAWDEV_H_

#include <rte_byteorder.h>
#include <rte_spinlock.h>

/* IQ instruction req types */
#define SDP_REQTYPE_NONE             (0)
#define SDP_REQTYPE_NORESP           (1)
#define SDP_REQTYPE_NORESP_GATHER    (2)

/* Input Request Header format */
struct sdp_instr_irh {
	/* Request ID  */
	uint64_t rid:16;

	/* PCIe port to use for response */
	uint64_t pcie_port:3;

	/* Scatter indicator  1=scatter */
	uint64_t scatter:1;

	/* Size of Expected result OR no. of entries in scatter list */
	uint64_t rlenssz:14;

	/* Desired destination port for result */
	uint64_t dport:6;

	/* Opcode Specific parameters */
	uint64_t param:8;

	/* Opcode for the return packet  */
	uint64_t opcode:16;
};

/* SDP 32B instruction format */
struct sdp_instr_32B {
	/* Pointer where the input data is available. */
	uint64_t dptr;

	/* SDP Instruction Header.  */
	uint64_t ih;

	/** Pointer where the response for a RAW mode packet
	 *  will be written by OCTEON TX2.
	 */
	uint64_t rptr;

	/* Input Request Header. Additional info about the input. */
	uint64_t irh;
};
#define SDP_32B_INSTR_SIZE	(sizeof(sdp_instr_32B))

/* SDP 64B instruction format */
struct sdp_instr_64B {
	/* Pointer where the input data is available. */
	uint64_t dptr;

	/* SDP Instruction Header. */
	uint64_t ih;

	/** Pointer where the response for a RAW mode packet
	 * will be written by OCTEON TX2.
	 */
	uint64_t rptr;

	/* Input Request Header. */
	uint64_t irh;

	/* Additional headers available in a 64-byte instruction. */
	uint64_t exhdr[4];
};
#define SDP_64B_INSTR_SIZE	(sizeof(sdp_instr_64B))

struct sdp_soft_instr {
	/** Input data pointer. It is either pointing directly to input data
	 *  or to a gather list.
	 */
	void *dptr;

	/** Response from OCTEON TX2 comes at this address. It is either
	 *  directlty pointing to output data buffer or to a scatter list.
	 */
	void *rptr;

	/* The instruction header. All input commands have this field. */
	struct sdp_instr_ih ih;

	/* Input request header. */
	struct sdp_instr_irh irh;

	/** The PCI instruction to be sent to OCTEON TX2. This is stored in the
	 *  instr to retrieve the physical address of buffers when instr is
	 *  freed.
	 */
	struct sdp_instr_64B command;

	/** If a gather list was allocated, this ptr points to the buffer used
	 *  for the gather list. The gather list has to be 8B aligned, so this
	 *  value may be different from dptr.
	 */
	void *gather_ptr;

	/* Total data bytes transferred in the gather mode request. */
	uint64_t gather_bytes;

	/** If a scatter list was allocated, this ptr points to the buffer used
	 *  for the scatter list. The scatter list has to be 8B aligned, so
	 *  this value may be different from rptr.
	 */
	void *scatter_ptr;

	/* Total data bytes to be received in the scatter mode request. */
	uint64_t scatter_bytes;

	/* IQ number to which this instruction has to be submitted. */
	uint32_t q_no;

	/* IQ instruction request type. */
	uint32_t reqtype;
};
#define SDP_SOFT_INSTR_SIZE	(sizeof(sdp_soft_instr))

/* SDP IQ request list */
struct sdp_instr_list {
	void *buf;
	uint32_t reqtype;
};
#define SDP_IQREQ_LIST_SIZE	(sizeof(struct sdp_instr_list))

/* Input Queue statistics. Each input queue has four stats fields. */
struct sdp_iq_stats {
	uint64_t instr_posted; /* Instructions posted to this queue. */
	uint64_t instr_processed; /* Instructions processed in this queue. */
	uint64_t instr_dropped; /* Instructions that could not be processed */
};

/* Structure to define the configuration attributes for each Input queue. */
struct sdp_iq_config {
	/* Max number of IQs available */
	uint16_t max_iqs;

	/* Command size - 32 or 64 bytes */
	uint16_t instr_type;

	/* Pending list size, usually set to the sum of the size of all IQs */
	uint32_t pending_list_size;
};

/** The instruction (input) queue.
 *  The input queue is used to post raw (instruction) mode data or packet data
 *  to OCTEON TX2 device from the host. Each IQ of a SDP EP VF device has one
 *  such structure to represent it.
 */
struct sdp_instr_queue {
	/* A spinlock to protect access to the input ring.  */
	rte_spinlock_t lock;
	rte_spinlock_t post_lock;

	struct sdp_device *sdp_dev;
	rte_atomic64_t iq_flush_running;

	uint32_t q_no;
	uint32_t pkt_in_done;

	/* Flag for 64 byte commands. */
	uint32_t iqcmd_64B:1;
	uint32_t rsvd:17;
	uint32_t status:8;

	/* Number of  descriptors in this ring. */
	uint32_t nb_desc;

	/* Input ring index, where the driver should write the next packet */
	uint32_t host_write_index;

	/* Input ring index, where the OCTEON TX2 should read the next packet */
	uint32_t otx_read_index;

	/** This index aids in finding the window in the queue where OCTEON TX2
	 *  has read the commands.
	 */
	uint32_t flush_index;

	/* This keeps track of the instructions pending in this queue. */
	rte_atomic64_t instr_pending;

	uint32_t reset_instr_cnt;

	/* Pointer to the Virtual Base addr of the input ring. */
	uint8_t *base_addr;

	/* This IQ request list */
	struct sdp_instr_list *req_list;

	/* SDP doorbell register for the ring. */
	void *doorbell_reg;

	/* SDP instruction count register for this ring. */
	void *inst_cnt_reg;

	/* Number of instructions pending to be posted to OCTEON TX2. */
	uint32_t fill_cnt;

	/* Statistics for this input queue. */
	struct sdp_iq_stats stats;

	/* DMA mapped base address of the input descriptor ring. */
	uint64_t base_addr_dma;

	/* Memory zone */
	const struct rte_memzone *iq_mz;
};

/* DROQ packet format for application i/f. */
struct sdp_droq_pkt {
	/* DROQ packet data buffer pointer. */
	uint8_t	 *data;

	/* DROQ packet data length */
	uint32_t len;

	uint32_t misc;
};

/** Descriptor format.
 *  The descriptor ring is made of descriptors which have 2 64-bit values:
 *  -# Physical (bus) address of the data buffer.
 *  -# Physical (bus) address of a sdp_droq_info structure.
 *  The device DMA's incoming packets and its information at the address
 *  given by these descriptor fields.
 */
struct sdp_droq_desc {
	/* The buffer pointer */
	uint64_t buffer_ptr;

	/* The Info pointer */
	uint64_t info_ptr;
};
#define SDP_DROQ_DESC_SIZE	(sizeof(struct sdp_droq_desc))

/* Receive Header */
union sdp_rh {
	uint64_t rh64;
};
#define SDP_RH_SIZE (sizeof(union sdp_rh))

/** Information about packet DMA'ed by OCTEON TX2.
 *  The format of the information available at Info Pointer after OCTEON TX2
 *  has posted a packet. Not all descriptors have valid information. Only
 *  the Info field of the first descriptor for a packet has information
 *  about the packet.
 */
struct sdp_droq_info {
	/* The Output Receive Header. */
	union sdp_rh rh;

	/* The Length of the packet. */
	uint64_t length;
};
#define SDP_DROQ_INFO_SIZE	(sizeof(struct sdp_droq_info))

/** Pointer to data buffer.
 *  Driver keeps a pointer to the data buffer that it made available to
 *  the OCTEON TX2 device. Since the descriptor ring keeps physical (bus)
 *  addresses, this field is required for the driver to keep track of
 *  the virtual address pointers.
 */
struct sdp_recv_buffer {
	/* Packet buffer, including meta data. */
	void *buffer;

	/* Data in the packet buffer. */
	/* uint8_t *data; */
};
#define SDP_DROQ_RECVBUF_SIZE	(sizeof(struct sdp_recv_buffer))

/* DROQ statistics. Each output queue has four stats fields. */
struct sdp_droq_stats {
	/* Number of packets received in this queue. */
	uint64_t pkts_received;

	/* Bytes received by this queue. */
	uint64_t bytes_received;

	/* Num of failures of rte_pktmbuf_alloc() */
	uint64_t rx_alloc_failure;
};

/* Structure to define the configuration attributes for each Output queue. */
struct sdp_oq_config {
	/* Max number of OQs available */
	uint16_t max_oqs;

	/* If set, the Output queue uses info-pointer mode. (Default: 1 ) */
	uint16_t info_ptr;

	/** The number of buffers that were consumed during packet processing by
	 *  the driver on this Output queue before the driver attempts to
	 *  replenish the descriptor ring with new buffers.
	 */
	uint32_t refill_threshold;
};

/* The Descriptor Ring Output Queue(DROQ) structure. */
struct sdp_droq {
	/* A spinlock to protect access to this ring. */
	rte_spinlock_t lock;

	struct sdp_device *sdp_dev;
	/* The 8B aligned descriptor ring starts at this address. */
	struct sdp_droq_desc *desc_ring;

	uint32_t q_no;
	uint32_t last_pkt_count;

	/* Driver should read the next packet at this index */
	uint32_t read_idx;

	/* OCTEON TX2 will write the next packet at this index */
	uint32_t write_idx;

	/* At this index, the driver will refill the descriptor's buffer */
	uint32_t refill_idx;

	/* Packets pending to be processed */
	rte_atomic64_t pkts_pending;

	/* Number of descriptors in this ring. */
	uint32_t nb_desc;

	/* The number of descriptors pending to refill. */
	uint32_t refill_count;

	uint32_t refill_threshold;

	/* The 8B aligned info ptrs begin from this address. */
	struct sdp_droq_info *info_list;

	/* receive buffer list contains virtual addresses of the buffers. */
	struct sdp_recv_buffer *recv_buf_list;

	/* The size of each buffer pointed by the buffer pointer. */
	uint32_t buffer_size;

	/** Pointer to the mapped packet credit register.
	 *  Host writes number of info/buffer ptrs available to this register
	 */
	void *pkts_credit_reg;

	/** Pointer to the mapped packet sent register. OCTEON TX2 writes the
	 *  number of packets DMA'ed to host memory in this register.
	 */
	void *pkts_sent_reg;

	/* Statistics for this DROQ. */
	struct sdp_droq_stats stats;

	/* DMA mapped address of the DROQ descriptor ring. */
	size_t desc_ring_dma;

	/* Info_ptr list is allocated at this virtual address. */
	size_t info_base_addr;

	/* DMA mapped address of the info list */
	size_t info_list_dma;

	/* Allocated size of info list. */
	uint32_t info_alloc_size;

	/* Memory zone **/
	const struct rte_memzone *desc_ring_mz;
	const struct rte_memzone *info_mz;
};
#define SDP_DROQ_SIZE		(sizeof(struct sdp_droq))

/* IQ/OQ mask */
struct sdp_io_enable {
	uint64_t iq;
	uint64_t oq;
	uint64_t iq64B;
};

/* Structure to define the configuration. */
struct sdp_config {
	/* Input Queue attributes. */
	struct sdp_iq_config iq;

	/* Output Queue attributes. */
	struct sdp_oq_config oq;

	/* Num of desc for IQ rings */
	uint32_t num_iqdef_descs;

	/* Num of desc for OQ rings */
	uint32_t num_oqdef_descs;

	/* OQ buffer size */
	uint32_t oqdef_buf_size;
};

/* Required functions for each VF device */
struct sdp_fn_list {
	void (*setup_iq_regs)(struct sdp_device *sdpvf, uint32_t q_no);
	void (*setup_oq_regs)(struct sdp_device *sdpvf, uint32_t q_no);

	int (*setup_device_regs)(struct sdp_device *sdpvf);
	uint32_t (*update_iq_read_idx)(struct sdp_instr_queue *iq);

	void (*enable_io_queues)(struct sdp_device *sdpvf);
	void (*disable_io_queues)(struct sdp_device *sdpvf);

	void (*enable_iq)(struct sdp_device *sdpvf, uint32_t q_no);
	void (*disable_iq)(struct sdp_device *sdpvf, uint32_t q_no);

	void (*enable_oq)(struct sdp_device *sdpvf, uint32_t q_no);
	void (*disable_oq)(struct sdp_device *sdpvf, uint32_t q_no);
};

/* SRIOV information */
struct sdp_sriov_info {
	/* Number of rings assigned to VF */
	uint32_t rings_per_vf;

	/* Number of VF devices enabled */
	uint32_t num_vfs;
};


/* Information to be passed from application */
struct sdp_rawdev_info {
	struct rte_mempool *enqdeq_mpool;
	const struct sdp_config *app_conf;
};

/* SDP EP VF device */
struct sdp_device {
	/* PCI device pointer */
	struct rte_pci_device *pci_dev;
	uint16_t chip_id;
	uint16_t pf_num;
	uint16_t vf_num;

	/* This device's PCIe port used for traffic. */
	uint16_t pcie_port;
	uint32_t pkind;

	/* The state of this device */
	rte_atomic64_t status;

	/* Memory mapped h/w address */
	uint8_t *hw_addr;

	struct sdp_fn_list fn_list;

	/* Num IQs */
	uint32_t num_iqs;

	/* The input instruction queues */
	struct sdp_instr_queue *instr_queue[SDP_VF_MAX_IOQS_PER_RAWDEV];

	/* Num OQs */
	uint32_t num_oqs;

	/* The DROQ output queues  */
	struct sdp_droq *droq[SDP_VF_MAX_IOQS_PER_RAWDEV];

	/* IOQ data buffer pool */
	struct rte_mempool *enqdeq_mpool;

	/* IOQ mask */
	struct sdp_io_enable io_qmask;

	/* SR-IOV info */
	struct sdp_sriov_info sriov_info;

	/* Device configuration */
	const struct sdp_config *conf;
};

const struct sdp_config *sdp_get_defconf(struct sdp_device *sdp_dev);
int sdp_setup_iqs(struct sdp_device *sdpvf, uint32_t iq_no);
int sdp_delete_iqs(struct sdp_device *sdpvf, uint32_t iq_no);

int sdp_setup_oqs(struct sdp_device *sdpvf, uint32_t oq_no);
int sdp_delete_oqs(struct sdp_device *sdpvf, uint32_t oq_no);

int sdp_rawdev_enqueue(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers,
		       unsigned int count, rte_rawdev_obj_t context);
int sdp_rawdev_dequeue(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers,
		       unsigned int count, rte_rawdev_obj_t context);

int sdp_rawdev_selftest(uint16_t dev_id);

#endif /* _OTX2_EP_RAWDEV_H_ */