core: Reuse buffers for tx, allow message pools

Use new m_msg_alloc/m_msg_free operations for whole-message
MCTP buffers. m_realloc is no longer used, instead the maximum
sized buffer is allocated for each reassembly.
This allows applications to keep a pool of MCTP message buffers.

Don't create a queue of packets to transmit, instead reuse a single
binding-provided tx_storage buffer for each transmitted packet, which
can be static for bindings that have a known maximum packet size.

Asynchronous users/bindings can no longer rely on the core for queueing
TX packets, instead they should test mctp_is_tx_ready() prior to calling
mctp_message_tx(). The stack will return -EBUSY from mctp_message_tx()
if there is already a message pending to send.

Bindings must be updated to add the tx_storage member, and the core will
no longer free packets passed to mctp_bus_rx().

Change-Id: I2598bb91026ccef01b268c52b06c0f8e20bebb1e
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
diff --git a/tests/test-utils.c b/tests/test-utils.c
index cbb931b..ccbe382 100644
--- a/tests/test-utils.c
+++ b/tests/test-utils.c
@@ -14,6 +14,7 @@
 
 struct mctp_binding_test {
 	struct mctp_binding binding;
+	uint8_t tx_storage[MCTP_PKTBUF_SIZE(MCTP_BTU)];
 };
 
 static int mctp_binding_test_tx(struct mctp_binding *b __attribute__((unused)),
@@ -35,6 +36,7 @@
 	test->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
 	test->binding.pkt_header = 0;
 	test->binding.pkt_trailer = 0;
+	test->binding.tx_storage = test->tx_storage;
 	return test;
 }
 
@@ -52,6 +54,7 @@
 	assert(pkt);
 	memcpy(mctp_pktbuf_hdr(pkt), buf, len);
 	mctp_bus_rx(&test->binding, pkt);
+	mctp_pktbuf_free(pkt);
 }
 
 void mctp_binding_test_register_bus(struct mctp_binding_test *binding,
diff --git a/tests/test_bridge.c b/tests/test_bridge.c
index 35625ca..73705ba 100644
--- a/tests/test_bridge.c
+++ b/tests/test_bridge.c
@@ -19,6 +19,7 @@
 	int rx_count;
 	int tx_count;
 	uint8_t last_pkt_data;
+	uint8_t tx_storage[MCTP_PKTBUF_SIZE(MCTP_BTU)];
 };
 
 struct test_ctx {
@@ -61,6 +62,7 @@
 
 	binding->rx_count++;
 	mctp_bus_rx(&binding->binding, pkt);
+	mctp_pktbuf_free(pkt);
 }
 
 static struct mctp_binding_bridge *mctp_binding_bridge_init(char *name)
@@ -75,6 +77,7 @@
 	binding->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
 	binding->binding.pkt_header = 0;
 	binding->binding.pkt_trailer = 0;
+	binding->binding.tx_storage = binding->tx_storage;
 	return binding;
 }
 
diff --git a/tests/test_cmds.c b/tests/test_cmds.c
index ca5e838..2646b8c 100644
--- a/tests/test_cmds.c
+++ b/tests/test_cmds.c
@@ -50,6 +50,7 @@
 	struct mctp_pktbuf *pkt = mctp_pktbuf_alloc(b, len);
 	memcpy(mctp_pktbuf_hdr(pkt), buf, len);
 	mctp_bus_rx(b, pkt);
+	mctp_pktbuf_free(pkt);
 }
 
 static void setup_test_binding(struct mctp_binding *test_binding,
@@ -59,6 +60,7 @@
 	assert(test_endpoint != NULL);
 	assert(callback_ctx != NULL);
 
+	uint8_t tx_storage[MCTP_PKTBUF_SIZE(MCTP_BTU)];
 	memset(test_binding, 0, sizeof(*test_binding));
 	test_binding->name = "test";
 	test_binding->version = 1;
@@ -68,6 +70,7 @@
 	test_binding->pkt_trailer = 0;
 	test_binding->control_rx = control_message_transport_callback;
 	test_binding->control_rx_data = callback_ctx;
+	test_binding->tx_storage = tx_storage;
 
 	mctp_register_bus(test_endpoint, test_binding, eid_1);
 	mctp_binding_set_tx_enabled(test_binding, true);
diff --git a/tests/test_core.c b/tests/test_core.c
index ead3990..2f5d2c7 100644
--- a/tests/test_core.c
+++ b/tests/test_core.c
@@ -97,11 +97,11 @@
 	rx_pkt->start = 0;
 	rx_pkt->end = MCTP_PACKET_SIZE(len);
 	rx_pkt->mctp_hdr_off = 0;
-	rx_pkt->next = NULL;
 	memcpy(rx_pkt->data, &pktbuf->hdr, sizeof(pktbuf->hdr));
 	memcpy(rx_pkt->data + sizeof(pktbuf->hdr), pktbuf->payload, alloc_size);
 
 	mctp_bus_rx((struct mctp_binding *)binding, rx_pkt);
+	__mctp_free(rx_pkt);
 }
 
 static void receive_one_fragment(struct mctp_binding_test *binding,