octeon: native driver for Marvell Octeon SoC
Type: feature Change-Id: I6898625c4e8854f777407dac3159e4c639a54860 Signed-off-by: Monendra Singh Kushwaha <kmonendra@marvell.com> Signed-off-by: Damjan Marion <damarion@cisco.com>
This commit is contained in:
parent
dc26d50426
commit
01fe7ab88e
@ -420,6 +420,12 @@ I: ena
|
||||
M: Damjan Marion <damarion@cisco.com>
|
||||
F: src/plugins/dev_ena/
|
||||
|
||||
Plugin - Marvell Octeon device driver
|
||||
I: octeon
|
||||
M: Monendra Singh Kushwaha <kmonendra@marvell.com>
|
||||
M: Damjan Marion <damarion@cisco.com>
|
||||
F: src/plugins/dev_octeon/
|
||||
|
||||
Plugin - Dispatch Trace PCAP
|
||||
I: dispatch-trace
|
||||
M: Dave Barach <vpp@barachs.net>
|
||||
|
@ -30,6 +30,9 @@ vpp_cmake_args += -DCMAKE_PREFIX_PATH:PATH="$(vpp_cmake_prefix_path)"
|
||||
ifeq ("$(V)","1")
|
||||
vpp_cmake_args += -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
||||
endif
|
||||
ifneq ($(VPP_PLATFORM),)
|
||||
vpp_cmake_args += -DVPP_PLATFORM="$(VPP_PLATFORM)"
|
||||
endif
|
||||
ifneq ($(VPP_EXCLUDED_PLUGINS),)
|
||||
vpp_cmake_args += -DVPP_EXCLUDED_PLUGINS="$(VPP_EXCLUDED_PLUGINS)"
|
||||
endif
|
||||
|
4
build/external/Makefile
vendored
4
build/external/Makefile
vendored
@ -35,6 +35,7 @@ CMAKE?=cmake
|
||||
endif
|
||||
|
||||
ARCH_X86_64=$(filter x86_64,$(shell uname -m))
|
||||
AARCH64=$(filter aarch64,$(shell uname -m))
|
||||
|
||||
include packages.mk
|
||||
include packages/ipsec-mb.mk
|
||||
@ -42,13 +43,14 @@ include packages/quicly.mk
|
||||
include packages/rdma-core.mk
|
||||
include packages/dpdk.mk
|
||||
include packages/xdp-tools.mk
|
||||
include packages/octeon-roc.mk
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(B) $(I)
|
||||
|
||||
.PHONY: install
|
||||
install: $(if $(ARCH_X86_64), ipsec-mb-install) dpdk-install rdma-core-install quicly-install xdp-tools-install
|
||||
install: $(if $(ARCH_X86_64), ipsec-mb-install) dpdk-install rdma-core-install quicly-install xdp-tools-install $(if $(AARCH64), octeon-roc-install)
|
||||
|
||||
.PHONY: config
|
||||
config: $(if $(ARCH_X86_64), ipsec-mb-config) dpdk-config rdma-core-config quicly-build
|
||||
|
26
build/external/packages/octeon-roc.mk
vendored
Normal file
26
build/external/packages/octeon-roc.mk
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2023 Marvell.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# https://spdx.org/licenses/Apache-2.0.html
|
||||
|
||||
octeon-roc_version := 0.2
|
||||
octeon-roc_tarball := octeon-roc-v$(octeon-roc_version).tar.gz
|
||||
octeon-roc_tarball_md5sum := a72bb3b27fd3bbaf58aadd99514620e1
|
||||
|
||||
octeon-roc_tarball_strip_dirs := 1
|
||||
octeon-roc_url := https://github.com/MarvellEmbeddedProcessors/marvell-vpp/archive/refs/tags/$(octeon-roc_tarball)
|
||||
|
||||
define octeon-roc_config_cmds
|
||||
@true
|
||||
endef
|
||||
|
||||
define octeon-roc_build_cmds
|
||||
@cd ${octeon-roc_src_dir} && rm -f $(octeon-roc_build_log) && $(CMAKE) ${octeon-roc_src_dir} -DCMAKE_INSTALL_PREFIX='$(octeon-roc_install_dir)' >> $(octeon-roc_build_log)
|
||||
@$(MAKE) -C ${octeon-roc_src_dir} >> $(octeon-roc_build_log)
|
||||
endef
|
||||
|
||||
define octeon-roc_install_cmds
|
||||
@$(MAKE) -C ${octeon-roc_src_dir} install >> $(octeon-roc_install_log)
|
||||
endef
|
||||
|
||||
$(eval $(call package,octeon-roc))
|
||||
|
12
configure
vendored
12
configure
vendored
@ -5,6 +5,7 @@ set -o pipefail -o errtrace -o nounset -o errexit
|
||||
# submitting any changes
|
||||
|
||||
# defaults
|
||||
platform=default
|
||||
build_dir=.
|
||||
install_dir=/usr/local
|
||||
build_type=release
|
||||
@ -31,6 +32,7 @@ OPTIONS:
|
||||
--native-only, -n Only compile for Native CPU (no multiarch)
|
||||
--wipe, -w Wipe whole repo (except startup.* files)
|
||||
--sanitize, -s Enable sanitizer (mem)
|
||||
--platform, -p Specify target platform
|
||||
__EOF__
|
||||
}
|
||||
|
||||
@ -76,6 +78,15 @@ while (( "$#" )); do
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-p|--platform)
|
||||
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
|
||||
platform=$2
|
||||
shift 2
|
||||
else
|
||||
echo "Error: Argument for $1 is missing" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-n|--native-only)
|
||||
native_only=yes
|
||||
shift 1
|
||||
@ -121,6 +132,7 @@ args+=("-DCMAKE_PREFIX_PATH=/opt/vpp/external/${arch}")
|
||||
args+=("-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON")
|
||||
args+=("-DCMAKE_INSTALL_PREFIX=${install_dir}")
|
||||
args+=("-DCMAKE_BUILD_TYPE:STRING=${build_type}")
|
||||
args+=("-DVPP_PLATFORM=${platform}")
|
||||
[ "${native_only}" == "yes" ] && args+=("-DVPP_BUILD_NATIVE_ONLY:BOOL=ON")
|
||||
|
||||
[ "${wipe}" == "yes" ] && git clean -fdx --exclude=startup.\*
|
||||
|
@ -249,6 +249,7 @@ det
|
||||
dev
|
||||
devbind
|
||||
dev_iavf
|
||||
dev_octeon
|
||||
df
|
||||
dhcp
|
||||
dhcp
|
||||
@ -786,6 +787,7 @@ O'Driscoll
|
||||
oacl
|
||||
oam
|
||||
OAM
|
||||
octeon
|
||||
oddbuf
|
||||
Oddbuf
|
||||
offline
|
||||
|
46
extras/deb/mkdeb-octeon-roc
Executable file
46
extras/deb/mkdeb-octeon-roc
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
PKG=vpp-dep-octeon-roc
|
||||
URL=https://github.com/MarvellEmbeddedProcessors/marvell-vpp.git
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
TMP_DIR=$(mktemp -d -p $PWD)
|
||||
|
||||
set -eEuo pipefail
|
||||
|
||||
err_handler()
|
||||
{
|
||||
trap '' INT TERM EXIT ERR
|
||||
echo "Cleaning up ${TMP_DIR}"
|
||||
rm -rf ${TMP_DIR}
|
||||
exit
|
||||
}
|
||||
trap "err_handler" INT TERM EXIT ERR
|
||||
|
||||
SRC=${TMP_DIR}/src
|
||||
BUILD=${TMP_DIR}/build
|
||||
STAGE=${TMP_DIR}/pkg
|
||||
INSTALL_PREFIX=/opt/vpp/external/$(uname -m)
|
||||
|
||||
git clone ${URL} ${SRC}
|
||||
VER=0.0.$(git -C ${SRC} rev-list --count HEAD)
|
||||
|
||||
cmake -S ${SRC} -B ${BUILD}
|
||||
cmake --build ${BUILD} --parallel
|
||||
cmake --install ${BUILD} --prefix ${STAGE}${INSTALL_PREFIX}
|
||||
|
||||
mkdir -p ${STAGE}/DEBIAN
|
||||
|
||||
cat > ${STAGE}/DEBIAN/control << __EOF__
|
||||
Package: ${PKG}
|
||||
Version: ${VER}
|
||||
Architecture: ${ARCH}
|
||||
Maintainer: vpp-dev <vpp-dev@fd.io>
|
||||
Installed-Size: $(du -ks ${STAGE}|cut -f 1)
|
||||
Section: system
|
||||
Priority: extra
|
||||
Description: Marvell Octeon ROC library for VPP
|
||||
See https://github.com/MarvellEmbeddedProcessors/marvell-vpp
|
||||
__EOF__
|
||||
|
||||
DEB=${PKG}_${VER}_${ARCH}.deb
|
||||
dpkg-deb -b ${STAGE} ${DEB}
|
@ -13,7 +13,25 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
if(DEFINED VPP_PLATFORM AND VPP_PLATFORM STREQUAL "default")
|
||||
unset(VPP_PLATFORM)
|
||||
set(VPP_PLATFORM_NAME "default")
|
||||
elseif(DEFINED VPP_PLATFORM)
|
||||
set(platform_file ${CMAKE_SOURCE_DIR}/cmake/platform/${VPP_PLATFORM}.cmake)
|
||||
if(NOT EXISTS ${platform_file})
|
||||
message(FATAL_ERROR "unknown platform ${VPP_PLATFORM}")
|
||||
endif()
|
||||
include(${platform_file})
|
||||
set(VPP_PLATFORM_NAME ${VPP_PLATFORM})
|
||||
else()
|
||||
set(VPP_PLATFORM_NAME "default")
|
||||
endif()
|
||||
|
||||
if (DEFINED VPP_PLATFORM_C_COMPILER_NAMES)
|
||||
set(CMAKE_C_COMPILER_NAMES ${VPP_PLATFORM_C_COMPILER_NAME})
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_NAMES clang gcc cc)
|
||||
endif()
|
||||
|
||||
project(vpp C)
|
||||
|
||||
@ -37,6 +55,11 @@ execute_process(
|
||||
OUTPUT_VARIABLE VPP_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (VPP_PLATFORM)
|
||||
set(VPP_VERSION ${VPP_VERSION}-${VPP_PLATFORM_NAME})
|
||||
endif()
|
||||
|
||||
string(REPLACE "-" ";" VPP_LIB_VERSION ${VPP_VERSION})
|
||||
list(GET VPP_LIB_VERSION 0 VPP_LIB_VERSION)
|
||||
|
||||
@ -183,7 +206,7 @@ if(VPP_ENABLE_TRAJECTORY_TRACE)
|
||||
endif()
|
||||
|
||||
##############################################################################
|
||||
# unittest with clang ode coverage
|
||||
# unittest with clang code coverage
|
||||
##############################################################################
|
||||
|
||||
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13" AND "${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||
@ -307,6 +330,7 @@ mark_as_advanced(CLEAR
|
||||
# print configuration
|
||||
##############################################################################
|
||||
message(STATUS "Configuration:")
|
||||
pr("VPP platform" ${VPP_PLATFORM_NAME})
|
||||
pr("VPP version" ${VPP_VERSION})
|
||||
pr("VPP library version" ${VPP_LIB_VERSION})
|
||||
pr("GIT toplevel dir" ${VPP_GIT_TOPLEVEL_DIR})
|
||||
|
@ -24,6 +24,10 @@ endmacro()
|
||||
##############################################################################
|
||||
# Cache line size
|
||||
##############################################################################
|
||||
|
||||
if(DEFINED VPP_PLATFORM_CACHE_LINE_SIZE)
|
||||
set(VPP_CACHE_LINE_SIZE ${VPP_PLATFORM_CACHE_LINE_SIZE})
|
||||
else()
|
||||
if(DEFINED VPP_CACHE_LINE_SIZE)
|
||||
# Cache line size assigned via cmake args
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
|
||||
@ -34,6 +38,7 @@ endif()
|
||||
|
||||
set(VPP_CACHE_LINE_SIZE ${VPP_CACHE_LINE_SIZE}
|
||||
CACHE STRING "Target CPU cache line size")
|
||||
endif()
|
||||
|
||||
set_log2_cacheline_size(VPP_LOG2_CACHE_LINE_SIZE ${VPP_CACHE_LINE_SIZE})
|
||||
|
||||
@ -57,7 +62,9 @@ endif()
|
||||
# CPU optimizations and multiarch support
|
||||
##############################################################################
|
||||
|
||||
if(NOT DEFINED VPP_PLATFORM)
|
||||
option(VPP_BUILD_NATIVE_ONLY "Build only for native CPU." OFF)
|
||||
endif()
|
||||
|
||||
macro(add_vpp_march_variant v)
|
||||
cmake_parse_arguments(ARG
|
||||
@ -104,15 +111,24 @@ macro(add_vpp_march_variant v)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
if(VPP_BUILD_NATIVE_ONLY)
|
||||
if(DEFINED VPP_PLATFORM)
|
||||
if(DEFINED VPP_PLATFORM_MARCH_FLAGS)
|
||||
set(VPP_DEFAULT_MARCH_FLAGS ${VPP_PLATFORM_MARCH_FLAGS})
|
||||
check_c_compiler_flag(${VPP_DEFAULT_MARCH_FLAGS} compiler_flag_march)
|
||||
if(NOT compiler_flag_march)
|
||||
message(FATAL_ERROR "platform build with ${VPP_DEFAULT_MARCH_FLAGS} is not supported by compiler")
|
||||
endif()
|
||||
else()
|
||||
set(VPP_DEFAULT_MARCH_FLAGS "")
|
||||
endif()
|
||||
set(MARCH_VARIANTS_NAMES "platform-only")
|
||||
elseif(VPP_BUILD_NATIVE_ONLY)
|
||||
set(VPP_BUILD_NATIVE_ARCH "native" CACHE STRING "native CPU -march= value.")
|
||||
set(VPP_DEFAULT_MARCH_FLAGS -march=${VPP_BUILD_NATIVE_ARCH})
|
||||
if(VPP_BUILD_NATIVE_ONLY)
|
||||
check_c_compiler_flag(${VPP_DEFAULT_MARCH_FLAGS} compiler_flag_march)
|
||||
if(NOT compiler_flag_march)
|
||||
message(FATAL_ERROR "Native-only build with ${VPP_DEFAULT_MARCH_FLAGS} is not supported by compiler")
|
||||
endif()
|
||||
endif()
|
||||
set(MARCH_VARIANTS_NAMES "native-only")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
|
||||
set(VPP_DEFAULT_MARCH_FLAGS -march=corei7 -mtune=corei7-avx)
|
||||
|
3
src/cmake/platform/octeon10.cmake
Normal file
3
src/cmake/platform/octeon10.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
set(VPP_PLATFORM_CACHE_LINE_SIZE 64)
|
||||
set(VPP_PLATFORM_MARCH_FLAGS -march=armv8.3-a+crypto+sve2-bitperm)
|
41
src/plugins/dev_octeon/CMakeLists.txt
Normal file
41
src/plugins/dev_octeon/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright(c) 2022 Cisco Systems, Inc.
|
||||
|
||||
if (NOT VPP_PLATFORM_NAME STREQUAL "octeon10")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Find OCTEON roc files
|
||||
vpp_find_path(OCTEON_ROC_DIR PATH_SUFFIXES octeon-roc NAMES platform.h)
|
||||
vpp_plugin_find_library(dev-octeon OCTEON_ROC_LIB "libocteon-roc.a")
|
||||
|
||||
if (NOT OCTEON_ROC_DIR)
|
||||
message("OCTEON ROC files not found - Marvell OCTEON device plugin disabled")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT OCTEON_ROC_LIB)
|
||||
message("OCTEON ROC library (libocteon-roc.a) not found - Marvell OCTEON device plugin disabled")
|
||||
return ()
|
||||
endif()
|
||||
|
||||
include_directories (${OCTEON_ROC_DIR}/)
|
||||
|
||||
add_vpp_plugin(dev_octeon
|
||||
SOURCES
|
||||
init.c
|
||||
format.c
|
||||
port.c
|
||||
queue.c
|
||||
roc_helper.c
|
||||
rx_node.c
|
||||
tx_node.c
|
||||
|
||||
MULTIARCH_SOURCES
|
||||
rx_node.c
|
||||
tx_node.c
|
||||
|
||||
LINK_LIBRARIES
|
||||
${OCTEON_ROC_LIB}
|
||||
)
|
||||
|
29
src/plugins/dev_octeon/common.h
Normal file
29
src/plugins/dev_octeon/common.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2023 Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _OCT_COMMON_H_
|
||||
#define _OCT_COMMON_H_
|
||||
|
||||
#include <vppinfra/clib.h>
|
||||
#include <vppinfra/format.h>
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/dev/dev.h>
|
||||
#include <base/roc_api.h>
|
||||
|
||||
static_always_inline u32
|
||||
oct_aura_free_all_buffers (vlib_main_t *vm, u64 aura_handle, u16 hdr_off)
|
||||
{
|
||||
u32 n = 0;
|
||||
u64 iova;
|
||||
|
||||
while ((iova = roc_npa_aura_op_alloc (aura_handle, 0)))
|
||||
{
|
||||
vlib_buffer_t *b = (void *) iova + hdr_off;
|
||||
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, b));
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif /* _OCT_COMMON_H_ */
|
164
src/plugins/dev_octeon/format.c
Normal file
164
src/plugins/dev_octeon/format.c
Normal file
@ -0,0 +1,164 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2023 Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#include "vlib/pci/pci.h"
|
||||
#include "vnet/error.h"
|
||||
#include "vppinfra/error.h"
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/dev/dev.h>
|
||||
#include <dev_octeon/octeon.h>
|
||||
|
||||
u8 *
|
||||
format_oct_port_status (u8 *s, va_list *args)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_oct_nix_rx_cqe_desc (u8 *s, va_list *args)
|
||||
{
|
||||
oct_nix_rx_cqe_desc_t *d = va_arg (*args, oct_nix_rx_cqe_desc_t *);
|
||||
u32 indent = format_get_indent (s);
|
||||
typeof (d->hdr) *h = &d->hdr;
|
||||
typeof (d->parse.f) *p = &d->parse.f;
|
||||
typeof (d->sg0) *sg0 = &d->sg0;
|
||||
typeof (d->sg0) *sg1 = &d->sg1;
|
||||
|
||||
s = format (s, "hdr: cqe_type %u nude %u q %u tag 0x%x", h->cqe_type,
|
||||
h->node, h->q, h->tag);
|
||||
s = format (s, "\n%Uparse:", format_white_space, indent);
|
||||
#define _(n, f) s = format (s, " " #n " " f, p->n)
|
||||
_ (chan, "%u");
|
||||
_ (errcode, "%u");
|
||||
_ (errlev, "%u");
|
||||
_ (desc_sizem1, "%u");
|
||||
_ (pkt_lenm1, "%u");
|
||||
_ (pkind, "%u");
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
_ (nix_idx, "%u");
|
||||
_ (color, "%u");
|
||||
_ (flow_key_alg, "%u");
|
||||
_ (eoh_ptr, "%u");
|
||||
_ (match_id, "0x%x");
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
_ (wqe_aura, "0x%x");
|
||||
_ (pb_aura, "0x%x");
|
||||
_ (imm_copy, "%u");
|
||||
_ (express, "%u");
|
||||
_ (wqwd, "%u");
|
||||
_ (l2m, "%u");
|
||||
_ (l2b, "%u");
|
||||
_ (l3m, "%u");
|
||||
_ (l3b, "%u");
|
||||
#undef _
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
s = format (s, "layer: a b c d e f g h");
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
s = format (s, "type: %3u %3u %3u %3u %3u %3u %3u %3u", p->latype,
|
||||
p->lbtype, p->lctype, p->ldtype, p->letype, p->lftype, p->lgtype,
|
||||
p->lhtype);
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
s = format (
|
||||
s, "flags: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
|
||||
p->laflags, p->lbflags, p->lcflags, p->ldflags, p->leflags, p->lfflags,
|
||||
p->lgflags, p->lhflags);
|
||||
s = format (s, "\n%U ", format_white_space, indent);
|
||||
s = format (s, "ptr: %3u %3u %3u %3u %3u %3u %3u %3u", p->laptr,
|
||||
p->lbptr, p->lcptr, p->ldptr, p->leptr, p->lfptr, p->lgptr,
|
||||
p->lhptr);
|
||||
|
||||
if (sg0->subdc != 0x4)
|
||||
return format (s, "\n%Usg0: unexpected subdc %x", format_white_space,
|
||||
indent, sg0->subdc);
|
||||
|
||||
s = format (s,
|
||||
"\n%Usg0: segs %u seg1_sz %u seg2_sz %u seg3_sz %u seg1 "
|
||||
"%p seg2 %p seg3 %p",
|
||||
format_white_space, indent, sg0->segs, sg0->seg1_size,
|
||||
sg0->seg2_size, sg0->seg3_size, d->segs0[0], d->segs0[1],
|
||||
d->segs0[2]);
|
||||
|
||||
if (sg1->subdc != 0x4 && sg1->subdc != 0)
|
||||
return format (s, "\n%Usg1: unexpected subdc %x", format_white_space,
|
||||
indent, sg1->subdc);
|
||||
|
||||
if (sg1->subdc == 4)
|
||||
s = format (s,
|
||||
"\n%Usg1: segs %u seg1_sz %u seg2_sz %u seg3_sz %u seg1 "
|
||||
"%p seg2 %p seg3 %p",
|
||||
format_white_space, indent, sg1->segs, sg1->seg1_size,
|
||||
sg1->seg2_size, sg1->seg3_size, d->segs1[0], d->segs1[1],
|
||||
d->segs1[2]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_oct_rx_trace (u8 *s, va_list *args)
|
||||
{
|
||||
vlib_main_t *vm = va_arg (*args, vlib_main_t *);
|
||||
vlib_node_t *node = va_arg (*args, vlib_node_t *);
|
||||
oct_rx_trace_t *t = va_arg (*args, oct_rx_trace_t *);
|
||||
u32 indent = format_get_indent (s);
|
||||
|
||||
s = format (s, "octeon-rx: next-node %U sw_if_index %u",
|
||||
format_vlib_next_node_name, vm, node->index, t->next_index,
|
||||
t->sw_if_index);
|
||||
s = format (s, "\n%U%U", format_white_space, indent + 2,
|
||||
format_oct_nix_rx_cqe_desc, &t->desc);
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_oct_tx_trace (u8 *s, va_list *args)
|
||||
{
|
||||
va_arg (*args, vlib_main_t *);
|
||||
va_arg (*args, vlib_node_t *);
|
||||
oct_tx_trace_t *t = va_arg (*args, oct_tx_trace_t *);
|
||||
u32 indent = format_get_indent (s);
|
||||
|
||||
s = format (s, "octeon-tx: sw_if_index %u", t->sw_if_index);
|
||||
s = format (s, "\n%Uhdr[0]:", format_white_space, indent + 2);
|
||||
#define _(n, f) s = format (s, " " #n " " f, t->desc.hdr_w0.n)
|
||||
_ (total, "%u");
|
||||
_ (df, "%u");
|
||||
_ (aura, "0x%x");
|
||||
_ (sizem1, "%u");
|
||||
_ (pnc, "%u");
|
||||
_ (sq, "%u");
|
||||
#undef _
|
||||
s = format (s, "\n%Uhdr[1]:", format_white_space, indent + 2);
|
||||
#define _(n, f) s = format (s, " " #n " " f, t->desc.hdr_w1.n)
|
||||
_ (ol3ptr, "%u");
|
||||
_ (ol4ptr, "%u");
|
||||
_ (il3ptr, "%u");
|
||||
_ (il4ptr, "%u");
|
||||
_ (ol3type, "%u");
|
||||
_ (ol4type, "%u");
|
||||
_ (il3type, "%u");
|
||||
_ (il4type, "%u");
|
||||
_ (sqe_id, "%u");
|
||||
#undef _
|
||||
|
||||
foreach_int (j, 0, 4)
|
||||
{
|
||||
s = format (s, "\n%Usg[%u]:", format_white_space, indent + 2, j);
|
||||
#define _(n, f) s = format (s, " " #n " " f, t->desc.sg[j].n)
|
||||
_ (subdc, "%u");
|
||||
_ (segs, "%u");
|
||||
_ (seg1_size, "%u");
|
||||
_ (seg2_size, "%u");
|
||||
_ (seg3_size, "%u");
|
||||
_ (i1, "%u");
|
||||
_ (i2, "%u");
|
||||
_ (i3, "%u");
|
||||
_ (ld_type, "%u");
|
||||
#undef _
|
||||
for (int i = 1; i < 4; i++)
|
||||
s = format (s, "\n%Usg[%u]: %p", format_white_space, indent + 2, i + j,
|
||||
t->desc.sg[i + j]);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
98
src/plugins/dev_octeon/hw_defs.h
Normal file
98
src/plugins/dev_octeon/hw_defs.h
Normal file
@ -0,0 +1,98 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2023 Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _OCT_HW_DEFS_H_
|
||||
#define _OCT_HW_DEFS_H_
|
||||
|
||||
#include <vppinfra/clib.h>
|
||||
#include <base/roc_api.h>
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u64 tail : 20;
|
||||
u64 head : 20;
|
||||
u64 resv40 : 6;
|
||||
u64 cq_err : 1;
|
||||
u64 resv47 : 16;
|
||||
u64 op_err : 1;
|
||||
};
|
||||
u64 as_u64;
|
||||
} oct_nix_lf_cq_op_status_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_nix_lf_cq_op_status_t, 8);
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u64 aura : 20;
|
||||
u64 _reseved20 : 12;
|
||||
u64 count_eot : 1;
|
||||
u64 _reserved33 : 30;
|
||||
u64 fabs : 1;
|
||||
};
|
||||
u64 as_u64;
|
||||
} oct_npa_lf_aura_batch_free0_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_npa_lf_aura_batch_free0_t, 8);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
oct_npa_lf_aura_batch_free0_t w0;
|
||||
u64 data[15];
|
||||
} oct_npa_lf_aura_batch_free_line_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_npa_lf_aura_batch_free_line_t, 128);
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct npa_batch_alloc_compare_s compare_s;
|
||||
u64 as_u64;
|
||||
} oct_npa_batch_alloc_compare_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union nix_send_hdr_w0_u hdr_w0;
|
||||
union nix_send_hdr_w1_u hdr_w1;
|
||||
union nix_send_sg_s sg[8];
|
||||
};
|
||||
u128 as_u128[5];
|
||||
} oct_tx_desc_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_tx_desc_t, 80);
|
||||
|
||||
typedef union
|
||||
{
|
||||
u128 dwords[8];
|
||||
u64 words[16];
|
||||
} lmt_line_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (lmt_line_t, 1 << ROC_LMT_LINE_SIZE_LOG2);
|
||||
|
||||
typedef union
|
||||
{
|
||||
union nix_rx_parse_u f;
|
||||
u64 w[7];
|
||||
} oct_nix_rx_parse_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_nix_rx_parse_t, 56);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLIB_ALIGN_MARK (desc, 128);
|
||||
struct nix_cqe_hdr_s hdr;
|
||||
oct_nix_rx_parse_t parse;
|
||||
struct nix_rx_sg_s sg0;
|
||||
void *segs0[3];
|
||||
struct nix_rx_sg_s sg1;
|
||||
void *segs1[3];
|
||||
} oct_nix_rx_cqe_desc_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_nix_rx_cqe_desc_t, 128);
|
||||
|
||||
#endif /* _OCT_HW_DEFS_H_ */
|
301
src/plugins/dev_octeon/init.c
Normal file
301
src/plugins/dev_octeon/init.c
Normal file
File diff suppressed because it is too large
Load Diff
154
src/plugins/dev_octeon/octeon.h
Normal file
154
src/plugins/dev_octeon/octeon.h
Normal file
@ -0,0 +1,154 @@
|
||||
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2023 Cisco Systems, Inc.
|
||||
*/
|
||||
#ifndef _OCTEON_H_
|
||||
#define _OCTEON_H_
|
||||
#include <vppinfra/clib.h>
|
||||
#include <vppinfra/error_bootstrap.h>
|
||||
#include <vppinfra/format.h>
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/dev/dev.h>
|
||||
#include <base/roc_api.h>
|
||||
#include <dev_octeon/hw_defs.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OCT_DEVICE_TYPE_UNKNOWN = 0,
|
||||
OCT_DEVICE_TYPE_RVU_PF,
|
||||
OCT_DEVICE_TYPE_CPT_VF,
|
||||
} __clib_packed oct_device_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
oct_device_type_t type;
|
||||
u8 nix_initialized : 1;
|
||||
u8 status : 1;
|
||||
u8 full_duplex : 1;
|
||||
u32 speed;
|
||||
struct plt_pci_device plt_pci_dev;
|
||||
struct roc_cpt cpt;
|
||||
struct roc_nix *nix;
|
||||
} oct_device_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 lf_allocated : 1;
|
||||
u8 tm_initialized : 1;
|
||||
u8 npc_initialized : 1;
|
||||
struct roc_npc npc;
|
||||
} oct_port_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 npa_pool_initialized : 1;
|
||||
u8 cq_initialized : 1;
|
||||
u8 rq_initialized : 1;
|
||||
u16 hdr_off;
|
||||
u32 n_enq;
|
||||
u64 aura_handle;
|
||||
u64 aura_batch_free_ioaddr;
|
||||
u64 lmt_base_addr;
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (data0);
|
||||
struct roc_nix_cq cq;
|
||||
struct roc_nix_rq rq;
|
||||
} oct_rxq_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLIB_ALIGN_MARK (cl, 128);
|
||||
union
|
||||
{
|
||||
struct npa_batch_alloc_status_s status;
|
||||
u64 iova[16];
|
||||
};
|
||||
} oct_npa_batch_alloc_cl128_t;
|
||||
|
||||
STATIC_ASSERT_SIZEOF (oct_npa_batch_alloc_cl128_t, 128);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 sq_initialized : 1;
|
||||
u8 npa_pool_initialized : 1;
|
||||
u16 hdr_off;
|
||||
u32 n_enq;
|
||||
u64 aura_handle;
|
||||
u64 io_addr;
|
||||
void *lmt_addr;
|
||||
|
||||
oct_npa_batch_alloc_cl128_t *ba_buffer;
|
||||
u8 ba_first_cl;
|
||||
u8 ba_num_cl;
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (data0);
|
||||
struct roc_nix_sq sq;
|
||||
} oct_txq_t;
|
||||
|
||||
/* format.c */
|
||||
format_function_t format_oct_port_status;
|
||||
format_function_t format_oct_rx_trace;
|
||||
format_function_t format_oct_tx_trace;
|
||||
|
||||
/* port.c */
|
||||
vnet_dev_rv_t oct_port_init (vlib_main_t *, vnet_dev_port_t *);
|
||||
vnet_dev_rv_t oct_port_start (vlib_main_t *, vnet_dev_port_t *);
|
||||
void oct_port_stop (vlib_main_t *, vnet_dev_port_t *);
|
||||
void oct_port_deinit (vlib_main_t *, vnet_dev_port_t *);
|
||||
vnet_dev_rv_t oct_port_cfg_change (vlib_main_t *, vnet_dev_port_t *,
|
||||
vnet_dev_port_cfg_change_req_t *);
|
||||
|
||||
/* queue.c */
|
||||
vnet_dev_rv_t oct_rx_queue_alloc (vlib_main_t *, vnet_dev_rx_queue_t *);
|
||||
vnet_dev_rv_t oct_tx_queue_alloc (vlib_main_t *, vnet_dev_tx_queue_t *);
|
||||
void oct_rx_queue_free (vlib_main_t *, vnet_dev_rx_queue_t *);
|
||||
void oct_tx_queue_free (vlib_main_t *, vnet_dev_tx_queue_t *);
|
||||
vnet_dev_rv_t oct_rxq_init (vlib_main_t *, vnet_dev_rx_queue_t *);
|
||||
vnet_dev_rv_t oct_txq_init (vlib_main_t *, vnet_dev_tx_queue_t *);
|
||||
void oct_rxq_deinit (vlib_main_t *, vnet_dev_rx_queue_t *);
|
||||
void oct_txq_deinit (vlib_main_t *, vnet_dev_tx_queue_t *);
|
||||
format_function_t format_oct_rxq_info;
|
||||
format_function_t format_oct_txq_info;
|
||||
|
||||
#define log_debug(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_DEBUG, oct_log.class, "%U: " f, \
|
||||
format_vnet_dev_addr, (dev), ##__VA_ARGS__)
|
||||
#define log_info(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_INFO, oct_log.class, "%U: " f, \
|
||||
format_vnet_dev_addr, (dev), ##__VA_ARGS__)
|
||||
#define log_notice(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_NOTICE, oct_log.class, "%U: " f, \
|
||||
format_vnet_dev_addr, (dev), ##__VA_ARGS__)
|
||||
#define log_warn(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_WARNING, oct_log.class, "%U: " f, \
|
||||
format_vnet_dev_addr, (dev), ##__VA_ARGS__)
|
||||
#define log_err(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_ERR, oct_log.class, "%U: " f, \
|
||||
format_vnet_dev_addr, (dev), ##__VA_ARGS__)
|
||||
|
||||
#define foreach_oct_tx_node_counter \
|
||||
_ (CHAIN_TOO_LONG, chain_too_long, ERROR, "drop due to buffer chain > 6") \
|
||||
_ (NO_FREE_SLOTS, no_free_slots, ERROR, "no free tx slots") \
|
||||
_ (AURA_BATCH_ALLOC_ISSUE_FAIL, aura_batch_alloc_issue_fail, ERROR, \
|
||||
"aura batch alloc issue failed") \
|
||||
_ (AURA_BATCH_ALLOC_NOT_READY, aura_batch_alloc_not_ready, ERROR, \
|
||||
"aura batch alloc not ready")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define _(f, n, s, d) OCT_TX_NODE_CTR_##f,
|
||||
foreach_oct_tx_node_counter
|
||||
#undef _
|
||||
} oct_tx_node_counter_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u32 next_index;
|
||||
oct_nix_rx_cqe_desc_t desc;
|
||||
} oct_rx_trace_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
oct_tx_desc_t desc;
|
||||
} oct_tx_trace_t;
|
||||
#endif /* _OCTEON_H_ */
|
418
src/plugins/dev_octeon/port.c
Normal file
418
src/plugins/dev_octeon/port.c
Normal file
File diff suppressed because it is too large
Load Diff
303
src/plugins/dev_octeon/queue.c
Normal file
303
src/plugins/dev_octeon/queue.c
Normal file
File diff suppressed because it is too large
Load Diff
181
src/plugins/dev_octeon/roc_helper.c
Normal file
181
src/plugins/dev_octeon/roc_helper.c
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Marvell.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* https://spdx.org/licenses/Apache-2.0.html
|
||||
*/
|
||||
|
||||
#include <vnet/vnet.h>
|
||||
#include <vlib/pci/pci.h>
|
||||
#include <vlib/linux/vfio.h>
|
||||
#include <base/roc_api.h>
|
||||
#include <common.h>
|
||||
|
||||
static oct_plt_memzone_list_t memzone_list;
|
||||
|
||||
static inline void
|
||||
oct_plt_log (oct_plt_log_level_t level, oct_plt_log_class_t cls, char *fmt,
|
||||
...)
|
||||
{
|
||||
vlib_log ((vlib_log_level_t) level, cls, fmt);
|
||||
}
|
||||
|
||||
static inline void
|
||||
oct_plt_spinlock_init (oct_plt_spinlock_t *p)
|
||||
{
|
||||
clib_spinlock_init ((clib_spinlock_t *) p);
|
||||
}
|
||||
|
||||
static void
|
||||
oct_plt_spinlock_lock (oct_plt_spinlock_t *p)
|
||||
{
|
||||
clib_spinlock_lock ((clib_spinlock_t *) p);
|
||||
}
|
||||
|
||||
static void
|
||||
oct_plt_spinlock_unlock (oct_plt_spinlock_t *p)
|
||||
{
|
||||
clib_spinlock_unlock ((clib_spinlock_t *) p);
|
||||
}
|
||||
|
||||
static int
|
||||
oct_plt_spinlock_trylock (oct_plt_spinlock_t *p)
|
||||
{
|
||||
return clib_spinlock_trylock ((clib_spinlock_t *) p);
|
||||
}
|
||||
|
||||
static u64
|
||||
oct_plt_get_thread_index (void)
|
||||
{
|
||||
return __os_thread_index;
|
||||
}
|
||||
|
||||
static void
|
||||
oct_drv_physmem_free (vlib_main_t *vm, void *mem)
|
||||
{
|
||||
if (!mem)
|
||||
{
|
||||
clib_warning ("Invalid address %p", mem);
|
||||
return;
|
||||
}
|
||||
|
||||
vlib_physmem_free (vm, mem);
|
||||
}
|
||||
|
||||
static void *
|
||||
oct_drv_physmem_alloc (vlib_main_t *vm, u32 size, u32 align)
|
||||
{
|
||||
clib_error_t *error = NULL;
|
||||
uword *mem = NULL;
|
||||
|
||||
if (align)
|
||||
{
|
||||
/* Force cache line alloc in case alignment is less than cache line */
|
||||
align = align < CLIB_CACHE_LINE_BYTES ? CLIB_CACHE_LINE_BYTES : align;
|
||||
mem = vlib_physmem_alloc_aligned_on_numa (vm, size, align, 0);
|
||||
}
|
||||
else
|
||||
mem =
|
||||
vlib_physmem_alloc_aligned_on_numa (vm, size, CLIB_CACHE_LINE_BYTES, 0);
|
||||
if (!mem)
|
||||
return NULL;
|
||||
|
||||
error = vfio_map_physmem_page (vm, mem);
|
||||
if (error)
|
||||
goto report_error;
|
||||
|
||||
clib_memset (mem, 0, size);
|
||||
return mem;
|
||||
|
||||
report_error:
|
||||
clib_error_report (error);
|
||||
oct_drv_physmem_free (vm, mem);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
oct_plt_free (void *addr)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
|
||||
oct_drv_physmem_free ((void *) vm, addr);
|
||||
}
|
||||
|
||||
static void *
|
||||
oct_plt_zmalloc (u32 size, u32 align)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
|
||||
return oct_drv_physmem_alloc (vm, size, align);
|
||||
}
|
||||
|
||||
static oct_plt_memzone_t *
|
||||
memzone_get (u32 index)
|
||||
{
|
||||
if (index == ((u32) ~0))
|
||||
return 0;
|
||||
|
||||
return pool_elt_at_index (memzone_list.mem_pool, index);
|
||||
}
|
||||
|
||||
static int
|
||||
oct_plt_memzone_free (const oct_plt_memzone_t *name)
|
||||
{
|
||||
uword *p;
|
||||
p = hash_get_mem (memzone_list.memzone_by_name, name);
|
||||
|
||||
if (p[0] == ((u32) ~0))
|
||||
return -EINVAL;
|
||||
|
||||
hash_unset_mem (memzone_list.memzone_by_name, name);
|
||||
|
||||
pool_put_index (memzone_list.mem_pool, p[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static oct_plt_memzone_t *
|
||||
oct_plt_memzone_lookup (const char *name)
|
||||
{
|
||||
uword *p;
|
||||
p = hash_get_mem (memzone_list.memzone_by_name, name);
|
||||
if (p)
|
||||
return memzone_get (p[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static oct_plt_memzone_t *
|
||||
oct_plt_memzone_reserve_aligned (const char *name, u64 len, u8 socket,
|
||||
u32 flags, u32 align)
|
||||
{
|
||||
oct_plt_memzone_t *mem_pool;
|
||||
void *p = NULL;
|
||||
|
||||
pool_get_zero (memzone_list.mem_pool, mem_pool);
|
||||
|
||||
p = oct_plt_zmalloc (len, align);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
mem_pool->addr = p;
|
||||
mem_pool->index = mem_pool - memzone_list.mem_pool;
|
||||
hash_set_mem (memzone_list.memzone_by_name, name, mem_pool->index);
|
||||
|
||||
return mem_pool;
|
||||
}
|
||||
|
||||
oct_plt_init_param_t oct_plt_init_param = {
|
||||
.oct_plt_log_reg_class = vlib_log_register_class,
|
||||
.oct_plt_log = oct_plt_log,
|
||||
.oct_plt_free = oct_plt_free,
|
||||
.oct_plt_zmalloc = oct_plt_zmalloc,
|
||||
.oct_plt_memzone_free = oct_plt_memzone_free,
|
||||
.oct_plt_memzone_lookup = oct_plt_memzone_lookup,
|
||||
.oct_plt_memzone_reserve_aligned = oct_plt_memzone_reserve_aligned,
|
||||
.oct_plt_spinlock_init = oct_plt_spinlock_init,
|
||||
.oct_plt_spinlock_lock = oct_plt_spinlock_lock,
|
||||
.oct_plt_spinlock_unlock = oct_plt_spinlock_unlock,
|
||||
.oct_plt_spinlock_trylock = oct_plt_spinlock_trylock,
|
||||
.oct_plt_get_thread_index = oct_plt_get_thread_index,
|
||||
};
|
385
src/plugins/dev_octeon/rx_node.c
Normal file
385
src/plugins/dev_octeon/rx_node.c
Normal file
File diff suppressed because it is too large
Load Diff
427
src/plugins/dev_octeon/tx_node.c
Normal file
427
src/plugins/dev_octeon/tx_node.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user