mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
firmware: arm_ffa: Fetch the Rx/Tx buffer size using ffa_features()
An endpoint can discover the minimum size, maximum size and alignment boundary for the Rx/Tx buffers by passing the function ID of the FFA_RXTX_MAP ABI as input in the FFA_FEATURES interface. The maximum size is an optional field and a value of 0 means that the partition manager or the hypervisor does not enforce a maximum size. Use the discovery mechanism and remove the hardcoded 4kB buffer size. If the discovery fails, it still defaults to 4kB. Message-Id: <20240820-ffa_v1-2-v2-7-18c0c5f3c65e@arm.com> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
parent
eaca7ef8f3
commit
61824feae5
@ -54,11 +54,8 @@
|
|||||||
#define PACK_TARGET_INFO(s, r) \
|
#define PACK_TARGET_INFO(s, r) \
|
||||||
(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
|
(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
|
||||||
|
|
||||||
/*
|
#define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
|
||||||
* Keeping RX TX buffer size as 4K for now
|
#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
|
||||||
* 64K may be preferred to keep it min a page in 64K PAGE_SIZE config
|
|
||||||
*/
|
|
||||||
#define RXTX_BUFFER_SIZE SZ_4K
|
|
||||||
|
|
||||||
#define FFA_MAX_NOTIFICATIONS 64
|
#define FFA_MAX_NOTIFICATIONS 64
|
||||||
|
|
||||||
@ -99,6 +96,7 @@ struct ffa_drv_info {
|
|||||||
struct mutex tx_lock; /* lock to protect Tx buffer */
|
struct mutex tx_lock; /* lock to protect Tx buffer */
|
||||||
void *rx_buffer;
|
void *rx_buffer;
|
||||||
void *tx_buffer;
|
void *tx_buffer;
|
||||||
|
size_t rxtx_bufsz;
|
||||||
bool mem_ops_native;
|
bool mem_ops_native;
|
||||||
bool msg_direct_req2_supp;
|
bool msg_direct_req2_supp;
|
||||||
bool bitmap_created;
|
bool bitmap_created;
|
||||||
@ -454,7 +452,7 @@ static int ffa_msg_send2(u16 src_id, u16 dst_id, void *buf, size_t sz)
|
|||||||
ffa_value_t ret;
|
ffa_value_t ret;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (sz > (RXTX_BUFFER_SIZE - sizeof(*msg)))
|
if (sz > (drv_info->rxtx_bufsz - sizeof(*msg)))
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
mutex_lock(&drv_info->tx_lock);
|
mutex_lock(&drv_info->tx_lock);
|
||||||
@ -689,9 +687,10 @@ static int ffa_memory_ops(u32 func_id, struct ffa_mem_ops_args *args)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *buffer;
|
void *buffer;
|
||||||
|
size_t rxtx_bufsz = drv_info->rxtx_bufsz;
|
||||||
|
|
||||||
if (!args->use_txbuf) {
|
if (!args->use_txbuf) {
|
||||||
buffer = alloc_pages_exact(RXTX_BUFFER_SIZE, GFP_KERNEL);
|
buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
@ -699,12 +698,12 @@ static int ffa_memory_ops(u32 func_id, struct ffa_mem_ops_args *args)
|
|||||||
mutex_lock(&drv_info->tx_lock);
|
mutex_lock(&drv_info->tx_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ffa_setup_and_transmit(func_id, buffer, RXTX_BUFFER_SIZE, args);
|
ret = ffa_setup_and_transmit(func_id, buffer, rxtx_bufsz, args);
|
||||||
|
|
||||||
if (args->use_txbuf)
|
if (args->use_txbuf)
|
||||||
mutex_unlock(&drv_info->tx_lock);
|
mutex_unlock(&drv_info->tx_lock);
|
||||||
else
|
else
|
||||||
free_pages_exact(buffer, RXTX_BUFFER_SIZE);
|
free_pages_exact(buffer, rxtx_bufsz);
|
||||||
|
|
||||||
return ret < 0 ? ret : 0;
|
return ret < 0 ? ret : 0;
|
||||||
}
|
}
|
||||||
@ -1718,6 +1717,8 @@ cleanup:
|
|||||||
static int __init ffa_init(void)
|
static int __init ffa_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 buf_sz;
|
||||||
|
size_t rxtx_bufsz = SZ_4K;
|
||||||
|
|
||||||
ret = ffa_transport_init(&invoke_ffa_fn);
|
ret = ffa_transport_init(&invoke_ffa_fn);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -1737,13 +1738,24 @@ static int __init ffa_init(void)
|
|||||||
goto free_drv_info;
|
goto free_drv_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv_info->rx_buffer = alloc_pages_exact(RXTX_BUFFER_SIZE, GFP_KERNEL);
|
ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
|
||||||
|
if (!ret) {
|
||||||
|
if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
|
||||||
|
rxtx_bufsz = SZ_64K;
|
||||||
|
else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
|
||||||
|
rxtx_bufsz = SZ_16K;
|
||||||
|
else
|
||||||
|
rxtx_bufsz = SZ_4K;
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_info->rxtx_bufsz = rxtx_bufsz;
|
||||||
|
drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
|
||||||
if (!drv_info->rx_buffer) {
|
if (!drv_info->rx_buffer) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv_info->tx_buffer = alloc_pages_exact(RXTX_BUFFER_SIZE, GFP_KERNEL);
|
drv_info->tx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
|
||||||
if (!drv_info->tx_buffer) {
|
if (!drv_info->tx_buffer) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
@ -1751,7 +1763,7 @@ static int __init ffa_init(void)
|
|||||||
|
|
||||||
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
|
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
|
||||||
virt_to_phys(drv_info->rx_buffer),
|
virt_to_phys(drv_info->rx_buffer),
|
||||||
RXTX_BUFFER_SIZE / FFA_PAGE_SIZE);
|
rxtx_bufsz / FFA_PAGE_SIZE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("failed to register FFA RxTx buffers\n");
|
pr_err("failed to register FFA RxTx buffers\n");
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
@ -1781,8 +1793,8 @@ cleanup_notifs:
|
|||||||
ffa_notifications_cleanup();
|
ffa_notifications_cleanup();
|
||||||
free_pages:
|
free_pages:
|
||||||
if (drv_info->tx_buffer)
|
if (drv_info->tx_buffer)
|
||||||
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
|
free_pages_exact(drv_info->tx_buffer, rxtx_bufsz);
|
||||||
free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE);
|
free_pages_exact(drv_info->rx_buffer, rxtx_bufsz);
|
||||||
free_drv_info:
|
free_drv_info:
|
||||||
kfree(drv_info);
|
kfree(drv_info);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1794,8 +1806,8 @@ static void __exit ffa_exit(void)
|
|||||||
ffa_notifications_cleanup();
|
ffa_notifications_cleanup();
|
||||||
ffa_partitions_cleanup();
|
ffa_partitions_cleanup();
|
||||||
ffa_rxtx_unmap(drv_info->vm_id);
|
ffa_rxtx_unmap(drv_info->vm_id);
|
||||||
free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
|
free_pages_exact(drv_info->tx_buffer, drv_info->rxtx_bufsz);
|
||||||
free_pages_exact(drv_info->rx_buffer, RXTX_BUFFER_SIZE);
|
free_pages_exact(drv_info->rx_buffer, drv_info->rxtx_bufsz);
|
||||||
kfree(drv_info);
|
kfree(drv_info);
|
||||||
}
|
}
|
||||||
module_exit(ffa_exit);
|
module_exit(ffa_exit);
|
||||||
|
Loading…
Reference in New Issue
Block a user