From patchwork Tue Mar 10 15:31:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taras Kondratiuk X-Patchwork-Id: 45591 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f198.google.com (mail-lb0-f198.google.com [209.85.217.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2C6C1214BF for ; Tue, 10 Mar 2015 15:32:32 +0000 (UTC) Received: by lbvn10 with SMTP id n10sf2085723lbv.1 for ; Tue, 10 Mar 2015 08:32:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list; bh=glHLsqoPm8BxGm/uvVBCMsml57SHq+hObWizRn8rk7s=; b=RgbIMSoHNhd70qJvmG1kr24t5tn0+8BkvPtCXU6hTmRCLzJDXMmUumaPt8Gf4ILQFL gi2VSTeVjb2sUt1vD/gWNpWN7EbFS5u6r9F26lezDKFi2SggSTSXp4eHbxp8inAc8RoR 3oj69x1A1nX3+tGRz58dftm9AREbW0Jvrm58K1PkIrLBY96Umhf4zd5aRy6I376EoH9T 9UbN1fDRs2eTNQcEwpv0txPQY+WeNour/PEcw7ZBTAZcy7rvNQaqVzsrVXcQcEW2Mc1P xpnyXP1wV7inQ5otNu2ZhTytpcmFGb78SS57kHPhKSD/aknoGwV14gs+8xj2s+GBDOtY eiAw== X-Gm-Message-State: ALoCoQlULSGaaTVNHgMSjElTYNe4j2Ebw7h1xNZGssSczuOS8cHLbdksclgOtLRWtsc1Xl7nEqS8 X-Received: by 10.152.4.229 with SMTP id n5mr4799966lan.1.1426001551172; Tue, 10 Mar 2015 08:32:31 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.5.104 with SMTP id r8ls37765lar.48.gmail; Tue, 10 Mar 2015 08:32:31 -0700 (PDT) X-Received: by 10.152.245.41 with SMTP id xl9mr14002078lac.24.1426001551023; Tue, 10 Mar 2015 08:32:31 -0700 (PDT) Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com. [209.85.217.182]) by mx.google.com with ESMTPS id kw1si606661lbb.18.2015.03.10.08.32.30 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Mar 2015 08:32:30 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.182 as permitted sender) client-ip=209.85.217.182; Received: by lbvn10 with SMTP id n10so2535907lbv.11 for ; Tue, 10 Mar 2015 08:32:30 -0700 (PDT) X-Received: by 10.152.116.11 with SMTP id js11mr8928561lab.106.1426001550852; Tue, 10 Mar 2015 08:32:30 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp2206980lbj; Tue, 10 Mar 2015 08:32:29 -0700 (PDT) X-Received: by 10.55.54.71 with SMTP id d68mr66362218qka.42.1426001548730; Tue, 10 Mar 2015 08:32:28 -0700 (PDT) Received: from ip-10-35-177-41.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id il9si813519qcb.4.2015.03.10.08.32.27 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 10 Mar 2015 08:32:28 -0700 (PDT) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-35-177-41.ec2.internal) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YVM8u-0003xx-DC; Tue, 10 Mar 2015 15:32:24 +0000 Received: from mail-la0-f48.google.com ([209.85.215.48]) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YVM87-0003pM-Eq for lng-odp@lists.linaro.org; Tue, 10 Mar 2015 15:31:35 +0000 Received: by lams18 with SMTP id s18so2516582lam.9 for ; Tue, 10 Mar 2015 08:31:29 -0700 (PDT) X-Received: by 10.152.45.1 with SMTP id i1mr30748553lam.61.1426001489729; Tue, 10 Mar 2015 08:31:29 -0700 (PDT) Received: from uglx0153363.synapse.com ([195.238.92.128]) by mx.google.com with ESMTPSA id a2sm106609lbm.32.2015.03.10.08.31.28 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 10 Mar 2015 08:31:29 -0700 (PDT) From: Taras Kondratiuk To: lng-odp@lists.linaro.org Date: Tue, 10 Mar 2015 17:31:08 +0200 Message-Id: <1426001473-14618-11-git-send-email-taras.kondratiuk@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1426001473-14618-1-git-send-email-taras.kondratiuk@linaro.org> References: <1426001473-14618-1-git-send-email-taras.kondratiuk@linaro.org> X-Topics: patch Cc: Taras Kondratiuk Subject: [lng-odp] [KEYSTONE2 PATCH 10/15] linux-ks2: buffer: update module X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: taras.kondratiuk@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.182 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Signed-off-by: Taras Kondratiuk Signed-off-by: Taras Kondratiuk --- platform/linux-keystone2/Makefile.am | 8 +- platform/linux-keystone2/include/odp.h | 2 + platform/linux-keystone2/include/odp/buffer.h | 164 +++---- platform/linux-keystone2/include/odp/buffer_pool.h | 101 ---- platform/linux-keystone2/include/odp/event.h | 9 + .../include/odp/plat/buffer_types.h | 29 ++ .../linux-keystone2/include/odp/plat/pool_types.h | 43 ++ platform/linux-keystone2/include/odp/pool.h | 108 +++++ .../linux-keystone2/include/odp_buffer_internal.h | 32 +- .../include/odp_buffer_pool_internal.h | 31 -- platform/linux-keystone2/include/odp_internal.h | 2 +- .../linux-keystone2/include/odp_pool_internal.h | 24 + platform/linux-keystone2/odp_buffer.c | 73 ++- platform/linux-keystone2/odp_buffer_pool.c | 132 ------ platform/linux-keystone2/odp_init.c | 4 +- platform/linux-keystone2/odp_pool.c | 513 +++++++++++++++++++++ 16 files changed, 877 insertions(+), 398 deletions(-) delete mode 100644 platform/linux-keystone2/include/odp/buffer_pool.h create mode 100644 platform/linux-keystone2/include/odp/plat/buffer_types.h create mode 100644 platform/linux-keystone2/include/odp/plat/pool_types.h create mode 100644 platform/linux-keystone2/include/odp/pool.h delete mode 100644 platform/linux-keystone2/include/odp_buffer_pool_internal.h create mode 100644 platform/linux-keystone2/include/odp_pool_internal.h delete mode 100644 platform/linux-keystone2/odp_buffer_pool.c create mode 100644 platform/linux-keystone2/odp_pool.c diff --git a/platform/linux-keystone2/Makefile.am b/platform/linux-keystone2/Makefile.am index 69dd247..a156c00 100644 --- a/platform/linux-keystone2/Makefile.am +++ b/platform/linux-keystone2/Makefile.am @@ -23,11 +23,11 @@ include_HEADERS = \ odpincludedir= $(includedir)/odp odpinclude_HEADERS = \ $(srcdir)/include/odp/buffer.h \ - $(srcdir)/include/odp/buffer_pool.h \ $(srcdir)/include/odp/crypto.h \ $(srcdir)/include/odp/event.h \ $(srcdir)/include/odp/packet_io.h \ $(srcdir)/include/odp/packet.h \ + $(srcdir)/include/odp/pool.h \ $(linux_generic_srcdir)/include/odp/align.h \ $(linux_generic_srcdir)/include/odp/atomic.h \ $(linux_generic_srcdir)/include/odp/barrier.h \ @@ -59,21 +59,21 @@ odpinclude_HEADERS = \ odpplatincludedir = $(includedir)/odp/plat odpplatinclude_HEADERS = \ $(srcdir)/include/odp/plat/align.h \ + $(srcdir)/include/odp/plat/buffer_types.h \ $(srcdir)/include/odp/plat/debug.h \ $(srcdir)/include/odp/plat/event_types.h \ $(srcdir)/include/odp/plat/mcsdk_tune.h \ $(srcdir)/include/odp/plat/osal.h \ + $(srcdir)/include/odp/plat/pool_types.h \ $(srcdir)/include/odp/plat/state.h \ $(srcdir)/include/odp/plat/ti_mcsdk.h \ $(linux_generic_srcdir)/include/odp/plat/atomic_types.h \ - $(linux_generic_srcdir)/include/odp/plat/buffer_types.h \ $(linux_generic_srcdir)/include/odp/plat/byteorder_types.h \ $(linux_generic_srcdir)/include/odp/plat/classification_types.h \ $(linux_generic_srcdir)/include/odp/plat/cpumask_types.h \ $(linux_generic_srcdir)/include/odp/plat/crypto_types.h \ $(linux_generic_srcdir)/include/odp/plat/packet_types.h \ $(linux_generic_srcdir)/include/odp/plat/packet_io_types.h \ - $(linux_generic_srcdir)/include/odp/plat/pool_types.h \ $(linux_generic_srcdir)/include/odp/plat/queue_types.h \ $(linux_generic_srcdir)/include/odp/plat/schedule_types.h \ $(linux_generic_srcdir)/include/odp/plat/shared_memory_types.h \ @@ -132,6 +132,8 @@ subdirheaders_HEADERS = \ __LIB__libodp_la_SOURCES = \ odp_init.c \ + odp_pool.c \ + odp_buffer.c \ mcsdk/mcsdk_init.c \ mcsdk/mcsdk_navig.c \ mcsdk/mcsdk_rmclient.c \ diff --git a/platform/linux-keystone2/include/odp.h b/platform/linux-keystone2/include/odp.h index 7526d93..cf52c25 100644 --- a/platform/linux-keystone2/include/odp.h +++ b/platform/linux-keystone2/include/odp.h @@ -36,6 +36,8 @@ extern "C" { #include #include #include +#include +#include #include #include #include diff --git a/platform/linux-keystone2/include/odp/buffer.h b/platform/linux-keystone2/include/odp/buffer.h index 1889cfb..4b3bf14 100644 --- a/platform/linux-keystone2/include/odp/buffer.h +++ b/platform/linux-keystone2/include/odp/buffer.h @@ -19,38 +19,39 @@ extern "C" { #endif -#include -#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include -/** - * ODP buffer - */ -typedef Ti_Pkt * odp_buffer_t; -#define ODP_BUFFER_INVALID ((odp_buffer_t)0) /**< Invalid buffer */ +typedef struct odp_bufhdr { + /* Empty structure for now */ +} odp_buffer_hdr_t; /** - * @internal Convert ODP buffer to PKTLIB packet handle - * - * @param buf Buffer handle - * - * @return PKTLIB packet handle + * Buffer headroom size reserved for implementation buffer metadata. */ -static inline Ti_Pkt *_odp_buf_to_ti_pkt(odp_buffer_t buf) +#define _ODP_BUFHDR_SIZE ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(odp_buffer_hdr_t)) + +_ODP_STATIC_ASSERT(_ODP_BUFHDR_SIZE <= ODP_CACHE_LINE_SIZE, + "_ODP_BUFHDR_SIZE <= ODP_CACHE_LINE_SIZE"); + +static inline odp_buffer_t _odp_ev_to_buf(odp_event_t ev) { - return (Ti_Pkt *)buf; + return (odp_buffer_t)ev; } -/** - * @internal Convert PKTLIB packet handle to ODP buffer - * - * @param pkt PKTLIB packet handle - * - * @return ODP buffer handle - */ -static inline odp_buffer_t _ti_pkt_to_odp_buf(Ti_Pkt *pkt) +static inline odp_event_t _odp_buf_to_ev(odp_buffer_t buf) { - return (odp_buffer_t)pkt; + return (odp_event_t)buf; } /** @@ -62,7 +63,7 @@ static inline odp_buffer_t _ti_pkt_to_odp_buf(Ti_Pkt *pkt) */ static inline Cppi_HostDesc *_odp_buf_to_cppi_desc(odp_buffer_t buf) { - return Pktlib_getDescFromPacket(_odp_buf_to_ti_pkt(buf)); + return _odp_ev_to_cppi_desc(_odp_buf_to_ev(buf)); } /** @@ -74,99 +75,84 @@ static inline Cppi_HostDesc *_odp_buf_to_cppi_desc(odp_buffer_t buf) */ static inline odp_buffer_t _cppi_desc_to_odp_buf(Cppi_HostDesc *desc) { - return _ti_pkt_to_odp_buf(Pktlib_getPacketFromDesc(desc)); + return _odp_ev_to_buf(_cppi_desc_to_odp_ev(desc)); } - +#if 0 /** - * Buffer start address + * @internal Convert ODP buffer to PKTLIB packet handle * - * @param buf Buffer handle + * @param buf Buffer handle * - * @return Buffer start address + * @return PKTLIB packet handle */ -static inline void *odp_buffer_addr(odp_buffer_t buf) +static inline Ti_Pkt *_odp_buf_to_ti_pkt(odp_buffer_t buf) { - return (void *)_odp_buf_to_cppi_desc(buf)->buffPtr; + return Pktlib_getPacketFromDesc(_odp_buf_to_cppi_desc(buf)); } /** - * Buffer maximum data size + * @internal Convert PKTLIB packet handle to ODP buffer * - * @param buf Buffer handle + * @param pkt PKTLIB packet handle * - * @return Buffer maximum data size + * @return ODP buffer handle */ -static inline size_t odp_buffer_size(odp_buffer_t buf) +static inline odp_buffer_t _ti_pkt_to_odp_buf(Ti_Pkt *pkt) { - return _odp_buf_to_cppi_desc(buf)->buffLen; + return _cppi_desc_to_odp_buf(Pktlib_getDescFromPacket(pkt)); } +#endif -#define ODP_BUFFER_TYPE_INVALID (-1) /**< Buffer type invalid */ -#define ODP_BUFFER_TYPE_ANY 0 /**< Buffer that can hold any other - buffer type */ -#define ODP_BUFFER_TYPE_RAW 1 /**< Raw buffer, no additional metadata */ -#define ODP_BUFFER_TYPE_PACKET 2 /**< Packet buffer */ -#define ODP_BUFFER_TYPE_TIMEOUT 3 /**< Timeout buffer */ -/** - * Buffer type - * - * @param buf Buffer handle - * - * @return Buffer type - */ -static inline int odp_buffer_type(odp_buffer_t buf) +static inline odp_buffer_t odp_buffer_from_event(odp_event_t ev) { - return Pktlib_getUsrFlags(_odp_buf_to_ti_pkt(buf)); + return _odp_ev_to_buf(ev); } -/** - * Tests if buffer is valid - * - * @param buf Buffer handle - * - * @return 1 if valid, otherwise 0 - */ -static inline int odp_buffer_is_valid(odp_buffer_t buf) +static inline odp_event_t odp_buffer_to_event(odp_buffer_t buf) { - return (buf != ODP_BUFFER_INVALID); + return _odp_buf_to_ev(buf); } -/** - * Print buffer metadata to STDOUT - * - * @param buf Buffer handle - */ -void odp_buffer_print(odp_buffer_t buf); +static inline struct odp_bufhdr *_odp_buf_hdr(odp_buffer_t buf) +{ + Cppi_HostDesc *desc = _odp_buf_to_cppi_desc(buf); + uint8_t *orig_ptr = _cppi_desc_orig_vptr(desc); + ODP_ASSERT(ODP_ALIGNED_CHECK(orig_ptr, ODP_ALIGNOF(struct odp_bufhdr)), + "Wrong buffer header alignment"); + return (struct odp_bufhdr *)(void *)orig_ptr; +} -/** - * @internal Set buffer user context - * - * @param buffer Buffer handle - * @param context User context - */ -static inline void odp_buffer_set_ctx(odp_buffer_t buffer, void *context) +/* Compatibility function for timer code reused from linux-generic */ +static inline odp_buffer_hdr_t *odp_buf_to_hdr(odp_buffer_t buf) { - Cppi_setTimeStamp(Cppi_DescType_HOST, - (Cppi_Desc *)_odp_buf_to_cppi_desc(buffer), - (uint32_t) context); + return (odp_buffer_hdr_t *)_odp_buf_hdr(buf); } -/** - * @internal Get buffer user context - * - * @param buffer Buffer handle - * - * @return User context - */ -static inline void *odp_buffer_get_ctx(odp_buffer_t buffer) +static inline void *odp_buffer_addr(odp_buffer_t buf) +{ + Cppi_HostDesc *desc = _odp_buf_to_cppi_desc(buf); + return _cppi_desc_orig_vptr(desc) + _ODP_BUFHDR_SIZE; +} + +static inline uint32_t odp_buffer_size(odp_buffer_t buf) +{ + Cppi_HostDesc *desc = _odp_buf_to_cppi_desc(buf); + return _cppi_desc_orig_len(desc) - _ODP_BUFHDR_SIZE; +} + +static inline int odp_buffer_is_valid(odp_buffer_t buf) +{ + return (buf != ODP_BUFFER_INVALID); +} + +static inline odp_pool_t odp_buffer_pool(odp_buffer_t buf) { - uint32_t app_ctx_id = 0; - Cppi_getTimeStamp(Cppi_DescType_HOST, - (Cppi_Desc *)_odp_buf_to_cppi_desc(buffer), - &app_ctx_id); - return (void *)app_ctx_id; + return _odp_event_pool(_odp_buf_to_ev(buf)); } +#include + + #ifdef __cplusplus } #endif diff --git a/platform/linux-keystone2/include/odp/buffer_pool.h b/platform/linux-keystone2/include/odp/buffer_pool.h deleted file mode 100644 index 970c33a..0000000 --- a/platform/linux-keystone2/include/odp/buffer_pool.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * Copyright (c) 2014, Texas Instruments Incorporated - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP buffer pool - */ - -#ifndef ODP_BUFFER_POOL_H_ -#define ODP_BUFFER_POOL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - - -#include -#include -#include - -/** Maximum queue name length in chars */ -/* #define ODP_BUFFER_POOL_NAME_LEN PKTLIB_MAX_HEAP_NAME */ - -/** Invalid buffer pool */ -#define ODP_BUFFER_POOL_INVALID (NULL) - -/** ODP buffer pool */ -typedef Pktlib_HeapHandle odp_buffer_pool_t; - - -/** - * Create a buffer pool - * - * @param name Name of the pool (max ODP_BUFFER_POOL_NAME_LEN - 1 chars) - * @param base_addr Pool base address - * @param size Pool size in bytes - * @param buf_size Buffer size in bytes - * @param buf_align Minimum buffer alignment - * @param buf_type Buffer type - * - * @return Buffer pool handle - */ -odp_buffer_pool_t odp_buffer_pool_create(const char *name, - void *base_addr, uint64_t size, - size_t buf_size, size_t buf_align, - int buf_type); - - -/** - * Find a buffer pool by name - * - * @param name Name of the pool - * - * @return Buffer pool handle, or ODP_BUFFER_POOL_INVALID if not found. - */ -odp_buffer_pool_t odp_buffer_pool_lookup(const char *name); - - -/** - * Print buffer pool info - * - * @param pool Pool handle - * - */ -void odp_buffer_pool_print(odp_buffer_pool_t pool); - - - -/** - * Buffer alloc - * - * @param pool Pool handle - * - * @return Buffer handle or ODP_BUFFER_INVALID - */ -odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool); - - -/** - * Buffer free - * - * @param buf Buffer handle - * - */ -void odp_buffer_free(odp_buffer_t buf); - - - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-keystone2/include/odp/event.h b/platform/linux-keystone2/include/odp/event.h index 1233e92..17b26bb 100644 --- a/platform/linux-keystone2/include/odp/event.h +++ b/platform/linux-keystone2/include/odp/event.h @@ -19,6 +19,7 @@ extern "C" { #include #include +#include /** * @internal Convert ODP event to CPPI descriptor @@ -44,6 +45,14 @@ static inline odp_event_t _cppi_desc_to_odp_ev(Cppi_HostDesc *desc) return (odp_event_t)desc; } +static inline odp_pool_t _odp_event_pool(odp_event_t ev) +{ + Cppi_HostDesc *desc = _odp_ev_to_cppi_desc(ev); + uint8_t pool_id = _cppi_desc_pool_id(desc); + pool_entry_t *pool_entry = _odp_pool_id_to_entry(pool_id); + return _odp_pool_from_entry(pool_entry); +} + /** @ingroup odp_event * @{ */ diff --git a/platform/linux-keystone2/include/odp/plat/buffer_types.h b/platform/linux-keystone2/include/odp/plat/buffer_types.h new file mode 100644 index 0000000..80319af --- /dev/null +++ b/platform/linux-keystone2/include/odp/plat/buffer_types.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, Linaro Limited + * Copyright (c) 2014, Texas Instruments Incorporated + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * ODP buffer types + */ + +#ifndef ODP_PLAT_BUFFER_TYPES_H_ +#define ODP_PLAT_BUFFER_TYPES_H_ + +#include +#include + +/** + * ODP buffer + */ +typedef odp_handle_t odp_buffer_t; + +#define ODP_BUFFER_INVALID ((odp_buffer_t)0) /**< Invalid buffer */ + +#endif diff --git a/platform/linux-keystone2/include/odp/plat/pool_types.h b/platform/linux-keystone2/include/odp/plat/pool_types.h new file mode 100644 index 0000000..82a7c8f --- /dev/null +++ b/platform/linux-keystone2/include/odp/plat/pool_types.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Linaro Limited + * Copyright (c) 2014, Texas Instruments Incorporated + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP pool types + */ + +#ifndef ODP_PLAT_POOL_TYPES_H_ +#define ODP_PLAT_POOL_TYPES_H_ + +#include +#include + +/** @addtogroup odp_buffer + * Operations on a pool. + * @{ + */ + +#define ODP_POOL_NAME_LEN 32 + +typedef odp_handle_t odp_pool_t; + +/** Invalid buffer pool */ +#define ODP_POOL_INVALID ((odp_pool_t)0) + +/** Get printable format of odp_pool_t */ +static inline uint64_t odp_pool_to_u64(odp_pool_t hdl) +{ + return _odp_pri(hdl); +} + +/** + * @} + */ + +#endif diff --git a/platform/linux-keystone2/include/odp/pool.h b/platform/linux-keystone2/include/odp/pool.h new file mode 100644 index 0000000..790e814 --- /dev/null +++ b/platform/linux-keystone2/include/odp/pool.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Linaro Limited + * Copyright (c) 2014, Texas Instruments Incorporated + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP buffer pool + */ + +#ifndef ODP_POOL_H_ +#define ODP_POOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* Use ticketlock instead of spinlock */ +#define POOL_USE_TICKETLOCK + +#ifdef POOL_USE_TICKETLOCK +#include +#define POOL_LOCK(a) odp_ticketlock_lock(a) +#define POOL_UNLOCK(a) odp_ticketlock_unlock(a) +#define POOL_LOCK_INIT(a) odp_ticketlock_init(a) +#define POOL_LOCK_T odp_ticketlock_t +#else +#include +#define POOL_LOCK(a) odp_spinlock_lock(a) +#define POOL_UNLOCK(a) odp_spinlock_unlock(a) +#define POOL_LOCK_INIT(a) odp_spinlock_init(a) +#define POOL_LOCK_T odp_spinlock_t +#endif + +typedef uint8_t _pool_id_t; + +struct pool_entry_s { + POOL_LOCK_T lock ODP_ALIGNED_CACHE; + Qmss_QueueHnd free_queue; + char name[ODP_POOL_NAME_LEN]; + _pool_id_t id; + uint32_t headroom; + uint32_t tailroom; + uint32_t buf_size; + uint32_t buf_align; + uint32_t num_bufs; + + struct { + Cppi_FlowHnd handle; + uint32_t id; + } cppi_flow; + + union { + uint32_t all; + struct { + uint32_t allocated:1; + uint32_t has_name:1; + uint32_t predefined:1; + }; + } flags; + + odp_pool_param_t orig_params; +}; + +typedef struct pool_entry_s pool_entry_t; + +extern pool_entry_t *pool_tbl; + +static inline +pool_entry_t *_odp_pool_entry(odp_pool_t pool) +{ + return (pool_entry_t *)(uintptr_t)pool; +} + +static inline +pool_entry_t *_odp_pool_id_to_entry(_pool_id_t pool_id) +{ + return &pool_tbl[pool_id]; +} + +static inline +odp_pool_t _odp_pool_from_entry(pool_entry_t *entry) +{ + return (odp_pool_t)entry; +} + +static inline +_pool_id_t _odp_pool_id(odp_pool_t pool) +{ + return _odp_pool_entry(pool)->id; +} + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-keystone2/include/odp_buffer_internal.h b/platform/linux-keystone2/include/odp_buffer_internal.h index c3228ec..dade794 100644 --- a/platform/linux-keystone2/include/odp_buffer_internal.h +++ b/platform/linux-keystone2/include/odp_buffer_internal.h @@ -19,40 +19,12 @@ extern "C" { #endif -#include -#include -#include -#include -#include -#include -#include - -typedef struct odp_bufhdr { - int type; -} odp_buffer_hdr_t; - -ODP_STATIC_ASSERT(sizeof(Cppi_HostDesc) <= ODP_CACHE_LINE_SIZE, - "ODP_BUFFER_HDR_T__SIZE_ERROR"); - -static inline struct odp_bufhdr *odp_buffer_hdr(odp_buffer_t buf) -{ - return (struct odp_bufhdr *)(_odp_buf_to_cppi_desc(buf)->origBuffPtr); -} - -/* Compatibility function for timer code reused from linux-generic */ -static inline odp_buffer_hdr_t *odp_buf_to_hdr(odp_buffer_t buf) -{ - return (odp_buffer_hdr_t *)odp_buffer_hdr(buf); -} - -extern odp_buffer_pool_t odp_buf_to_pool(odp_buffer_t buf); +#include +#include int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf); -void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src); - - #ifdef __cplusplus } #endif diff --git a/platform/linux-keystone2/include/odp_buffer_pool_internal.h b/platform/linux-keystone2/include/odp_buffer_pool_internal.h deleted file mode 100644 index 95960c9..0000000 --- a/platform/linux-keystone2/include/odp_buffer_pool_internal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * Copyright (c) 2014, Texas Instruments Incorporated - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP buffer pool - internal header - */ - -#ifndef ODP_BUFFER_POOL_INTERNAL_H_ -#define ODP_BUFFER_POOL_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -uint32_t _odp_pool_get_free_queue(odp_buffer_pool_t pool_id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-keystone2/include/odp_internal.h b/platform/linux-keystone2/include/odp_internal.h index 816e74f..2131e5a 100644 --- a/platform/linux-keystone2/include/odp_internal.h +++ b/platform/linux-keystone2/include/odp_internal.h @@ -34,7 +34,7 @@ int odp_shm_init_global(void); int odp_shm_term_global(void); int odp_shm_init_local(void); -int odp_buffer_pool_init_global(void); +int odp_pool_init_global(void); int odp_pktio_init_global(void); diff --git a/platform/linux-keystone2/include/odp_pool_internal.h b/platform/linux-keystone2/include/odp_pool_internal.h new file mode 100644 index 0000000..b605cf6 --- /dev/null +++ b/platform/linux-keystone2/include/odp_pool_internal.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014, Linaro Limited + * Copyright (c) 2014, Texas Instruments Incorporated + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP pool - internal header + */ + +#ifndef ODP_POOL_INTERNAL_H_ +#define ODP_POOL_INTERNAL_H_ + +#include +#include + +Qmss_QueueHnd _odp_pool_get_free_queue(odp_pool_t pool_id); +int32_t _odp_pool_cppi_flow_id(odp_pool_t pool); + +#endif diff --git a/platform/linux-keystone2/odp_buffer.c b/platform/linux-keystone2/odp_buffer.c index 676a8a4..1e04ccb 100644 --- a/platform/linux-keystone2/odp_buffer.c +++ b/platform/linux-keystone2/odp_buffer.c @@ -6,9 +6,70 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include +#include + +#include +#include + #include -#include + +odp_buffer_t odp_buffer_alloc(odp_pool_t pool) +{ + Cppi_HostDesc *desc; + uintptr_t desc_phys; + pool_entry_t *pool_entry = _odp_pool_entry(pool); + uint32_t headroom = pool_entry->headroom; + odp_pa_t buf_phys; + + desc_phys = QMSS_DESC_PTR(Qmss_queuePopRaw(pool_entry->free_queue)); + desc = _odp_mem_phys_to_virt(desc_phys); + + if (!desc) + return ODP_BUFFER_INVALID; + + ODP_ASSERT(_cppi_desc_next(desc) == 0, + "Pool should not have linked buffers"); + + buf_phys = _cppi_desc_orig_ptr(desc); + if (buf_phys) { + uint8_t *buf_addr = _odp_mem_phys_to_virt(buf_phys); + ODP_ASSERT(buf_addr, "Failed phys to virt translation"); + + _cppi_desc_orig_vptr_set(desc, buf_addr); + /* Leave space for buffer metadata */ + _cppi_desc_buf_vptr_set(desc, buf_addr + headroom); + _cppi_desc_buf_len_set(desc, _cppi_desc_orig_len(desc) - + headroom); + } + + odp_pr_vdbg("pool_id: %p, pkt: %p, buf: %p\n", id, pkt, buf); + return _cppi_desc_to_odp_buf(desc); +} + +void odp_buffer_free(odp_buffer_t buf) +{ + Cppi_HostDesc *desc; + uint32_t pool_id; + pool_entry_t *pool_entry; + + odp_pr_vdbg("buf: %p\n", buf); + desc = _odp_buf_to_cppi_desc(buf); + ODP_ASSERT(_cppi_desc_vnext(desc) == NULL, + "Pool should not have linked buffers"); + + pool_id = _cppi_desc_pool_id(desc); + pool_entry = _odp_pool_id_to_entry(pool_id); + + if (_cppi_desc_orig_vptr(desc)) { + _cppi_desc_orig_ptr_set(desc, _odp_mem_virt_to_phys( + _cppi_desc_orig_vptr(desc))); + } + + Qmss_queuePushDescSizeRaw(pool_entry->free_queue, + (void *)_odp_mem_virt_to_phys(desc), + 16); +} int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) { @@ -35,7 +96,7 @@ int odp_buffer_snprint(char *str, size_t n, odp_buffer_t buf) len += snprintf(&str[len], n-len, " buf_len 0x%x\n", desc->buffLen); len += snprintf(&str[len], n-len, - " pool %p\n", odp_buf_to_pool(buf)); + " pool %p\n", odp_buffer_pool(buf)); len += snprintf(&str[len], n-len, "\n"); @@ -62,9 +123,3 @@ void odp_buffer_print(odp_buffer_t buf) desc->buffPtr - desc->origBuffPtr + 128, "Buffer start"); } - -void odp_buffer_copy_scatter(odp_buffer_t buf_dst, odp_buffer_t buf_src) -{ - (void)buf_dst; - (void)buf_src; -} diff --git a/platform/linux-keystone2/odp_buffer_pool.c b/platform/linux-keystone2/odp_buffer_pool.c deleted file mode 100644 index 13656a9..0000000 --- a/platform/linux-keystone2/odp_buffer_pool.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * Copyright (c) 2014, Texas Instruments Incorporated - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/** - * @todo: Currently a number of HW descriptors is limited, - * so temporary limit max number of buffers per pool - * to be albe to run ODP example apps. - * Descriptor management have to be made more intelligent - * To remove this limitation. - */ -#define MAX_BUFS_PER_POOL 1024 - -int odp_buffer_pool_init_global(void) -{ - /* Pktlib initialized in mcsdk_global_init() */ - return 0; -} - -odp_buffer_pool_t odp_buffer_pool_create(const char *name, - void *base_addr ODP_UNUSED, uint64_t size, - size_t buf_size, size_t buf_align, - int buf_type ODP_UNUSED) -{ - Pktlib_HeapCfg heap_cfg; - Pktlib_HeapHandle heap_handle; - int num_bufs; - int err_code; - - buf_size = ODP_ALIGN_ROUNDUP(buf_size, buf_align); - /* - * XXX: size is used only to get number of buffers. - * Memory is allocated for each buffer separately - */ - num_bufs = size / buf_size; - buf_size += odp_global->cfg.min_buf_headroom_size; - buf_size = ODP_CACHE_LINE_SIZE_ROUNDUP(buf_size); - - - if (num_bufs > MAX_BUFS_PER_POOL) { - odp_pr_dbg("Limiting number of buffer in %s from %d to %d\n", - name, num_bufs, MAX_BUFS_PER_POOL); - num_bufs = MAX_BUFS_PER_POOL; - } - - /* Initialize the heap configuration. */ - memset((void *)&heap_cfg, 0, sizeof(Pktlib_HeapCfg)); - /* Populate the heap configuration */ - heap_cfg.name = name; - heap_cfg.memRegion = odp_global->public_desc_memregion; - heap_cfg.sharedHeap = 1; - heap_cfg.useStarvationQueue = 0; - heap_cfg.dataBufferSize = buf_size; - heap_cfg.numPkts = num_bufs; - heap_cfg.numZeroBufferPackets = 0; - heap_cfg.heapInterfaceTable.data_malloc = - pktlib_if_table.data_malloc; - heap_cfg.heapInterfaceTable.data_free = - pktlib_if_table.data_free; - heap_cfg.dataBufferPktThreshold = 0; - heap_cfg.zeroBufferPktThreshold = 0; - odp_pr_dbg("name: %s, buf_size: %u, num_bufs: %u\n", name, buf_size, - num_bufs); - /* Create Shared Heap with specified configuration. */ - heap_handle = Pktlib_createHeap(&heap_cfg, &err_code); - odp_pr_dbg("heap_handle: %p, err_code: %d\n", heap_handle, err_code); - return heap_handle; -} - -odp_buffer_pool_t odp_buffer_pool_lookup(const char *name) -{ - return Pktlib_findHeapByName(name); -} - -odp_buffer_t odp_buffer_alloc(odp_buffer_pool_t pool_id) -{ - Ti_Pkt *pkt; - odp_buffer_t buf; - Cppi_HostDesc *desc; - - pkt = Pktlib_allocPacket(pool_id, -1); - if (!pkt) - return ODP_BUFFER_INVALID; - - buf = _ti_pkt_to_odp_buf(pkt); - desc = _odp_buf_to_cppi_desc(buf); - - /* Leave space for buffer metadata. There must be enough space. */ - desc->buffPtr = desc->origBuffPtr + - odp_global->cfg.min_buf_headroom_size; - - odp_pr_vdbg("pool_id: %p, pkt: %p, buf: %p\n", pool_id, pkt, buf); - return buf; -} - -void odp_buffer_free(odp_buffer_t buf) -{ - odp_pr_vdbg("buf: %p\n", buf); - Pktlib_freePacket(_odp_buf_to_ti_pkt(buf)); -} - -void odp_buffer_pool_print(odp_buffer_pool_t pool_id) -{ - (void)pool_id; -} - -odp_buffer_pool_t odp_buf_to_pool(odp_buffer_t buf) -{ - return Pktlib_getPktHeap(_odp_buf_to_ti_pkt(buf)); -} - -uint32_t _odp_pool_get_free_queue(odp_buffer_pool_t pool_id) -{ - return Pktlib_getInternalHeapQueue(pool_id); -} diff --git a/platform/linux-keystone2/odp_init.c b/platform/linux-keystone2/odp_init.c index 86df7fe..38055e0 100644 --- a/platform/linux-keystone2/odp_init.c +++ b/platform/linux-keystone2/odp_init.c @@ -45,12 +45,12 @@ int odp_init_global(odp_init_t *params ODP_UNUSED, odp_pr_err("ODP McSDK init failed.\n"); return -1; } -#if 0 - if (odp_buffer_pool_init_global()) { + if (odp_pool_init_global()) { odp_pr_err("ODP buffer pool init failed.\n"); return -1; } +#if 0 if (odp_queue_init_global()) { odp_pr_err("ODP queue init failed.\n"); return -1; diff --git a/platform/linux-keystone2/odp_pool.c b/platform/linux-keystone2/odp_pool.c new file mode 100644 index 0000000..93fac4b --- /dev/null +++ b/platform/linux-keystone2/odp_pool.c @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2014, Linaro Limited + * Copyright (c) 2014, Texas Instruments Incorporated + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +pool_entry_t *pool_tbl; +/** + * @todo: Currently a number of HW descriptors is limited, + * so temporary limit max number of buffers per pool + * to be albe to run ODP example apps. + * Descriptor management have to be made more intelligent + * To remove this limitation. + */ +#define MAX_BUFS_PER_POOL 1024 + +int odp_pool_init_global(void) +{ + _pool_id_t i; + odp_shm_t shm; + size_t shm_size = sizeof(pool_entry_t) * ODP_CONFIG_POOLS; + + shm = odp_shm_reserve("odp_pools", + shm_size, + sizeof(pool_entry_t), 0); + + pool_tbl = odp_shm_addr(shm); + + if (pool_tbl == NULL) + return -1; + + memset(pool_tbl, 0, shm_size); + + for (i = 0; i < ODP_CONFIG_POOLS; i++) { + /* init locks */ + pool_entry_t *entry = _odp_pool_id_to_entry(i); + POOL_LOCK_INIT(&entry->lock); + entry->id = i; + } + + ODP_DBG("\nBuffer pool init global\n"); + ODP_DBG(" pool_entry_t size %zu\n", sizeof(pool_entry_t)); + ODP_DBG("\n"); + return 0; +} + +static pool_entry_t *find_free_pool_entry_locked(void) +{ + int i; + + for (i = 0; i < ODP_CONFIG_POOLS; i++) { + pool_entry_t *entry = _odp_pool_id_to_entry(i); + + POOL_LOCK(&entry->lock); + if (!entry->flags.allocated) + return entry; + POOL_UNLOCK(&entry->lock); + } + return NULL; +} + +static void _free_descriptors(Qmss_MemRegion mem_region, + Qmss_QueueHnd queue) +{ + Qmss_QueueHnd mem_reg_queue = Qmss_getMemRegQueueHandle(mem_region); + Qmss_Result result; + + while (Qmss_getQueueEntryCount(queue) != 0) { + uintptr_t desc_phys = QMSS_DESC_PTR(Qmss_queuePopRaw(queue)); + ODP_ASSERT(desc_phys, "No descriptors in a pool free queue"); + + /* Place back the descriptor into the memory region queue. */ + Qmss_queuePushDescSizeRaw(mem_reg_queue, (void *)desc_phys, 16); + } + result = Qmss_queueClose(queue); + ODP_ASSERT(result >= 0, "Queue close failed"); +} + +static Qmss_QueueHnd _alloc_descriptors(Qmss_MemRegion mem_region, + uint32_t desc_num) +{ + Cppi_DescCfg desc_cfg; + Qmss_QueueHnd queue; + uint32_t num_allocated; + + /* Initialize the descriptor configuration */ + memset((void *)&desc_cfg, 0, sizeof(Cppi_DescCfg)); + + /* Populate the descriptor configuration: */ + desc_cfg.memRegion = mem_region; + desc_cfg.descNum = desc_num; + desc_cfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED; + desc_cfg.queueGroup = 0; + desc_cfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE; + desc_cfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR; + desc_cfg.descType = Cppi_DescType_HOST; + desc_cfg.returnQueue.qMgr = QMSS_PARAM_NOT_SPECIFIED; + desc_cfg.returnQueue.qNum = QMSS_PARAM_NOT_SPECIFIED; + desc_cfg.epibPresent = Cppi_EPIB_EPIB_PRESENT; + desc_cfg.returnPushPolicy = Qmss_Location_TAIL; + desc_cfg.cfg.host.returnPolicy = Cppi_ReturnPolicy_RETURN_BUFFER; + desc_cfg.cfg.host.psLocation = Cppi_PSLoc_PS_IN_DESC; + + /* Initialize the descriptors and place them into a queue. */ + queue = Cppi_initDescriptor(&desc_cfg, &num_allocated); + if (queue < 0) { + ODP_ERR("Cppi_initDescriptor() failed: %i\n", (int32_t)queue); + return queue; + } + + if (num_allocated != desc_num) { + ODP_ERR("Wrong number of descriptors allocated: requested: %u, allocated: %u\n", + desc_num, num_allocated); + _free_descriptors(mem_region, queue); + return (Qmss_QueueHnd)QMSS_LLD_EBASE; + } + + ODP_ASSERT(Qmss_getQueueEntryCount(queue) == desc_num, + "Wrong number of descriptors in queue"); + + return queue; +} + +static void _detach_buffers(Qmss_QueueHnd queue) +{ + uint32_t num_bufs = Qmss_getQueueEntryCount(queue); + uint32_t i; + + for (i = 0; i < num_bufs; i++) { + uint8_t *buf_ptr; + odp_pa_t buf_phys; + uint32_t buf_size; + odp_pa_t desc_phys = QMSS_DESC_PTR(Qmss_queuePopRaw(queue)); + Cppi_HostDesc *desc = _odp_mem_phys_to_virt(desc_phys); + ODP_ASSERT(desc != NULL, "No descriptors in a pool free queue"); + + _cppi_desc_orig_info(desc, &buf_phys, &buf_size); + buf_ptr = _odp_mem_phys_to_virt(buf_phys); + if (buf_ptr) { + hplib_vmMemFree(buf_ptr, buf_size, 0); + _cppi_desc_orig_info_set(desc, 0, 0); + } + + /* Push this descriptor into the corresponding queue */ + Qmss_queuePushDescSizeRaw(queue, (void *)desc_phys, 16); + } +} + +static int _attach_buffers(Qmss_QueueHnd queue, + uint32_t buf_size, + uint32_t buf_align, + int buf_type, + int pool_id) +{ + uint32_t num_bufs = Qmss_getQueueEntryCount(queue); + uint32_t i; + + if (num_bufs == 0) + return -1; + + for (i = 0; i < num_bufs; i++) { + uint8_t *buf_ptr; + odp_pa_t buf_phys; + /* Pop a descriptor of the free queue. */ + odp_pa_t desc_phys = QMSS_DESC_PTR(Qmss_queuePopRaw(queue)); + Cppi_HostDesc *desc = _odp_mem_phys_to_virt(desc_phys); + ODP_ASSERT(desc != NULL, "No descriptors in a pool free queue"); + + /* Allocate memory for the data buffer. */ + buf_ptr = hplib_vmMemAlloc(buf_size, buf_align, 0); + if (buf_ptr == NULL) { + /* Return descriptor to a queue and detach buffers */ + Qmss_queuePushDescSizeRaw(queue, (void *)desc_phys, 16); + _detach_buffers(queue); + return -1; + } + + buf_phys = _odp_mem_virt_to_phys(buf_ptr); + /* Set the original buffer information in the descriptor. */ + _cppi_desc_orig_info_set(desc, buf_phys, buf_size); + + /* Set the data and payload length into the packet. */ + _cppi_desc_buf_info_set(desc, buf_phys, buf_size); + + _cppi_desc_pkt_type_set(desc, buf_type); + _cppi_desc_pool_id_set(desc, pool_id); + + /* Push this descriptor into the corresponding queue */ + Qmss_queuePushDescSizeRaw(queue, (void *)desc_phys, 16); + } + + return 0; +} + +Qmss_QueueHnd _odp_pool_get_free_queue(odp_pool_t pool) +{ + pool_entry_t *entry = _odp_pool_entry(pool); + return entry->free_queue; +} + +static int _odp_buffer_pool_init(pool_entry_t *entry) +{ + uint32_t buf_align = entry->orig_params.buf.align; + uint32_t buf_size = entry->orig_params.buf.size; + + /* Set correct alignment based on input request */ + if (buf_align == 0) + buf_align = ODP_CACHE_LINE_SIZE; + else if (buf_align < ODP_CONFIG_BUFFER_ALIGN_MIN) + buf_align = ODP_CONFIG_BUFFER_ALIGN_MIN; + else if (buf_align > ODP_CONFIG_BUFFER_ALIGN_MAX) + return -1; + + if (buf_size > ODP_CONFIG_PACKET_SEG_LEN_MAX) + return -1; + + entry->headroom = _ODP_BUFHDR_SIZE; + entry->tailroom = 0; + + buf_size += entry->headroom; + buf_size = ODP_CACHE_LINE_SIZE_ROUNDUP(buf_size); + + entry->buf_size = buf_size; + entry->buf_align = buf_align; + + if (_attach_buffers(entry->free_queue, + buf_size, + buf_align, + entry->orig_params.type, + entry->id)) { + return -1; + } + + return 0; +} + +odp_pool_t odp_pool_create(const char *name, + odp_shm_t shm, + odp_pool_param_t *params) +{ + uint32_t num_bufs; + pool_entry_t *entry; + static const char anon_name[] = "anonymous"; + int ret = 0; + + if (params == NULL) + return ODP_POOL_INVALID; + + if (shm != ODP_SHM_INVALID) { + ODP_ERR("Pool from user memory is not yet supported\n"); + return ODP_POOL_INVALID; + } + + entry = find_free_pool_entry_locked(); + if (entry == NULL) + return ODP_POOL_INVALID; + + entry->flags.all = 0; + entry->flags.allocated = 1; + + if (name == NULL) { + entry->name[0] = 0; + name = anon_name; + } else { + strncpy(entry->name, name, ODP_POOL_NAME_LEN - 1); + entry->name[ODP_POOL_NAME_LEN - 1] = 0; + entry->flags.has_name = 1; + } + + num_bufs = params->buf.num; + if (num_bufs > MAX_BUFS_PER_POOL) { + odp_pr_dbg("Limiting number of buffer in %s from %d to %d\n", + name, num_bufs, MAX_BUFS_PER_POOL); + num_bufs = MAX_BUFS_PER_POOL; + } + + entry->free_queue = _alloc_descriptors( + odp_global->public_desc_memregion, + num_bufs); + if (entry->free_queue < 0) { + entry->flags.allocated = 0; + POOL_UNLOCK(&entry->lock); + return ODP_POOL_INVALID; + } + + memcpy(&entry->orig_params, params, sizeof(entry->orig_params)); + entry->num_bufs = num_bufs; + + switch (params->type) { + case ODP_POOL_BUFFER: + ret = _odp_buffer_pool_init(entry); + break; + case ODP_POOL_PACKET: + ret = -1; + break; + case ODP_POOL_TIMEOUT: + ret = -1; + break; + default: + ODP_ERR("Wrong pool type\n"); + ret = -1; + } + if (ret) { + _free_descriptors(odp_global->public_desc_memregion, + entry->free_queue); + entry->flags.allocated = 0; + POOL_UNLOCK(&entry->lock); + return ODP_POOL_INVALID; + } + + POOL_UNLOCK(&entry->lock); + return _odp_pool_from_entry(entry); +} + +int odp_pool_destroy(odp_pool_t pool) +{ + pool_entry_t *entry = _odp_pool_entry(pool); + + if (entry == NULL) + return -1; + + POOL_LOCK(&entry->lock); + + /* Call fails if pool is not allocated or predefined*/ + if (!entry->flags.allocated || entry->flags.predefined) { + POOL_UNLOCK(&entry->lock); + return -1; + } + + if (Qmss_getQueueEntryCount(entry->free_queue) != entry->num_bufs) { + ODP_ERR("Not all buffers are returned to the pool\n"); + POOL_UNLOCK(&entry->lock); + return -1; + } + + _detach_buffers(entry->free_queue); + _free_descriptors(odp_global->public_desc_memregion, + entry->free_queue); + + POOL_UNLOCK(&entry->lock); + return 0; +} +odp_pool_t odp_pool_lookup(const char *name) +{ + uint32_t i; + pool_entry_t *entry; + + for (i = 0; i < ODP_CONFIG_POOLS; i++) { + entry = _odp_pool_id_to_entry(i); + + POOL_LOCK(&entry->lock); + if (strcmp(name, entry->name) == 0) { + /* found it */ + POOL_UNLOCK(&entry->lock); + return _odp_pool_from_entry(entry); + } + POOL_UNLOCK(&entry->lock); + } + return ODP_POOL_INVALID; +} + +int odp_pool_info(odp_pool_t pool, + odp_pool_info_t *info) +{ + pool_entry_t *entry = _odp_pool_entry(pool); + + if (entry == NULL || info == NULL) + return -1; + + info->name = entry->name; + info->shm = ODP_SHM_INVALID; + memcpy(&info->params, &entry->orig_params, sizeof(entry->orig_params)); + + return 0; +} + +static const char *_odp_buffer_type_string(int type) +{ + switch (type) { + case ODP_POOL_BUFFER: + return "buffer"; + case ODP_POOL_PACKET: + return "packet"; + case ODP_POOL_TIMEOUT: + return "timeout"; + default: + return "invalid"; + } +} + +static uint32_t _odp_pool_available_bufs(odp_pool_t pool) +{ + pool_entry_t *entry = _odp_pool_entry(pool); + return Qmss_getQueueEntryCount(entry->free_queue); +} + +void odp_pool_print(odp_pool_t pool) +{ + pool_entry_t *entry = _odp_pool_entry(pool); + + if (!entry) + return; + + ODP_PRINT("Pool info\n"); + ODP_PRINT("---------\n"); + ODP_PRINT(" pool %p\n", pool); + ODP_PRINT(" pool_id %i\n", _odp_pool_id(pool)); + ODP_PRINT(" name %s\n", + entry->flags.has_name ? entry->name : "Unnamed Pool"); + ODP_PRINT(" pool type %s\n", + _odp_buffer_type_string(entry->orig_params.type)); + ODP_PRINT(" buf size %u requested, %u used\n", + entry->orig_params.buf.size, entry->buf_size); + ODP_PRINT(" buf align %u requested, %u used\n", + entry->orig_params.buf.align, entry->buf_align); + ODP_PRINT(" num_bufs %u requested, %u used\n", + entry->orig_params.buf.num, entry->num_bufs); + ODP_PRINT(" bufs available %u\n", _odp_pool_available_bufs(pool)); +} + +static Cppi_FlowHnd _create_cppi_flow(Qmss_QueueHnd queue, uint32_t sop_offset) +{ + Cppi_RxFlowCfg rx_flow_cfg; + Uint8 is_alloc; + Qmss_Queue tmp_queue; + Cppi_FlowHnd flow; + + memset(&rx_flow_cfg, 0, sizeof(Cppi_RxFlowCfg)); + + /* Configure Rx flow */ + tmp_queue = Qmss_getQueueNumber(odp_global->nwal.info.defFlowQ); + rx_flow_cfg.rx_dest_qnum = tmp_queue.qNum; /* Override in PA */ + rx_flow_cfg.rx_dest_qmgr = tmp_queue.qMgr; + rx_flow_cfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED; + rx_flow_cfg.rx_sop_offset = sop_offset; + rx_flow_cfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC; + rx_flow_cfg.rx_desc_type = Cppi_DescType_HOST; + rx_flow_cfg.rx_error_handling = 1; + rx_flow_cfg.rx_psinfo_present = 1; + rx_flow_cfg.rx_einfo_present = 1; + + rx_flow_cfg.rx_size_thresh0_en = 0; + rx_flow_cfg.rx_size_thresh1_en = 0; + rx_flow_cfg.rx_size_thresh2_en = 0; + + rx_flow_cfg.rx_dest_tag_lo_sel = 0; + rx_flow_cfg.rx_dest_tag_hi_sel = 0; + rx_flow_cfg.rx_src_tag_lo_sel = 0; + rx_flow_cfg.rx_src_tag_hi_sel = 0; + + tmp_queue = Qmss_getQueueNumber(queue); + + rx_flow_cfg.rx_fdq0_sz0_qnum = tmp_queue.qNum; + rx_flow_cfg.rx_fdq0_sz0_qmgr = tmp_queue.qMgr; + + rx_flow_cfg.rx_fdq1_qnum = tmp_queue.qNum; + rx_flow_cfg.rx_fdq1_qmgr = tmp_queue.qMgr; + + rx_flow_cfg.rx_fdq2_qnum = tmp_queue.qNum; + rx_flow_cfg.rx_fdq2_qmgr = tmp_queue.qMgr; + + rx_flow_cfg.rx_fdq3_qnum = tmp_queue.qNum; + rx_flow_cfg.rx_fdq3_qmgr = tmp_queue.qMgr; + + flow = Cppi_configureRxFlow(odp_global->nwal.info.passCppiHandle, + &rx_flow_cfg, + &is_alloc); + return flow; +} + +int32_t _odp_pool_cppi_flow_id(odp_pool_t pool) +{ + Cppi_FlowHnd flow; + pool_entry_t *entry = _odp_pool_entry(pool); + ODP_ASSERT(entry, "Invalid pool entry"); + + POOL_LOCK(&entry->lock); + if (entry->cppi_flow.handle) { + POOL_UNLOCK(&entry->lock); + return entry->cppi_flow.id; + } + + flow = _create_cppi_flow(entry->free_queue, + entry->headroom); + if (!flow) { + POOL_UNLOCK(&entry->lock); + return -1; + } + + entry->cppi_flow.handle = flow; + entry->cppi_flow.id = Cppi_getFlowId(flow); + POOL_UNLOCK(&entry->lock); + + return entry->cppi_flow.id; +}