Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163279650
D47421.id146814.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D47421.id146814.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D47421: scmi: Redefine max message payload size
Attached
Detach File
Event Timeline
Log In to Comment