net/liquidio: add APIs for SG list
Add APIs to setup and free Scatter-Gather list. SG list is used while sending packets with multiple segments. Signed-off-by: Shijith Thotton <shijith.thotton@caviumnetworks.com> Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com> Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com> Signed-off-by: Venkat Koppula <venkat.koppula@caviumnetworks.com> Signed-off-by: Srisivasubramanian S <ssrinivasan@caviumnetworks.com> Signed-off-by: Mallesham Jatharakonda <mjatharakonda@oneconvergence.com>
This commit is contained in:
parent
1d395422f8
commit
990c41eea8
@ -202,6 +202,15 @@ lio_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t q_no,
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = lio_setup_sglists(lio_dev, q_no, fw_mapped_iq,
|
||||
lio_dev->instr_queue[fw_mapped_iq]->max_count,
|
||||
socket_id);
|
||||
|
||||
if (retval) {
|
||||
lio_delete_instruction_queue(lio_dev, fw_mapped_iq);
|
||||
return retval;
|
||||
}
|
||||
|
||||
eth_dev->data->tx_queues[q_no] = lio_dev->instr_queue[fw_mapped_iq];
|
||||
|
||||
return 0;
|
||||
@ -334,6 +343,20 @@ static int lio_dev_configure(struct rte_eth_dev *eth_dev)
|
||||
/* Copy the permanent MAC address */
|
||||
ether_addr_copy((struct ether_addr *)mac, ð_dev->data->mac_addrs[0]);
|
||||
|
||||
lio_dev->glist_lock =
|
||||
rte_zmalloc(NULL, sizeof(*lio_dev->glist_lock) * num_iqueues, 0);
|
||||
if (lio_dev->glist_lock == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
lio_dev->glist_head =
|
||||
rte_zmalloc(NULL, sizeof(*lio_dev->glist_head) * num_iqueues,
|
||||
0);
|
||||
if (lio_dev->glist_head == NULL) {
|
||||
rte_free(lio_dev->glist_lock);
|
||||
lio_dev->glist_lock = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lio_dev->port_configured = 1;
|
||||
|
||||
lio_free_soft_command(sc);
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "lio_ethdev.h"
|
||||
#include "lio_rxtx.h"
|
||||
|
||||
#define LIO_MAX_SG 12
|
||||
|
||||
static void
|
||||
lio_droq_compute_max_packet_bufs(struct lio_droq *droq)
|
||||
{
|
||||
@ -1272,3 +1274,108 @@ lio_process_ordered_list(struct lio_device *lio_dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct lio_stailq_node *
|
||||
list_delete_first_node(struct lio_stailq_head *head)
|
||||
{
|
||||
struct lio_stailq_node *node;
|
||||
|
||||
if (STAILQ_EMPTY(head))
|
||||
node = NULL;
|
||||
else
|
||||
node = STAILQ_FIRST(head);
|
||||
|
||||
if (node)
|
||||
STAILQ_REMOVE(head, node, lio_stailq_node, entries);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
lio_delete_sglist(struct lio_instr_queue *txq)
|
||||
{
|
||||
struct lio_device *lio_dev = txq->lio_dev;
|
||||
int iq_no = txq->q_index;
|
||||
struct lio_gather *g;
|
||||
|
||||
if (lio_dev->glist_head == NULL)
|
||||
return;
|
||||
|
||||
do {
|
||||
g = (struct lio_gather *)list_delete_first_node(
|
||||
&lio_dev->glist_head[iq_no]);
|
||||
if (g) {
|
||||
if (g->sg)
|
||||
rte_free(
|
||||
(void *)((unsigned long)g->sg - g->adjust));
|
||||
rte_free(g);
|
||||
}
|
||||
} while (g);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setup gather lists
|
||||
* @param lio per-network private data
|
||||
*/
|
||||
int
|
||||
lio_setup_sglists(struct lio_device *lio_dev, int iq_no,
|
||||
int fw_mapped_iq, int num_descs, unsigned int socket_id)
|
||||
{
|
||||
struct lio_gather *g;
|
||||
int i;
|
||||
|
||||
rte_spinlock_init(&lio_dev->glist_lock[iq_no]);
|
||||
|
||||
STAILQ_INIT(&lio_dev->glist_head[iq_no]);
|
||||
|
||||
for (i = 0; i < num_descs; i++) {
|
||||
g = rte_zmalloc_socket(NULL, sizeof(*g), RTE_CACHE_LINE_SIZE,
|
||||
socket_id);
|
||||
if (g == NULL) {
|
||||
lio_dev_err(lio_dev,
|
||||
"lio_gather memory allocation failed for qno %d\n",
|
||||
iq_no);
|
||||
break;
|
||||
}
|
||||
|
||||
g->sg_size =
|
||||
((ROUNDUP4(LIO_MAX_SG) >> 2) * LIO_SG_ENTRY_SIZE);
|
||||
|
||||
g->sg = rte_zmalloc_socket(NULL, g->sg_size + 8,
|
||||
RTE_CACHE_LINE_SIZE, socket_id);
|
||||
if (g->sg == NULL) {
|
||||
lio_dev_err(lio_dev,
|
||||
"sg list memory allocation failed for qno %d\n",
|
||||
iq_no);
|
||||
rte_free(g);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The gather component should be aligned on 64-bit boundary */
|
||||
if (((unsigned long)g->sg) & 7) {
|
||||
g->adjust = 8 - (((unsigned long)g->sg) & 7);
|
||||
g->sg =
|
||||
(struct lio_sg_entry *)((unsigned long)g->sg +
|
||||
g->adjust);
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(&lio_dev->glist_head[iq_no], &g->list,
|
||||
entries);
|
||||
}
|
||||
|
||||
if (i != num_descs) {
|
||||
lio_delete_sglist(lio_dev->instr_queue[fw_mapped_iq]);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lio_delete_instruction_queue(struct lio_device *lio_dev, int iq_no)
|
||||
{
|
||||
lio_delete_instr_queue(lio_dev, iq_no);
|
||||
rte_free(lio_dev->instr_queue[iq_no]);
|
||||
lio_dev->instr_queue[iq_no] = NULL;
|
||||
lio_dev->num_iqs--;
|
||||
}
|
||||
|
@ -42,6 +42,10 @@
|
||||
|
||||
#include "lio_struct.h"
|
||||
|
||||
#ifndef ROUNDUP4
|
||||
#define ROUNDUP4(val) (((val) + 3) & 0xfffffffc)
|
||||
#endif
|
||||
|
||||
#define LIO_STQUEUE_FIRST_ENTRY(ptr, type, elem) \
|
||||
(type *)((char *)((ptr)->stqh_first) - offsetof(type, elem))
|
||||
|
||||
@ -548,9 +552,12 @@ uint16_t lio_dev_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
|
||||
uint16_t budget);
|
||||
void lio_delete_droq_queue(struct lio_device *lio_dev, int oq_no);
|
||||
|
||||
int lio_setup_sglists(struct lio_device *lio_dev, int iq_no,
|
||||
int fw_mapped_iq, int num_descs, unsigned int socket_id);
|
||||
int lio_setup_iq(struct lio_device *lio_dev, int q_index,
|
||||
union octeon_txpciq iq_no, uint32_t num_descs, void *app_ctx,
|
||||
unsigned int socket_id);
|
||||
void lio_delete_instruction_queue(struct lio_device *lio_dev, int iq_no);
|
||||
/** Setup instruction queue zero for the device
|
||||
* @param lio_dev which lio device to setup
|
||||
*
|
||||
|
@ -298,6 +298,41 @@ struct lio_instr_queue {
|
||||
const struct rte_memzone *iq_mz;
|
||||
};
|
||||
|
||||
/* The Scatter-Gather List Entry. The scatter or gather component used with
|
||||
* input instruction has this format.
|
||||
*/
|
||||
struct lio_sg_entry {
|
||||
/** The first 64 bit gives the size of data in each dptr. */
|
||||
union {
|
||||
uint16_t size[4];
|
||||
uint64_t size64;
|
||||
} u;
|
||||
|
||||
/** The 4 dptr pointers for this entry. */
|
||||
uint64_t ptr[4];
|
||||
};
|
||||
|
||||
#define LIO_SG_ENTRY_SIZE (sizeof(struct lio_sg_entry))
|
||||
|
||||
/** Structure of a node in list of gather components maintained by
|
||||
* driver for each network device.
|
||||
*/
|
||||
struct lio_gather {
|
||||
/** List manipulation. Next and prev pointers. */
|
||||
struct lio_stailq_node list;
|
||||
|
||||
/** Size of the gather component at sg in bytes. */
|
||||
int sg_size;
|
||||
|
||||
/** Number of bytes that sg was adjusted to make it 8B-aligned. */
|
||||
int adjust;
|
||||
|
||||
/** Gather component that can accommodate max sized fragment list
|
||||
* received from the IP layer.
|
||||
*/
|
||||
struct lio_sg_entry *sg;
|
||||
};
|
||||
|
||||
struct lio_io_enable {
|
||||
uint64_t iq;
|
||||
uint64_t oq;
|
||||
@ -516,6 +551,11 @@ struct lio_device {
|
||||
|
||||
uint32_t num_iqs;
|
||||
|
||||
/** Guards each glist */
|
||||
rte_spinlock_t *glist_lock;
|
||||
/** Array of gather component linked lists */
|
||||
struct lio_stailq_head *glist_head;
|
||||
|
||||
/* The pool containing pre allocated buffers used for soft commands */
|
||||
struct rte_mempool *sc_buf_pool;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user