Commit 67ce2658 authored by Federico Vaga's avatar Federico Vaga

sw: remove driver filter mechanism

It is unused and useless. People who wants to filter they want to filter
on their payload and the generic mechanism offerd by mock turtle is over
complicated for the task that is supposed to achieve.

People can implement filtering in userspace easily.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 3388e161
......@@ -207,17 +207,12 @@ The Mock Turtle driver exports a *char device* for each Mock Turtle HMQ.
All HMQ instances will appear as child of a :ref:`sw:drv:core`; in
*/dev/mockturtle/* you will have devices named ``trtl-%04x-%02d-%02d``
(trtl-<device-id>-<cpu-index>-<hmq-index>). The main purpose of this
interface is to exchange messages and configure filters. These devices
are bidirectional, so you can: ``write(2)`` to send messaged;
``read(2)`` to receive messages; ``poll(2)`` or ``select(2)`` to wait
for the interface to become accessible.
interface is to exchange messages. These devices are bidirectional,
so you can: ``write(2)`` to send messaged; ``read(2)`` to receive messages;
``poll(2)`` or ``select(2)`` to wait for the interface to become accessible.
This *char device* provides a set of ``ioctl(2)`` commands:
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_ADD
.. doxygendefine:: TRTL_IOCTL_MSG_FILTER_CLEAN
.. doxygendefine:: TRTL_IOCTL_HMQ_SYNC_SET
.. doxygendefine:: TRTL_IOCTL_MSG_SYNC_ABORT
......
......@@ -153,21 +153,6 @@ side so that the complete flush happens synchronously.
.. doxygenfunction:: trtl_hmq_flush
The Mock Turtle driver has a basic message filtering mechanism. Each
user can add a set of filters on any host message queue. Mock Turtle
will deliver to the user only those messages which pass the filter.
Rembember that this is a user filter, this means that on the same
host message queue, different users can have different filters.
.. doxygenfunction:: trtl_hmq_filter_add
.. doxygenfunction:: trtl_hmq_filter_clean
.. doxygenenum:: trtl_msg_filter_operation_type
.. doxygenstruct:: trtl_msg_filter
:members:
Then, there are the functions to exchange messages with firmware
running on Mock Turtle. This API offers a minimum set of function
to allow users to send/receive synchronous/asynchronous messages.
......
......@@ -179,35 +179,6 @@ enum trtl_smem_modifier {
TRTL_SMEM_TYPE_TST_SET, /**< atomic test and set */
};
/**
* @enum trtl_msg_filter_operation_type
* List of available filter's operations
*/
enum trtl_msg_filter_operation_type {
TRTL_MSG_FILTER_AND,
TRTL_MSG_FILTER_OR,
TRTL_MSG_FILTER_EQ,
TRTL_MSG_FILTER_NEQ,
__TRTL_MSG_FILTER_MAX,
};
#define TRTL_MSG_FILTER_FLAG_HEADER (0)
#define TRTL_MSG_FILTER_FLAG_PAYLOAD (1 << 0)
/**
* It describe a filter to apply to messages
*/
struct trtl_msg_filter {
unsigned long flags; /**< options for the filter */
uint32_t operation; /**< kind of operation to perform */
uint32_t word_offset; /**< offset of the word to check */
uint32_t mask; /**< mask to apply before the operation */
uint32_t value; /**< second operand of the operation */
};
/**
* Descriptor of the IO operation on Shared Memory
*/
......@@ -225,8 +196,6 @@ struct trtl_smem_io {
*/
enum trtl_ioctl_commands {
TRTL_SMEM_IO, /**< access to shared memory */
TRTL_MSG_FILTER_ADD, /**< add a message filter */
TRTL_MSG_FILTER_CLEAN, /**< remove all filters */
TRTL_MSG_SYNC_ABORT, /**< abort sync message*/
TRTL_HMQ_SYNC_SET, /**< Mark HMQ user context as synchronous */
};
......@@ -237,27 +206,15 @@ enum trtl_ioctl_commands {
struct trtl_smem_io)
/**
* The IOCTL command to add a filter to an HMQ
*/
#define TRTL_IOCTL_MSG_FILTER_ADD _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_FILTER_ADD, \
struct trtl_msg_filter)
/**
* The IOCTL command to remove all filters from an HMQ
*/
#define TRTL_IOCTL_MSG_FILTER_CLEAN _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_FILTER_CLEAN, \
struct trtl_msg_filter)
/**
* The IOCTL command to add a filter to an HMQ
* The IOCTL command to set HMQ user context to SYNC
*/
#define TRTL_IOCTL_HMQ_SYNC_SET _IOW(TRTL_IOCTL_MAGIC, \
TRTL_HMQ_SYNC_SET, \
unsigned int)
/**
* The IOCTL command to add a filter to an HMQ
* The IOCTL command to abort a sync message. Usefull when the answer is
* not coming
*/
#define TRTL_IOCTL_MSG_SYNC_ABORT _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_SYNC_ABORT, \
......
......@@ -75,11 +75,6 @@ static inline uint32_t trtl_get_sequence(struct trtl_msg *msg)
return msg->data[1];
}
struct trtl_msg_filter_element {
struct trtl_msg_filter filter;
struct list_head list;
};
struct trtl_memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
......@@ -192,9 +187,7 @@ struct trtl_hmq {
* It describes the consumer of the output slot
* @list: to keep it in our local queue
* @hmq: reference to opened HMQ
* @lock: to protect filters, flags, wait_id
* @list_filters: list of filters to apply
* @n_filters: number of filters
* @lock: to protect flags, wait_id
* @idx_r: index read pointer for the message circular buffer. This is
* protected by the input buffer lock. Accessing this field means that
* you are accessing the buffer input, and in order to do that you need
......@@ -206,8 +199,6 @@ struct trtl_hmq_user {
struct trtl_hmq *hmq;
spinlock_t lock;
unsigned long flags;
struct list_head list_filters;
unsigned int n_filters;
unsigned int idx_r;
uint16_t wait_id;
};
......
......@@ -375,59 +375,6 @@ static void trtl_hmq_flush(struct trtl_hmq *hmq)
mutex_unlock(&hmq->mtx);
}
/**
* It applies filters on a given message.
* @user HMQ user instance from which we take filters
* @msg the message to filter
*
* Return: 1 if the message passes all filters, otherwise 0
*/
static int trtl_hmq_filter_check(struct trtl_hmq_user *user,
struct trtl_msg *msg)
{
struct trtl_msg_filter_element *fltel, *tmp;
unsigned int passed = 1;
uint32_t word, *data = msg->data, *head = (uint32_t *)&msg->hdr;
unsigned long flags;
spin_lock_irqsave(&user->lock, flags);
list_for_each_entry_safe(fltel, tmp, &user->list_filters, list) {
/* If one of the previous filter failed, then stop */
if (!passed)
break;
if (fltel->filter.flags & TRTL_MSG_FILTER_FLAG_PAYLOAD)
word = data[fltel->filter.word_offset];
else
word = head[fltel->filter.word_offset];
switch (fltel->filter.operation) {
case TRTL_MSG_FILTER_AND:
word &= fltel->filter.mask;
if (word != fltel->filter.value)
passed = 0;
break;
case TRTL_MSG_FILTER_OR:
word |= fltel->filter.mask;
if (word != fltel->filter.value)
passed = 0;
break;
case TRTL_MSG_FILTER_EQ:
if (word != fltel->filter.value)
passed = 0;
break;
case TRTL_MSG_FILTER_NEQ:
if (word == fltel->filter.value)
passed = 0;
break;
}
}
spin_unlock_irqrestore(&user->lock, flags);
return passed;
}
/**
* Tell if user accepts the given message
* @user: HMQ user
......@@ -439,15 +386,12 @@ static bool trtl_hmq_user_filter_one(struct trtl_hmq_user *user,
struct trtl_msg *msg)
{
if (trtl_hmq_user_is_sync(user)) {
if (trtl_hmq_user_is_waiting(user) &&
return trtl_hmq_user_is_waiting(user) &&
trtl_msg_is_ack(msg) &&
trtl_hmq_user_msg_is_answer(user, msg))
return true;
} else {
if (trtl_hmq_filter_check(user, msg))
return true;
trtl_hmq_user_msg_is_answer(user, msg);
}
return false;
return true;
}
/**
......@@ -618,7 +562,6 @@ static int trtl_hmq_open(struct inode *inode, struct file *file)
user->hmq = hmq;
spin_lock_init(&user->lock);
INIT_LIST_HEAD(&user->list_filters);
/* Add new user to the list */
spin_lock_irqsave(&hmq->lock, flags);
......@@ -767,86 +710,6 @@ static ssize_t trtl_hmq_write(struct file *f, const char __user *buf,
return count ? count : err;
}
/**
* Add a filter rule to a given file-descriptor
*/
static int trtl_ioctl_msg_filter_add(struct trtl_hmq_user *user,
void __user *uarg)
{
struct trtl_msg_filter_element *fltel;
uint32_t size;
int err = 0;
unsigned long flags;
fltel = kmalloc(sizeof(struct trtl_msg_filter_element), GFP_KERNEL);
if (!fltel)
return -ENOMEM;
/* Copy the message from user space*/
err = copy_from_user(&fltel->filter, uarg,
sizeof(struct trtl_msg_filter));
if (err)
goto err;
/* validate filter */
if (fltel->filter.operation >= __TRTL_MSG_FILTER_MAX) {
err = -EINVAL;
goto err;
}
size = TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD(user->hmq->cfg->sizes);
if ((fltel->filter.flags & TRTL_MSG_FILTER_FLAG_PAYLOAD) &&
fltel->filter.word_offset >= size) {
dev_err(&user->hmq->dev,
"Invalid filter: word offset %d greater than maximum payload size %d\n",
fltel->filter.word_offset, size);
err = -EINVAL;
goto err;
}
size = TRTL_CONFIG_ROM_MQ_SIZE_HEADER(user->hmq->cfg->sizes);
if (!(fltel->filter.flags & TRTL_MSG_FILTER_FLAG_PAYLOAD) &&
fltel->filter.word_offset >= size) {
dev_err(&user->hmq->dev,
"Invalid filter: word offset %d greater than maximum header size %d\n",
fltel->filter.word_offset, size);
err = -EINVAL;
goto err;
}
/* Store filter */
spin_lock_irqsave(&user->lock, flags);
list_add_tail(&fltel->list, &user->list_filters);
user->n_filters++;
spin_unlock_irqrestore(&user->lock, flags);
return 0;
err:
kfree(fltel);
return err;
}
/**
* FIXME: to be tested
* Remove all filter rules form a given file-descriptor
*/
static void trtl_ioctl_msg_filter_clean(struct trtl_hmq_user *user,
void __user *uarg)
{
struct trtl_msg_filter_element *fltel, *tmp;
unsigned long flags;
spin_lock_irqsave(&user->lock, flags);
list_for_each_entry_safe(fltel, tmp, &user->list_filters, list) {
list_del(&fltel->list);
kfree(fltel);
user->n_filters--;
}
spin_unlock_irqrestore(&user->lock, flags);
}
/**
* Set of special operations that can be done on the HMQ
*/
......@@ -871,12 +734,6 @@ static long trtl_hmq_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
/* Perform commands */
mutex_lock(&user->hmq->mtx);
switch (cmd) {
case TRTL_IOCTL_MSG_FILTER_ADD:
err = trtl_ioctl_msg_filter_add(user, uarg);
break;
case TRTL_MSG_FILTER_CLEAN:
trtl_ioctl_msg_filter_clean(user, uarg);
break;
case TRTL_IOCTL_MSG_SYNC_ABORT:
if (trtl_hmq_user_is_sync(user)) {
if (trtl_hmq_user_is_waiting(user))
......
......@@ -310,15 +310,6 @@ class TrtlDevice(object):
self.libtrtl.trtl_fw_variable_set.restype = c_int
self.libtrtl.trtl_fw_variable_set.errcheck = self.__errcheck_int
# self.libtrtl.trtl_hmq_filter_add.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_clean.argtypes = [c_void_p]
# # Return
# self.libtrtl.trtl_hmq_filter_add.restype = c_int
# self.libtrtl.trtl_hmq_filter_clean.restype = c_int
# # Error
# self.libtrtl.trtl_hmq_filter_add.errcheck = self.__errcheck_int
# self.libtrtl.trtl_hmq_filter_clean.errcheck = self.__errcheck_int
def __errcheck_pointer(self, ret, func, args):
"""Generic error handler for functions returning pointers"""
if ret is None:
......
......@@ -818,40 +818,6 @@ int trtl_cpu_is_enable(struct trtl_dev *trtl, unsigned int index,
}
/**
* It adds a new filter to the given hmq descriptor
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
* @param[in] filter filter to add
* @return 0 on success, -1 otherwise and errno is set appropriately
*/
int trtl_hmq_filter_add(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq,
struct trtl_msg_filter *filter)
{
return ioctl(trtl_hmq_fd(trtl, idx_cpu, idx_hmq),
TRTL_IOCTL_MSG_FILTER_ADD, filter);
}
/**
* It removes all filters from the given hmq descriptor
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
* @return 0 on success, -1 otherwise and errno is set appropriately
*/
int trtl_hmq_filter_clean(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq)
{
return ioctl(trtl_hmq_fd(trtl, idx_cpu, idx_hmq),
TRTL_IOCTL_MSG_FILTER_CLEAN, NULL);
}
/**
* It returns the device name
* @param[in] trtl device token
......
......@@ -151,13 +151,6 @@ static inline int trtl_cpu_restart(struct trtl_dev *trtl, unsigned int index)
* @{
*/
extern int trtl_hmq_filter_add(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq,
struct trtl_msg_filter *filter);
extern int trtl_hmq_filter_clean(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq);
extern int trtl_hmq_fd(struct trtl_dev *trtl,
unsigned int idx_cpu,
unsigned int idx_hmq);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment