Page MenuHomeFreeBSD

D47421.id146814.diff
No OneTemporary

D47421.id146814.diff

diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h
--- a/sys/dev/firmware/arm/scmi.h
+++ b/sys/dev/firmware/arm/scmi.h
@@ -34,10 +34,21 @@
#include "scmi_if.h"
-#define SCMI_MAX_MSG 32
-#define SCMI_MAX_MSG_PAYLD_SIZE 128
-#define SCMI_MAX_MSG_REPLY_SIZE (SCMI_MAX_MSG_PAYLD_SIZE - sizeof(uint32_t))
-#define SCMI_MAX_MSG_SIZE (SCMI_MAX_MSG_PAYLD_SIZE + sizeof(uint32_t))
+#define SCMI_DEF_MAX_MSG 32
+#define SCMI_DEF_MAX_MSG_PAYLD_SIZE 128
+#define SCMI_DEF_MAX_RX_TIMEOUT_MS 30
+
+#define SCMI_MAX_MSG(sc) ((sc)->trs_desc.max_msg)
+#define SCMI_MAX_MSG_TIMEOUT_MS(sc) ((sc)->trs_desc.reply_timo_ms)
+
+/* Payload including status, excluding header*/
+#define SCMI_MAX_MSG_PAYLD_SIZE(sc) ((sc)->trs_desc.max_payld_sz)
+
+/* Payload size minus status field */
+#define SCMI_MAX_MSG_REPLY_SIZE(sc) (SCMI_MAX_MSG_PAYLD_SIZE((sc)) - sizeof(uint32_t))
+
+/* Payload size plus header field */
+#define SCMI_MAX_MSG_SIZE(sc) (SCMI_MAX_MSG_PAYLD_SIZE(sc) + sizeof(uint32_t))
enum scmi_chan {
SCMI_CHAN_A2P,
@@ -47,6 +58,8 @@
struct scmi_transport_desc {
bool no_completion_irq;
+ unsigned int max_msg;
+ unsigned int max_payld_sz;
unsigned int reply_timo_ms;
};
diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -127,6 +127,8 @@
struct mtx mtx;
};
+static int scmi_transport_configure(device_t,
+ struct scmi_transport_desc *);
static int scmi_transport_init(struct scmi_softc *);
static void scmi_transport_cleanup(struct scmi_softc *);
static struct scmi_reqs_pool *scmi_reqs_pool_allocate(const int, const int);
@@ -169,8 +171,8 @@
if (error != 0)
return (error);
- device_printf(dev, "Transport reply timeout initialized to %dms\n",
- sc->trs_desc.reply_timo_ms);
+ device_printf(dev, "Transport - max_msg:%d max_payld_sz:%u reply_timo_ms:%d\n",
+ SCMI_MAX_MSG(sc), SCMI_MAX_MSG_PAYLD_SIZE(sc), SCMI_MAX_MSG_TIMEOUT_MS(sc));
/*
* Allow devices to identify.
@@ -248,36 +250,54 @@
free(rp, M_DEVBUF);
}
+static int
+scmi_transport_configure(device_t dev, struct scmi_transport_desc *tdesc)
+{
+ /* Initialize to default values at first ... */
+ tdesc->max_msg = SCMI_DEF_MAX_MSG;
+ tdesc->max_payld_sz = SCMI_DEF_MAX_MSG_PAYLD_SIZE;
+ tdesc->reply_timo_ms = SCMI_DEF_MAX_RX_TIMEOUT_MS;
+
+ /* ... check against per-transport needs */
+ return SCMI_TRANSPORT_CONFIGURE(dev);
+}
+
static int
scmi_transport_init(struct scmi_softc *sc)
{
+ struct scmi_transport_desc *tdesc = &sc->trs_desc;
struct scmi_transport *trs;
int ret;
trs = malloc(sizeof(*trs), M_DEVBUF, M_ZERO | M_WAITOK);
+ sc->trs = trs;
+
+ ret = scmi_transport_configure(sc->dev, tdesc);
+ if (ret != 0) {
+ free(trs, M_DEVBUF);
+ return (ret);
+ }
BIT_FILL(SCMI_MAX_TOKEN, &trs->avail_tokens);
mtx_init(&trs->mtx, "tokens", "SCMI", MTX_SPIN);
- trs->inflight_ht = hashinit(SCMI_MAX_MSG, M_DEVBUF,
- &trs->inflight_mask);
+ trs->inflight_ht = hashinit(tdesc->max_msg, M_DEVBUF, &trs->inflight_mask);
trs->chans[SCMI_CHAN_A2P] =
- scmi_reqs_pool_allocate(SCMI_MAX_MSG, SCMI_MAX_MSG_PAYLD_SIZE);
+ scmi_reqs_pool_allocate(tdesc->max_msg, tdesc->max_payld_sz);
if (trs->chans[SCMI_CHAN_A2P] == NULL) {
free(trs, M_DEVBUF);
return (ENOMEM);
}
trs->chans[SCMI_CHAN_P2A] =
- scmi_reqs_pool_allocate(SCMI_MAX_MSG, SCMI_MAX_MSG_PAYLD_SIZE);
+ scmi_reqs_pool_allocate(tdesc->max_msg, tdesc->max_payld_sz);
if (trs->chans[SCMI_CHAN_P2A] == NULL) {
scmi_reqs_pool_free(trs->chans[SCMI_CHAN_A2P]);
free(trs, M_DEVBUF);
return (ENOMEM);
}
- sc->trs = trs;
ret = SCMI_TRANSPORT_INIT(sc->dev);
if (ret != 0) {
scmi_reqs_pool_free(trs->chans[SCMI_CHAN_A2P]);
@@ -355,7 +375,7 @@
{
mtx_lock_spin(&req->mtx);
if (!refcount_release_if_not_last(&req->cnt)) {
- bzero(&req->msg, sizeof(req->msg) + SCMI_MAX_MSG_PAYLD_SIZE);
+ bzero(&req->msg, sizeof(req->msg) + SCMI_MAX_MSG_PAYLD_SIZE(sc));
scmi_req_free_unlocked(sc, SCMI_CHAN_A2P, req);
}
mtx_unlock_spin(&req->mtx);
@@ -532,13 +552,13 @@
static int
scmi_wait_for_response(struct scmi_softc *sc, struct scmi_req *req, void **out)
{
+ unsigned int reply_timo_ms = SCMI_MAX_MSG_TIMEOUT_MS(sc);
int ret;
if (req->msg.polling) {
bool needs_drop;
- ret = SCMI_POLL_MSG(sc->dev, &req->msg,
- sc->trs_desc.reply_timo_ms);
+ ret = SCMI_POLL_MSG(sc->dev, &req->msg, reply_timo_ms);
/*
* Drop reference to successfully polled req unless it had
* already also been processed on the IRQ path.
@@ -557,8 +577,7 @@
le32toh(req->msg.hdr), le32toh(req->header));
}
} else {
- ret = tsleep(req, 0, "scmi_wait4",
- (sc->trs_desc.reply_timo_ms * hz) / 1000);
+ ret = tsleep(req, 0, "scmi_wait4", (reply_timo_ms * hz) / 1000);
/* Check for lost wakeups since there is no associated lock */
mtx_lock_spin(&req->mtx);
if (ret != 0 && req->done)
@@ -591,8 +610,8 @@
sc = device_get_softc(dev);
- if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE ||
- rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE) {
+ if (tx_payld_sz > SCMI_MAX_MSG_PAYLD_SIZE(sc) ||
+ rx_payld_sz > SCMI_MAX_MSG_REPLY_SIZE(sc)) {
device_printf(dev, "Unsupported payload size. Drop.\n");
return (NULL);
}
@@ -606,7 +625,7 @@
req->message_id = message_id & SCMI_HDR_MESSAGE_ID_BF;
req->msg.tx_len = sizeof(req->msg.hdr) + tx_payld_sz;
req->msg.rx_len = rx_payld_sz ?
- rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE;
+ rx_payld_sz + 2 * sizeof(uint32_t) : SCMI_MAX_MSG_SIZE(sc);
return (&req->msg.payld[0]);
}
diff --git a/sys/dev/firmware/arm/scmi_if.m b/sys/dev/firmware/arm/scmi_if.m
--- a/sys/dev/firmware/arm/scmi_if.m
+++ b/sys/dev/firmware/arm/scmi_if.m
@@ -31,6 +31,10 @@
struct scmi_msg;
};
+METHOD int transport_configure {
+ device_t dev;
+};
+
METHOD int transport_init {
device_t dev;
};
diff --git a/sys/dev/firmware/arm/scmi_mailbox.c b/sys/dev/firmware/arm/scmi_mailbox.c
--- a/sys/dev/firmware/arm/scmi_mailbox.c
+++ b/sys/dev/firmware/arm/scmi_mailbox.c
@@ -56,6 +56,7 @@
struct arm_doorbell *db;
};
+static int scmi_mailbox_transport_configure(device_t);
static int scmi_mailbox_transport_init(device_t);
static void scmi_mailbox_transport_cleanup(device_t);
static int scmi_mailbox_xfer_msg(device_t, struct scmi_msg *);
@@ -80,6 +81,24 @@
scmi_rx_irq_callback(sc->base.dev, sc->a2p_dev, msg_header, rx_len);
}
+static int
+scmi_mailbox_transport_configure(device_t dev)
+{
+ struct scmi_mailbox_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->base.trs_desc.max_payld_sz <= SCMI_SHMEM_TRANSPORT_LAYOUT_HDR_SZ) {
+ device_printf(dev,
+ "Failed to configure transport: max_payld_sz not big enough !\n");
+ return (EINVAL);
+ }
+
+ sc->base.trs_desc.max_payld_sz -= SCMI_SHMEM_TRANSPORT_LAYOUT_HDR_SZ;
+
+ return (0);
+}
+
static int
scmi_mailbox_transport_init(device_t dev)
{
@@ -109,8 +128,6 @@
return (ENXIO);
}
- sc->base.trs_desc.reply_timo_ms = 30;
-
arm_doorbell_set_handler(sc->db, scmi_mailbox_a2p_callback, sc);
return (0);
@@ -211,6 +228,7 @@
DEVMETHOD(device_probe, scmi_mailbox_probe),
/* SCMI interface */
+ DEVMETHOD(scmi_transport_configure, scmi_mailbox_transport_configure),
DEVMETHOD(scmi_transport_init, scmi_mailbox_transport_init),
DEVMETHOD(scmi_transport_cleanup, scmi_mailbox_transport_cleanup),
DEVMETHOD(scmi_xfer_msg, scmi_mailbox_xfer_msg),
diff --git a/sys/dev/firmware/arm/scmi_shmem.h b/sys/dev/firmware/arm/scmi_shmem.h
--- a/sys/dev/firmware/arm/scmi_shmem.h
+++ b/sys/dev/firmware/arm/scmi_shmem.h
@@ -46,6 +46,8 @@
uint8_t msg_payload[0];
};
+#define SCMI_SHMEM_TRANSPORT_LAYOUT_HDR_SZ 24
+
#define SMT_SIZE_HEADER sizeof(struct scmi_smt_header)
#define SMT_OFFSET_CHAN_STATUS \
diff --git a/sys/dev/firmware/arm/scmi_smc.c b/sys/dev/firmware/arm/scmi_smc.c
--- a/sys/dev/firmware/arm/scmi_smc.c
+++ b/sys/dev/firmware/arm/scmi_smc.c
@@ -54,6 +54,7 @@
device_t a2p_dev;
};
+static int scmi_smc_transport_configure(device_t);
static int scmi_smc_transport_init(device_t);
static int scmi_smc_xfer_msg(device_t, struct scmi_msg *);
static int scmi_smc_poll_msg(device_t, struct scmi_msg *, unsigned int);
@@ -62,6 +63,17 @@
static int scmi_smc_probe(device_t);
+static int
+scmi_smc_transport_configure(device_t dev)
+{
+ struct scmi_smc_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->base.trs_desc.no_completion_irq = true;
+
+ return (0);
+}
+
static int
scmi_smc_transport_init(device_t dev)
{
@@ -87,9 +99,6 @@
return (ENXIO);
}
- sc->base.trs_desc.no_completion_irq = true;
- sc->base.trs_desc.reply_timo_ms = 30;
-
return (0);
}
@@ -169,6 +178,7 @@
DEVMETHOD(device_probe, scmi_smc_probe),
/* SCMI interface */
+ DEVMETHOD(scmi_transport_configure, scmi_smc_transport_configure),
DEVMETHOD(scmi_transport_init, scmi_smc_transport_init),
DEVMETHOD(scmi_xfer_msg, scmi_smc_xfer_msg),
DEVMETHOD(scmi_poll_msg, scmi_smc_poll_msg),
diff --git a/sys/dev/firmware/arm/scmi_virtio.c b/sys/dev/firmware/arm/scmi_virtio.c
--- a/sys/dev/firmware/arm/scmi_virtio.c
+++ b/sys/dev/firmware/arm/scmi_virtio.c
@@ -54,6 +54,7 @@
static void scmi_virtio_callback(void *, unsigned int, void *);
static void *scmi_virtio_p2a_pool_init(device_t, unsigned int);
+static int scmi_virtio_transport_configure(device_t);
static int scmi_virtio_transport_init(device_t);
static void scmi_virtio_transport_cleanup(device_t);
static int scmi_virtio_xfer_msg(device_t, struct scmi_msg *);
@@ -83,19 +84,19 @@
scmi_virtio_p2a_pool_init(device_t dev, unsigned int max_msg)
{
struct scmi_virtio_softc *sc;
+ unsigned int max_msg_sz;
void *pool;
uint8_t *buf;
int i;
sc = device_get_softc(dev);
+ max_msg_sz = SCMI_MAX_MSG_SIZE(&sc->base);
+ pool = mallocarray(max_msg, max_msg_sz, M_DEVBUF, M_ZERO | M_WAITOK);
- pool = mallocarray(max_msg, SCMI_MAX_MSG_SIZE, M_DEVBUF,
- M_ZERO | M_WAITOK);
-
- for (i = 0, buf = pool; i < max_msg; i++, buf += SCMI_MAX_MSG_SIZE) {
+ for (i = 0, buf = pool; i < max_msg; i++, buf += max_msg_sz) {
/* Feed platform with pre-allocated P2A buffers */
virtio_scmi_message_enqueue(sc->virtio_dev,
- VIRTIO_SCMI_CHAN_P2A, buf, 0, SCMI_MAX_MSG_SIZE);
+ VIRTIO_SCMI_CHAN_P2A, buf, 0, max_msg_sz);
}
device_printf(dev,
@@ -111,7 +112,18 @@
sc = device_get_softc(dev);
virtio_scmi_message_enqueue(sc->virtio_dev, VIRTIO_SCMI_CHAN_P2A,
- msg, 0, SCMI_MAX_MSG_SIZE);
+ msg, 0, SCMI_MAX_MSG_SIZE(&sc->base));
+}
+
+static int
+scmi_virtio_transport_configure(device_t dev)
+{
+ struct scmi_virtio_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->base.trs_desc.reply_timo_ms = 100;
+
+ return (0);
}
static int
@@ -169,8 +181,6 @@
}
}
- sc->base.trs_desc.reply_timo_ms = 100;
-
return (0);
}
@@ -280,6 +290,7 @@
DEVMETHOD(device_attach, scmi_virtio_attach),
/* SCMI interface */
+ DEVMETHOD(scmi_transport_configure, scmi_virtio_transport_configure),
DEVMETHOD(scmi_transport_init, scmi_virtio_transport_init),
DEVMETHOD(scmi_transport_cleanup, scmi_virtio_transport_cleanup),
DEVMETHOD(scmi_xfer_msg, scmi_virtio_xfer_msg),

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 4:48 PM (6 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35372717
Default Alt Text
D47421.id146814.diff (10 KB)

Event Timeline