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/serial.c b/serial.c
index 77b6bae..d79c99c 100644
--- a/serial.c
+++ b/serial.c
@@ -25,6 +25,8 @@
 
 #define pr_fmt(x) "serial: " x
 
+#define SERIAL_BTU MCTP_BTU
+
 #include "libmctp.h"
 #include "libmctp-alloc.h"
 #include "libmctp-log.h"
@@ -42,6 +44,7 @@
 	/* receive buffer and state */
 	uint8_t rxbuf[1024];
 	struct mctp_pktbuf *rx_pkt;
+	uint8_t rx_storage[MCTP_PKTBUF_SIZE(SERIAL_BTU)];
 	uint8_t rx_exp_len;
 	uint16_t rx_fcs;
 	uint16_t rx_fcs_calc;
@@ -58,6 +61,8 @@
 
 	/* temporary transmit buffer */
 	uint8_t txbuf[256];
+	/* used by the MCTP stack */
+	uint8_t tx_storage[MCTP_PKTBUF_SIZE(SERIAL_BTU)];
 };
 
 #define binding_to_serial(b)                                                   \
@@ -198,10 +203,9 @@
 	serial->rx_pkt = NULL;
 }
 
-static void mctp_serial_start_packet(struct mctp_binding_serial *serial,
-				     uint8_t len)
+static void mctp_serial_start_packet(struct mctp_binding_serial *serial)
 {
-	serial->rx_pkt = mctp_pktbuf_alloc(&serial->binding, len);
+	serial->rx_pkt = mctp_pktbuf_init(&serial->binding, serial->rx_storage);
 }
 
 static void mctp_rx_consume_one(struct mctp_binding_serial *serial, uint8_t c)
@@ -253,7 +257,7 @@
 			mctp_prdebug("invalid size %d", c);
 			serial->rx_state = STATE_WAIT_SYNC_START;
 		} else {
-			mctp_serial_start_packet(serial, 0);
+			mctp_serial_start_packet(serial);
 			pkt = serial->rx_pkt;
 			serial->rx_exp_len = c;
 			serial->rx_state = STATE_DATA;
@@ -404,9 +408,10 @@
 	serial->rx_pkt = NULL;
 	serial->binding.name = "serial";
 	serial->binding.version = 1;
-	serial->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
+	serial->binding.pkt_size = MCTP_PACKET_SIZE(SERIAL_BTU);
 	serial->binding.pkt_header = 0;
 	serial->binding.pkt_trailer = 0;
+	serial->binding.tx_storage = serial->tx_storage;
 
 	serial->binding.start = mctp_serial_core_start;
 	serial->binding.tx = mctp_binding_serial_tx;