Binding for PCIe transport, starting point

Beginning of PCIe VDM binding implementation for aspeed AST2600.
Only stubs for initialization routines, api and callbacks.

This implementation depends on AST600 mctp driver (work in progress).
We don't plan to extend this implementation to other HW platforms.

Tests initialization routine with assert checks of crucial parameters.

Change-Id: I885ce82d68345bdcf06f99005c40ea2f7bdcbd4b
Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a0cace7..bca9136 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@
 add_definitions (-DMCTP_HAVE_STDIO)
 add_definitions (-DMCTP_DEFAULT_ALLOC)
 
-add_library (mctp STATIC alloc.c astlpc.c core.c log.c libmctp.h serial.c)
+add_library (mctp STATIC alloc.c astlpc.c core.c log.c libmctp.h serial.c astpcie.c)
 
 target_include_directories (mctp PUBLIC
                             $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
@@ -33,6 +33,10 @@
 target_link_libraries (test_serial mctp)
 add_test (NAME serial COMMAND test_serial)
 
+add_executable (test_astpcie tests/test_astpcie.c)
+target_link_libraries (test_astpcie mctp)
+add_test (NAME astpcie COMMAND test_astpcie)
+
 install (TARGETS mctp DESTINATION lib)
 install (FILES libmctp.h DESTINATION include)
 
diff --git a/Makefile.am b/Makefile.am
index c93d452..bd338c5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,6 +15,11 @@
 include_HEADERS += libmctp-astlpc.h
 endif
 
+if LIBMCTP_BINDING_astpcie
+libmctp_la_SOURCES += astpcie.c
+include_HEADERS += libmctp-astpcie.h
+endif
+
 if HAVE_SYSTEMD
 systemdsystemunit_DATA = \
 	mctp-demux.service
@@ -40,7 +45,8 @@
 TESTS = $(check_PROGRAMS)
 
 check_PROGRAMS = tests/test_eid tests/test_seq tests/test_bridge \
-		 tests/test_astlpc tests/test_serial
+		 tests/test_astlpc tests/test_serial \
+		 tests/test_astpcie
 # We set a global LDADD here, as there's no way to specify it for all
 # tests. This means other targets' LDADDs need to be overridden.
 LDADD = tests/libtest-utils.a libmctp.la
diff --git a/astpcie.c b/astpcie.c
new file mode 100644
index 0000000..565c7ed
--- /dev/null
+++ b/astpcie.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libmctp.h"
+#include "libmctp-alloc.h"
+#include "libmctp-astpcie.h"
+#include "container_of.h"
+
+#include "astpcie.h"
+
+#define binding_to_astpcie(b) \
+    container_of(b, struct mctp_binding_astpcie, binding)
+
+/* dummy start function */
+int mctp_binding_astpcie_start(struct mctp_binding *binding) {
+    return -1;
+}
+
+/* dummy tx function */
+int mctp_binding_astpcie_tx(struct mctp_binding *binding,
+                         struct mctp_pktbuf *pkt) {
+    return -1;
+}
+
+struct mctp_binding_astpcie *mctp_binding_astpcie_init(void)
+{
+    struct mctp_binding_astpcie *pcie;
+    pcie = __mctp_alloc(sizeof(*pcie));
+    memset(pcie, 0, sizeof(*pcie));
+
+    pcie->binding.name = "astpcie";
+    pcie->binding.version = 1;
+    pcie->binding.tx = mctp_binding_astpcie_tx;
+    pcie->binding.start = mctp_binding_astpcie_start;
+    pcie->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
+    pcie->binding.pkt_pad = 0;
+
+    return pcie;
+}
+
+void mctp_binding_astpcie_free(struct mctp_binding_astpcie *b) {
+    __mctp_free(b);
+}
+
+struct mctp_binding *mctp_binding_astpcie_core(struct mctp_binding_astpcie *b) {
+    return &b->binding;
+}
diff --git a/astpcie.h b/astpcie.h
new file mode 100644
index 0000000..a64b2dc
--- /dev/null
+++ b/astpcie.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+
+/* This is a private header file defining binding structure for PCIe binding */
+
+#ifndef _ASTPCIE_H
+#define _ASTPCIE_H
+
+#include "libmctp.h"
+
+#define MCTP_ASTPCIE_BINDING_DEFAULT_BUFFER     1024
+
+struct mctp_binding_astpcie {
+    struct mctp_binding binding;
+    int fd;
+
+    struct mctp_pktbuf *rx_pkt;
+
+    /* placeholder for buffer */
+    uint8_t rxbuf[MCTP_ASTPCIE_BINDING_DEFAULT_BUFFER];
+};
+
+#endif
diff --git a/configure.ac b/configure.ac
index 138fa05..9b61b2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,6 +126,7 @@
 # Enable all bindings. AC_ARG_ENABLE in future.
 AM_CONDITIONAL([LIBMCTP_BINDING_serial], [true])
 AM_CONDITIONAL([LIBMCTP_BINDING_astlpc], [true])
+AM_CONDITIONAL([LIBMCTP_BINDING_astpcie], [true])
 
 AX_CODE_COVERAGE
 m4_ifdef([_AX_CODE_COVERAGE_RULES],
diff --git a/libmctp-astpcie.h b/libmctp-astpcie.h
new file mode 100644
index 0000000..b63acbc
--- /dev/null
+++ b/libmctp-astpcie.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+
+#ifndef _LIBMCTP_ASTPCIE_H
+#define _LIBMCTP_ASTPCIE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libmctp.h"
+#include "libmctp-alloc.h"
+
+struct mctp_binding_astpcie;
+
+struct mctp_binding_astpcie *mctp_binding_astpcie_init(void);
+
+struct mctp_binding *mctp_binding_astpcie_core(struct mctp_binding_astpcie *b);
+
+void mctp_binding_astpcie_free(struct mctp_binding_astpcie *b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBMCTP_ASTPCIE_H */
diff --git a/tests/test_astpcie.c b/tests/test_astpcie.c
new file mode 100644
index 0000000..476d4d2
--- /dev/null
+++ b/tests/test_astpcie.c
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "libmctp-astpcie.h"
+#include "libmctp-log.h"
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "astpcie.h"
+
+#define TEST_EID   10
+
+int main(void)
+{
+    int res;
+    struct mctp *mctp;
+    struct mctp_binding *binding;
+    struct mctp_binding_astpcie *pcie;
+
+    mctp_set_log_stdio(MCTP_LOG_DEBUG);
+
+    mctp = mctp_init();
+    assert(mctp);
+
+    pcie = mctp_binding_astpcie_init();
+    assert(pcie);
+
+    binding = mctp_binding_astpcie_core(pcie);
+    assert(binding);
+
+    assert(strcmp(pcie->binding.name, "astpcie") == 0);
+    assert(pcie->binding.version == 1);
+    assert(pcie->binding.tx != NULL);
+    assert(pcie->binding.start != NULL);
+
+    res = mctp_register_bus(mctp, &pcie->binding, TEST_EID);
+    assert(res == 0);
+
+    /* cleanup */
+    mctp_binding_astpcie_free(pcie);
+    __mctp_free(mctp);
+
+    return 0;
+}