@@ -60,8 +60,6 @@ typedef struct odp_buffer_hdr_t {
void *buf_vaddr;
uint32_t free_queue;
int type;
- struct odp_buffer_hdr_t *next; /* next buf in a list */
- odp_buffer_bits_t handle; /* handle */
} odp_buffer_hdr_t;
@@ -72,6 +72,7 @@ static inline void *get_pool_entry(odp_buffer_pool_t pool_id)
{
return pool_entry_ptr[pool_id];
}
+uint32_t _odp_pool_get_free_queue(odp_buffer_pool_t pool_id);
#ifdef __cplusplus
}
@@ -110,19 +110,11 @@ typedef struct {
uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */
uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */
- uint32_t frame_len;
-
odp_pktio_t input;
- uint32_t pad;
- uint8_t payload[];
-
} odp_packet_hdr_t;
-ODP_ASSERT(sizeof(odp_packet_hdr_t) == ODP_OFFSETOF(odp_packet_hdr_t, payload),
- ODP_PACKET_HDR_T__SIZE_ERR);
-ODP_ASSERT(sizeof(odp_packet_hdr_t) % sizeof(uint64_t) == 0,
- ODP_PACKET_HDR_T__SIZE_ERR2);
+ODP_ASSERT(sizeof(odp_packet_hdr_t) <= 128, ODP_PACKET_HDR_T_SIZE_ERROR);
/**
* Return the packet header
@@ -132,6 +124,11 @@ static inline odp_packet_hdr_t *odp_packet_hdr(odp_packet_t pkt)
return (odp_packet_hdr_t *)odp_buf_to_hdr((odp_buffer_t)pkt);
}
+static inline odp_packet_hdr_t *odp_bufhdr_to_pkthdr(odp_buffer_hdr_t *hdr)
+{
+ return (odp_packet_hdr_t *)hdr;
+}
+
/**
* Parse packet and set internal metadata
*/
@@ -24,17 +24,22 @@ extern "C" {
#include <odp_packet_netmap.h>
#endif
+#define PKTIO_DEV_MAX_NAME_LEN 10
+struct pktio_device {
+ const char name[PKTIO_DEV_MAX_NAME_LEN];
+ uint32_t tx_hw_queue;
+ uint32_t rx_channel;
+ uint32_t rx_flow;
+ uint32_t port_id;
+};
+
struct pktio_entry {
odp_spinlock_t lock; /**< entry spinlock */
int taken; /**< is entry taken(1) or free(0) */
odp_queue_t inq_default; /**< default input queue, if set */
odp_queue_t outq_default; /**< default out queue */
- odp_pktio_params_t params; /**< pktio parameters */
- pkt_sock_t pkt_sock; /**< using socket API for IO */
- pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap API for IO */
-#ifdef ODP_HAVE_NETMAP
- pkt_netmap_t pkt_nm; /**< using netmap API for IO */
-#endif
+ odp_buffer_pool_t in_pool;
+ struct pktio_device *dev;
};
typedef union {
@@ -73,6 +73,7 @@ struct queue_entry_s {
odp_queue_param_t param;
odp_pktio_t pktin;
odp_pktio_t pktout;
+ uint32_t out_port_id;
uint32_t hw_queue;
char name[ODP_QUEUE_NAME_LEN];
};
@@ -59,15 +59,16 @@ int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf)
len += snprintf(&str[len], n-len,
" buf_paddr 0x%x\n", desc->desc.buffPtr);
len += snprintf(&str[len], n-len,
+ " buf_len_o 0x%x\n", desc->desc.origBufferLen);
+ len += snprintf(&str[len], n-len,
+ " buf_len 0x%x\n", desc->desc.buffLen);
+ len += snprintf(&str[len], n-len,
" pool %i\n", odp_buf_to_pool(buf));
len += snprintf(&str[len], n-len,
" free_queue %u\n", desc->free_queue);
len += snprintf(&str[len], n-len, "\n");
- ti_em_rh_dump_mem(desc, sizeof(*desc), "Descriptor dump");
- ti_em_rh_dump_mem(desc->buf_vaddr, 64, "Buffer start");
-
return len;
}
@@ -77,11 +78,18 @@ void odp_buffer_print(odp_buffer_t buf)
int max_len = 512;
char str[max_len];
int len;
+ odp_buffer_hdr_t *desc;
len = odp_buffer_snprint(str, max_len-1, buf);
+ if (!len)
+ return;
str[len] = 0;
printf("\n%s\n", str);
+
+ desc = odp_buf_to_hdr(buf);
+ ti_em_rh_dump_mem(desc, sizeof(*desc), "Descriptor dump");
+ ti_em_rh_dump_mem(desc->buf_vaddr, 64, "Buffer start");
}
void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src)
@@ -163,6 +163,7 @@ static int link_bufs(pool_entry_t *pool)
(void *)buf_addr.v, (void *)buf_addr.p);
ODP_DBG("%s: num_bufs: %u, desc_index: %u\n", __func__,
num_bufs, desc_index);
+ ODP_DBG("%s: free_queue: %u\n", __func__, pool->s.free_queue);
/* FIXME: Need to define error codes somewhere */
if (desc_index == (uint32_t)-1) {
@@ -195,10 +196,9 @@ static int link_bufs(pool_entry_t *pool)
/* Set defaults in descriptor */
hdr->desc.descInfo = (Cppi_DescType_HOST << 30) |
(Cppi_PSLoc_PS_IN_DESC << 22) |
- (buf_size & 0xFFFF);
+ (pool->s.payload_size & 0xFFFF);
hdr->desc.packetInfo =
(((uint32_t) Cppi_EPIB_EPIB_PRESENT) << 31) |
- (0x2 << 16) |
(((uint32_t) Cppi_ReturnPolicy_RETURN_BUFFER) << 15) |
(pool->s.free_queue & 0x3FFF);
hdr->desc.origBuffPtr = buf_addr.p;
@@ -308,3 +308,9 @@ void odp_buffer_pool_print(odp_buffer_pool_t pool_id)
{
(void)pool_id;
}
+
+uint32_t _odp_pool_get_free_queue(odp_buffer_pool_t pool_id)
+{
+ pool_entry_t *pool = get_pool_entry(pool_id);
+ return pool->s.free_queue;
+}
@@ -12,7 +12,7 @@
#include <ti_em_osal_queue.h>
#include <ti_em_rh.h>
#include <odp_config.h>
-#include <odp_buffer_internal.h>
+#include <odp_packet_internal.h>
/*
* Make region_configs[] global, because hw_config is saved in
@@ -49,7 +49,7 @@ static int ti_init_hw_config(void)
reg_config = ®ion_configs[TI_EM_RH_PUBLIC];
reg_config->region_idx = TI_ODP_PUBLIC_REGION_IDX;
reg_config->desc_size =
- ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(odp_buffer_hdr_t));
+ ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(odp_packet_hdr_t));
reg_config->desc_num = TI_ODP_PUBLIC_DESC_NUM;
reg_config->desc_base = TI_ODP_PUBLIC_DESC_BASE;
reg_config->desc_vbase = TI_ODP_PUBLIC_DESC_VBASE;
@@ -8,6 +8,7 @@
#include <odp_packet_internal.h>
#include <odp_hints.h>
#include <odp_byteorder.h>
+#include <ti_em_rh.h>
#include <helper/odp_eth.h>
#include <helper/odp_ip.h>
@@ -16,20 +17,13 @@
#include <stdio.h>
static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
- size_t *offset_out);
+ size_t *offset_out);
static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
- size_t *offset_out);
+ size_t *offset_out);
void odp_packet_init(odp_packet_t pkt)
{
odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt);
- const size_t start_offset = ODP_FIELD_SIZEOF(odp_packet_hdr_t, buf_hdr);
- uint8_t *start;
- size_t len;
-
- start = (uint8_t *)pkt_hdr + start_offset;
- len = ODP_OFFSETOF(odp_packet_hdr_t, payload) - start_offset;
- memset(start, 0, len);
pkt_hdr->l2_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
pkt_hdr->l3_offset = (uint32_t) ODP_PACKET_OFFSET_INVALID;
@@ -48,12 +42,12 @@ odp_buffer_t odp_buffer_from_packet(odp_packet_t pkt)
void odp_packet_set_len(odp_packet_t pkt, size_t len)
{
- odp_packet_hdr(pkt)->frame_len = len;
+ ti_em_cppi_set_pktlen(&odp_packet_hdr(pkt)->buf_hdr.desc, len);
}
size_t odp_packet_get_len(odp_packet_t pkt)
{
- return odp_packet_hdr(pkt)->frame_len;
+ return ti_em_cppi_get_pktlen(&odp_packet_hdr(pkt)->buf_hdr.desc);
}
uint8_t *odp_packet_buf_addr(odp_packet_t pkt)
@@ -130,8 +124,9 @@ void odp_packet_set_l4_offset(odp_packet_t pkt, size_t offset)
/**
* Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP
*
- * Internal function: caller is resposible for passing only valid packet handles
- * , lengths and offsets (usually done&called in packet input).
+ * Internal function: caller is responsible for passing only
+ * valid packet handles, lengths and offsets
+ * (usually done&called in packet input).
*
* @param pkt Packet handle
* @param len Packet length in bytes
@@ -150,7 +145,6 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
pkt_hdr->input_flags.eth = 1;
pkt_hdr->frame_offset = frame_offset;
- pkt_hdr->frame_len = len;
if (odp_unlikely(len < ODP_ETH_LEN_MIN)) {
pkt_hdr->error_flags.frame_len = 1;
@@ -159,6 +153,9 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
pkt_hdr->input_flags.jumbo = 1;
}
+ len -= 4; /* Crop L2 CRC */
+ ti_em_cppi_set_pktlen(&pkt_hdr->buf_hdr.desc, len);
+
/* Assume valid L2 header, no CRC/FCS check in SW */
pkt_hdr->input_flags.l2 = 1;
pkt_hdr->l2_offset = frame_offset;
@@ -236,7 +233,7 @@ void odp_packet_parse(odp_packet_t pkt, size_t len, size_t frame_offset)
}
static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
- size_t *offset_out)
+ size_t *offset_out)
{
uint8_t ihl;
uint16_t frag_offset;
@@ -276,7 +273,7 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, odp_ipv4hdr_t *ipv4,
}
static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odp_ipv6hdr_t *ipv6,
- size_t *offset_out)
+ size_t *offset_out)
{
if (ipv6->next_hdr == ODP_IPPROTO_ESP ||
ipv6->next_hdr == ODP_IPPROTO_AH) {
@@ -321,12 +318,14 @@ void odp_packet_print(odp_packet_t pkt)
len += snprintf(&str[len], n-len,
" l4_offset %u\n", hdr->l4_offset);
len += snprintf(&str[len], n-len,
- " frame_len %u\n", hdr->frame_len);
+ " packet len %u\n", odp_packet_get_len(pkt));
len += snprintf(&str[len], n-len,
" input %u\n", hdr->input);
str[len] = '\0';
printf("\n%s\n", str);
+ ti_em_rh_dump_mem(hdr, sizeof(*hdr), "Descriptor dump");
+ ti_em_rh_dump_mem(hdr->buf_hdr.buf_vaddr, 64, "Buffer start");
}
int odp_packet_copy(odp_packet_t pkt_dst, odp_packet_t pkt_src)
@@ -21,6 +21,7 @@
#include <odp_queue_internal.h>
#include <odp_schedule_internal.h>
#include <odp_debug.h>
+#include <odp_buffer_pool_internal.h>
#include <odp_pktio_socket.h>
#ifdef ODP_HAVE_NETMAP
@@ -35,6 +36,23 @@ typedef struct {
static pktio_table_t *pktio_tbl;
+struct pktio_device pktio_devs[] = {
+ /* eth0 is used by Linux kernel */
+ /* {.name = "eth0", .tx_hw_queue = 648, .rx_channel = 22, .rx_flow = 22, .port_id = 1}, */
+ {.name = "eth1", .tx_hw_queue = 648, .rx_channel = 23, .rx_flow = 23, .port_id = 2},
+ {.name = "eth2", .tx_hw_queue = 648, .rx_channel = 24, .rx_flow = 24, .port_id = 3},
+ {.name = "eth3", .tx_hw_queue = 648, .rx_channel = 25, .rx_flow = 25, .port_id = 4},
+};
+
+static struct pktio_device *_odp_pktio_dev_lookup(const char *name)
+{
+ int i;
+ int num = sizeof(pktio_devs)/sizeof(pktio_devs[0]);
+ for (i = 0; i < num; i++)
+ if (!strncmp(pktio_devs[i].name, name, PKTIO_DEV_MAX_NAME_LEN))
+ return &pktio_devs[i];
+ return NULL;
+}
static pktio_entry_t *get_entry(odp_pktio_t id)
{
@@ -47,11 +65,9 @@ static pktio_entry_t *get_entry(odp_pktio_t id)
int odp_pktio_init_global(void)
{
- char name[ODP_QUEUE_NAME_LEN];
pktio_entry_t *pktio_entry;
- queue_entry_t *queue_entry;
- odp_queue_t qid;
- int id;
+ int id, i;
+ int dev_num = sizeof(pktio_devs)/sizeof(pktio_devs[0]);
pktio_tbl = odp_shm_reserve("odp_pktio_entries",
sizeof(pktio_table_t),
@@ -65,20 +81,13 @@ int odp_pktio_init_global(void)
pktio_entry = get_entry(id);
odp_spinlock_init(&pktio_entry->s.lock);
-
- /* Create a default output queue for each pktio resource */
- snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
- name[ODP_QUEUE_NAME_LEN-1] = '\0';
-
- qid = odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL);
- if (qid == ODP_QUEUE_INVALID)
- return -1;
- pktio_entry->s.outq_default = qid;
-
- queue_entry = queue_to_qentry(qid);
- queue_entry->s.pktout = id;
}
+ /* Close all used RX channels */
+ for (i = 0; i < dev_num; i++)
+ ti_em_osal_cppi_rx_channel_close(Cppi_CpDma_PASS_CPDMA,
+ pktio_devs[i].rx_channel);
+
return 0;
}
@@ -112,43 +121,20 @@ static void unlock_entry(pktio_entry_t *entry)
odp_spinlock_unlock(&entry->s.lock);
}
-static void init_pktio_entry(pktio_entry_t *entry, odp_pktio_params_t *params)
-{
- set_taken(entry);
- entry->s.inq_default = ODP_QUEUE_INVALID;
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- memset(&entry->s.pkt_sock, 0, sizeof(entry->s.pkt_sock));
- memset(&entry->s.pkt_sock_mmap, 0,
- sizeof(entry->s.pkt_sock_mmap));
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- memset(&entry->s.pkt_nm, 0, sizeof(entry->s.pkt_nm));
- break;
-#endif
- default:
- ODP_ERR("Packet I/O type not supported. Please recompile\n");
- break;
- }
- /* Save pktio parameters, type is the most useful */
- memcpy(&entry->s.params, params, sizeof(*params));
-}
-
static odp_pktio_t alloc_lock_pktio_entry(odp_pktio_params_t *params)
{
odp_pktio_t id;
pktio_entry_t *entry;
int i;
-
+ (void)params;
for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) {
entry = &pktio_tbl->entries[i];
if (is_free(entry)) {
lock_entry(entry);
if (is_free(entry)) {
- init_pktio_entry(entry, params);
+ set_taken(entry);
+ entry->s.inq_default = ODP_QUEUE_INVALID;
+ entry->s.outq_default = ODP_QUEUE_INVALID;
id = i + 1;
return id; /* return with entry locked! */
}
@@ -176,28 +162,16 @@ odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool,
{
odp_pktio_t id;
pktio_entry_t *pktio_entry;
- int res;
+ char name[ODP_QUEUE_NAME_LEN];
+ queue_entry_t *queue_entry;
+ odp_queue_t qid = ODP_QUEUE_INVALID;
if (params == NULL) {
ODP_ERR("Invalid pktio params\n");
return ODP_PKTIO_INVALID;
}
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- ODP_DBG("Allocating socket pktio\n");
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- ODP_DBG("Allocating netmap pktio\n");
- break;
-#endif
- default:
- ODP_ERR("Invalid pktio type: %02x\n", params->type);
- return ODP_PKTIO_INVALID;
- }
+ ODP_DBG("Allocating HW pktio\n");
id = alloc_lock_pktio_entry(params);
if (id == ODP_PKTIO_INVALID) {
@@ -208,44 +182,33 @@ odp_pktio_t odp_pktio_open(char *dev, odp_buffer_pool_t pool,
pktio_entry = get_entry(id);
- switch (params->type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- res = setup_pkt_sock(&pktio_entry->s.pkt_sock, dev, pool);
- if (res == -1) {
- close_pkt_sock(&pktio_entry->s.pkt_sock);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- res = setup_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, dev,
- pool, params->sock_params.fanout);
- if (res == -1) {
- close_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
-
- res = setup_pkt_netmap(&pktio_entry->s.pkt_nm, dev,
- pool, ¶ms->nm_params);
- if (res == -1) {
- close_pkt_netmap(&pktio_entry->s.pkt_nm);
- free_pktio_entry(id);
- id = ODP_PKTIO_INVALID;
- }
- break;
-#endif
- default:
+ /* Create a default output queue for each pktio resource */
+ snprintf(name, sizeof(name), "%i-pktio_outq_default", (int)id);
+ name[ODP_QUEUE_NAME_LEN-1] = '\0';
+
+ pktio_entry->s.dev = _odp_pktio_dev_lookup(dev);
+ if (!pktio_entry->s.dev) {
+ free_pktio_entry(id);
+ id = ODP_PKTIO_INVALID;
+ goto unlock;
+ }
+
+ qid = _odp_queue_create(name, ODP_QUEUE_TYPE_PKTOUT, NULL,
+ pktio_entry->s.dev->tx_hw_queue);
+ ODP_DBG("Created queue %u for hw queue %d\n", (uint32_t)qid,
+ pktio_entry->s.dev->tx_hw_queue);
+ if (qid == ODP_QUEUE_INVALID) {
free_pktio_entry(id);
id = ODP_PKTIO_INVALID;
- ODP_ERR("This type of I/O is not supported. Please recompile.\n");
- break;
+ goto unlock;
}
+ pktio_entry->s.in_pool = pool;
+ pktio_entry->s.outq_default = qid;
+ queue_entry = queue_to_qentry(qid);
+ queue_entry->s.pktout = id;
+ queue_entry->s.out_port_id = pktio_entry->s.dev->port_id;
+unlock:
unlock_entry(pktio_entry);
return id;
}
@@ -261,24 +224,10 @@ int odp_pktio_close(odp_pktio_t id)
lock_entry(entry);
if (!is_free(entry)) {
- switch (entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- res = close_pkt_sock(&entry->s.pkt_sock);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- res = close_pkt_sock_mmap(&entry->s.pkt_sock_mmap);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- res = close_pkt_netmap(&entry->s.pkt_nm);
- break;
-#endif
- default:
- break;
+ /* FIXME: Here rx/tx channels should be closed */
res |= free_pktio_entry(id);
- }
}
+
unlock_entry(entry);
if (res != 0)
@@ -300,79 +249,71 @@ odp_pktio_t odp_pktio_get_input(odp_packet_t pkt)
int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
{
pktio_entry_t *pktio_entry = get_entry(id);
- int pkts;
- int i;
+ unsigned pkts = 0;
+ odp_buffer_t buf;
if (pktio_entry == NULL)
return -1;
lock_entry(pktio_entry);
- switch (pktio_entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- pkts = recv_pkt_sock_basic(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- pkts = recv_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
- pkt_table, len);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- pkts = recv_pkt_netmap(&pktio_entry->s.pkt_nm, pkt_table, len);
- break;
-#endif
- default:
- pkts = -1;
- break;
- }
- unlock_entry(pktio_entry);
- if (pkts < 0)
- return pkts;
+ if (pktio_entry->s.inq_default == ODP_QUEUE_INVALID) {
+ char name[ODP_QUEUE_NAME_LEN];
+ odp_queue_param_t qparam;
+ odp_queue_t inq_def;
+ /*
+ * Create a default input queue.
+ * FIXME: IT is a kind of WA for current ODP API usage.
+ * It should be revised.
+ */
+ ODP_DBG("Creating default input queue\n");
+ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ qparam.sched.sync = ODP_SCHED_SYNC_NONE;
+ qparam.sched.group = ODP_SCHED_GROUP_DEFAULT;
+ snprintf(name, sizeof(name), "%i-pktio_inq_default", (int)id);
+ name[ODP_QUEUE_NAME_LEN-1] = '\0';
+ inq_def = odp_queue_create(name, ODP_QUEUE_TYPE_PKTIN, &qparam);
+ if (inq_def == ODP_QUEUE_INVALID) {
+ ODP_ERR("pktio queue creation failed\n");
+ goto unlock;
+ }
+
+ if (odp_pktio_inq_setdef(id, inq_def)) {
+ ODP_ERR("default input-Q setup\n");
+ goto unlock;
+ }
+ }
- for (i = 0; i < pkts; ++i)
- odp_pktio_set_input(pkt_table[i], id);
+ for (pkts = 0; pkts < len; pkts++) {
+ buf = odp_queue_deq(pktio_entry->s.inq_default);
+ if (!odp_buffer_is_valid(buf))
+ break;
+ pkt_table[pkts] = odp_packet_from_buffer(buf);
+ }
+unlock:
+ unlock_entry(pktio_entry);
return pkts;
}
int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len)
{
pktio_entry_t *pktio_entry = get_entry(id);
- int pkts;
+ unsigned pkts;
+ int ret;
if (pktio_entry == NULL)
return -1;
lock_entry(pktio_entry);
- switch (pktio_entry->s.params.type) {
- case ODP_PKTIO_TYPE_SOCKET_BASIC:
- pkts = send_pkt_sock_basic(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMSG:
- pkts = send_pkt_sock_mmsg(&pktio_entry->s.pkt_sock,
- pkt_table, len);
- break;
- case ODP_PKTIO_TYPE_SOCKET_MMAP:
- pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap,
- pkt_table, len);
- break;
-#ifdef ODP_HAVE_NETMAP
- case ODP_PKTIO_TYPE_NETMAP:
- pkts = send_pkt_netmap(&pktio_entry->s.pkt_nm,
- pkt_table, len);
- break;
-#endif
- default:
- pkts = -1;
+
+ for (pkts = 0; pkts < len; pkts++) {
+ ret = odp_queue_enq(pktio_entry->s.outq_default,
+ odp_buffer_from_packet(pkt_table[pkts]));
+ if (ret)
+ break;
}
unlock_entry(pktio_entry);
-
return pkts;
}
@@ -387,9 +328,25 @@ int odp_pktio_inq_setdef(odp_pktio_t id, odp_queue_t queue)
if (qentry->s.type != ODP_QUEUE_TYPE_PKTIN)
return -1;
- lock_entry(pktio_entry);
pktio_entry->s.inq_default = queue;
- unlock_entry(pktio_entry);
+ {
+ uint32_t free_queue =
+ _odp_pool_get_free_queue(pktio_entry->s.in_pool);
+ ti_em_osal_cppi_rx_channel_close(Cppi_CpDma_PASS_CPDMA,
+ pktio_entry->s.dev->rx_channel);
+ ti_em_osal_cppi_rx_flow_open(Cppi_CpDma_PASS_CPDMA,
+ pktio_entry->s.dev->rx_flow,
+ qentry->s.hw_queue,
+ free_queue,
+ 0);
+ ti_em_osal_cppi_rx_channel_open(Cppi_CpDma_PASS_CPDMA,
+ pktio_entry->s.dev->rx_channel);
+ ODP_DBG("%s: Opened rx flow %u with dest queue: %u and free queue: %u\n",
+ __func__,
+ pktio_entry->s.dev->rx_flow,
+ qentry->s.hw_queue,
+ free_queue);
+ }
queue_lock(qentry);
qentry->s.pktin = id;
@@ -426,112 +383,54 @@ odp_queue_t odp_pktio_outq_getdef(odp_pktio_t id)
return pktio_entry->s.outq_default;
}
-int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
+int pktout_enqueue(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr)
{
- odp_packet_t pkt = odp_packet_from_buffer(buf_hdr->handle.handle);
- int len = 1;
- int nbr;
-
- nbr = odp_pktio_send(qentry->s.pktout, &pkt, len);
- return (nbr == len ? 0 : -1);
-}
-
-odp_buffer_hdr_t *pktout_dequeue(queue_entry_t *qentry)
-{
- (void)qentry;
- return NULL;
+ /*
+ * Set port number directly in a descriptor.
+ * TODO: Remove it when PA will be used.
+ */
+ ti_em_cppi_set_psflags(&buf_hdr->desc, queue->s.out_port_id);
+ return queue_enq(queue, buf_hdr);
}
-int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
- int num)
+int pktout_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
{
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- int nbr;
int i;
-
- for (i = 0; i < num; ++i)
- pkt_tbl[i] = odp_packet_from_buffer(buf_hdr[i]->handle.handle);
-
- nbr = odp_pktio_send(qentry->s.pktout, pkt_tbl, num);
- return (nbr == num ? 0 : -1);
+ uint32_t port_id = queue->s.out_port_id;
+ for (i = 0; i < num; i++)
+ ti_em_cppi_set_psflags(&buf_hdr[i]->desc, port_id);
+ return queue_enq_multi(queue, buf_hdr, num);
}
-int pktout_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[],
- int num)
+static inline void update_in_packet(odp_buffer_hdr_t *buf_hdr,
+ odp_pktio_t pktin)
{
- (void)qentry;
- (void)buf_hdr;
- (void)num;
-
- return 0;
+ if (!buf_hdr)
+ return;
+
+ odp_buffer_t buf = hdr_to_odp_buf(buf_hdr);
+ odp_packet_t pkt = odp_packet_from_buffer(buf);
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ size_t len = odp_packet_get_len(pkt);
+ pkt_hdr->input = pktin;
+ odp_packet_parse(pkt, len, 0);
}
-int pktin_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr)
-{
- /* Use default action */
- return queue_enq(qentry, buf_hdr);
-}
-
-odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *qentry)
+odp_buffer_hdr_t *pktin_dequeue(queue_entry_t *queue)
{
odp_buffer_hdr_t *buf_hdr;
+ buf_hdr = queue_deq(queue);
- buf_hdr = queue_deq(qentry);
-
- if (buf_hdr == NULL) {
- odp_packet_t pkt;
- odp_buffer_t buf;
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
- int pkts, i, j;
-
- pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
- QUEUE_MULTI_MAX);
-
- if (pkts > 0) {
- pkt = pkt_tbl[0];
- buf = odp_buffer_from_packet(pkt);
- buf_hdr = odp_buf_to_hdr(buf);
-
- for (i = 1, j = 0; i < pkts; ++i) {
- buf = odp_buffer_from_packet(pkt_tbl[i]);
- tmp_hdr_tbl[j++] = odp_buf_to_hdr(buf);
- }
- queue_enq_multi(qentry, tmp_hdr_tbl, j);
- }
- }
-
+ update_in_packet(buf_hdr, queue->s.pktin);
return buf_hdr;
}
-int pktin_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
+int pktin_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num)
{
- /* Use default action */
- return queue_enq_multi(qentry, buf_hdr, num);
-}
-
-int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num)
-{
- int nbr;
-
- nbr = queue_deq_multi(qentry, buf_hdr, num);
-
- if (nbr < num) {
- odp_packet_t pkt_tbl[QUEUE_MULTI_MAX];
- odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX];
- odp_buffer_t buf;
- int pkts, i;
-
- pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl,
- QUEUE_MULTI_MAX);
- if (pkts > 0) {
- for (i = 0; i < pkts; ++i) {
- buf = odp_buffer_from_packet(pkt_tbl[i]);
- tmp_hdr_tbl[i] = odp_buf_to_hdr(buf);
- }
- queue_enq_multi(qentry, tmp_hdr_tbl, pkts);
- }
- }
+ int i;
+ num = queue_deq_multi(queue, buf_hdr, num);
- return nbr;
+ for (i = 0; i < num; i++)
+ update_in_packet(buf_hdr[i], queue->s.pktin);
+ return num;
}
@@ -66,16 +66,16 @@ static void queue_init(queue_entry_t *queue, const char *name,
switch (type) {
case ODP_QUEUE_TYPE_PKTIN:
- queue->s.enqueue = pktin_enqueue;
+ queue->s.enqueue = queue_enq;
queue->s.dequeue = pktin_dequeue;
- queue->s.enqueue_multi = pktin_enq_multi;
+ queue->s.enqueue_multi = queue_enq_multi;
queue->s.dequeue_multi = pktin_deq_multi;
break;
case ODP_QUEUE_TYPE_PKTOUT:
queue->s.enqueue = pktout_enqueue;
- queue->s.dequeue = pktout_dequeue;
+ queue->s.dequeue = queue_deq;
queue->s.enqueue_multi = pktout_enq_multi;
- queue->s.dequeue_multi = pktout_deq_multi;
+ queue->s.dequeue_multi = queue_deq_multi;
break;
default:
queue->s.enqueue = queue_enq;
Add simple Packet IO implementation. Packet accelerator is not used, so packets are sent directly to Ethernet switch ports. Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> --- .../linux-keystone2/include/odp_buffer_internal.h | 2 - .../include/odp_buffer_pool_internal.h | 1 + .../linux-keystone2/include/odp_packet_internal.h | 15 +- .../include/odp_packet_io_internal.h | 17 +- .../linux-keystone2/include/odp_queue_internal.h | 1 + platform/linux-keystone2/source/odp_buffer.c | 14 +- platform/linux-keystone2/source/odp_buffer_pool.c | 10 +- platform/linux-keystone2/source/odp_init.c | 4 +- platform/linux-keystone2/source/odp_packet.c | 33 +- platform/linux-keystone2/source/odp_packet_io.c | 405 ++++++++------------ platform/linux-keystone2/source/odp_queue.c | 8 +- 11 files changed, 212 insertions(+), 298 deletions(-)