API: add mctp_set_tx_enabled
Provide a method for MCTP bindings to implement flow control
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
diff --git a/core.c b/core.c
index 71b54ce..d36248d 100644
--- a/core.c
+++ b/core.c
@@ -20,6 +20,7 @@
struct mctp_bus {
mctp_eid_t eid;
struct mctp_binding *binding;
+ bool tx_enabled;
/* todo: routing */
};
@@ -322,13 +323,48 @@
static int mctp_packet_tx(struct mctp_bus *bus,
struct mctp_pktbuf *pkt)
{
+ if (!bus->tx_enabled)
+ return -1;
+
+ mctp_prdebug("sending pkt, len %d",
+ mctp_pktbuf_size(pkt));
+
return bus->binding->tx(bus->binding, pkt);
}
+static void mctp_send_tx_queue(struct mctp *mctp,
+ struct mctp_bus *bus)
+{
+ struct mctp_pktbuf *pkt;
+
+ while ((pkt = mctp->tx_queue_head)) {
+ int rc;
+
+ rc = mctp_packet_tx(bus, pkt);
+ if (rc)
+ break;
+
+ mctp->tx_queue_head = pkt->next;
+ mctp_pktbuf_free(pkt);
+ }
+
+ if (!mctp->tx_queue_head)
+ mctp->tx_queue_tail = NULL;
+
+}
+
+void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable)
+{
+ struct mctp_bus *bus = binding->bus;
+ bus->tx_enabled = enable;
+ if (enable)
+ mctp_send_tx_queue(binding->mctp, bus);
+}
+
int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid,
void *msg, size_t msg_len)
{
- struct mctp_pktbuf *pkt, *tmp;
+ struct mctp_pktbuf *pkt;
struct mctp_hdr *hdr;
struct mctp_bus *bus;
size_t pkt_len, p;
@@ -366,18 +402,7 @@
p += pkt_len;
}
- /* send queued packets */
- for (pkt = mctp->tx_queue_head; pkt;) {
- mctp_prdebug("sending pkt, len %d",
- mctp_pktbuf_size(pkt));
- mctp_packet_tx(bus, pkt);
- tmp = pkt->next;
- mctp_pktbuf_free(pkt);
- pkt = tmp;
- }
-
- mctp->tx_queue_tail = NULL;
- mctp->tx_queue_head = NULL;
+ mctp_send_tx_queue(mctp, bus);
return 0;
}
diff --git a/libmctp.h b/libmctp.h
index 291b639..8a66ef8 100644
--- a/libmctp.h
+++ b/libmctp.h
@@ -3,6 +3,7 @@
#ifndef _LIBMCTP_H
#define _LIBMCTP_H
+#include <stdbool.h>
#include <stdint.h>
typedef uint8_t mctp_eid_t;
@@ -87,6 +88,8 @@
struct mctp_pktbuf *pkt);
};
+void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable);
+
void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt);
/* environment-specific allocation */
diff --git a/serial.c b/serial.c
index 2fa3abe..22c1b4b 100644
--- a/serial.c
+++ b/serial.c
@@ -288,6 +288,7 @@
{
assert(serial->fd >= 0);
mctp_register_bus(mctp, &serial->binding, eid);
+ mctp_binding_set_tx_enabled(&serial->binding, true);
}
struct mctp_binding_serial *mctp_serial_init(void)