drivers: can: mcan: do not iterate all filter elements to find free one
There is no need for iterating all the Bosch M_CAN filter elements in Message RAM in order to find a free filter as the driver already keeps track of assigned filters. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
0f36f1a3ee
commit
5f67426b93
1 changed files with 26 additions and 56 deletions
|
@ -944,31 +944,6 @@ unlock:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_mcan_get_free_std(const struct device *dev)
|
|
||||||
{
|
|
||||||
const struct can_mcan_config *config = dev->config;
|
|
||||||
const struct can_mcan_callbacks *cbs = config->callbacks;
|
|
||||||
struct can_mcan_std_filter filter;
|
|
||||||
int err;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < cbs->num_std; ++i) {
|
|
||||||
err = can_mcan_read_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
|
||||||
i * sizeof(struct can_mcan_std_filter), &filter,
|
|
||||||
sizeof(struct can_mcan_std_filter));
|
|
||||||
if (err != 0) {
|
|
||||||
LOG_ERR("failed to read std filter (err %d)", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.sfce == CAN_MCAN_FCE_DISABLE) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *config = dev->config;
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
@ -997,13 +972,20 @@ int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callb
|
||||||
.id2 = filter->mask,
|
.id2 = filter->mask,
|
||||||
.sft = CAN_MCAN_SFT_MASKED
|
.sft = CAN_MCAN_SFT_MASKED
|
||||||
};
|
};
|
||||||
int filter_id;
|
int filter_id = -ENOSPC;
|
||||||
int err;
|
int err;
|
||||||
|
int i;
|
||||||
|
|
||||||
k_mutex_lock(&data->lock, K_FOREVER);
|
k_mutex_lock(&data->lock, K_FOREVER);
|
||||||
filter_id = can_mcan_get_free_std(dev);
|
|
||||||
|
|
||||||
if (filter_id < 0) {
|
for (i = 0; i < cbs->num_std; i++) {
|
||||||
|
if (cbs->std[i].function == NULL) {
|
||||||
|
filter_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_id == -ENOSPC) {
|
||||||
LOG_WRN("No free standard id filter left");
|
LOG_WRN("No free standard id filter left");
|
||||||
k_mutex_unlock(&data->lock);
|
k_mutex_unlock(&data->lock);
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
@ -1032,31 +1014,6 @@ int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callb
|
||||||
return filter_id;
|
return filter_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_mcan_get_free_ext(const struct device *dev)
|
|
||||||
{
|
|
||||||
const struct can_mcan_config *config = dev->config;
|
|
||||||
const struct can_mcan_callbacks *cbs = config->callbacks;
|
|
||||||
struct can_mcan_ext_filter filter;
|
|
||||||
int err;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < cbs->num_ext; ++i) {
|
|
||||||
err = can_mcan_read_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
|
||||||
i * sizeof(struct can_mcan_ext_filter), &filter,
|
|
||||||
sizeof(struct can_mcan_ext_filter));
|
|
||||||
if (err != 0) {
|
|
||||||
LOG_ERR("failed to read ext filter (err %d)", err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.efce == CAN_MCAN_FCE_DISABLE) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_t callback,
|
static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_t callback,
|
||||||
void *user_data, const struct can_filter *filter)
|
void *user_data, const struct can_filter *filter)
|
||||||
{
|
{
|
||||||
|
@ -1068,13 +1025,20 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_
|
||||||
.id1 = filter->id,
|
.id1 = filter->id,
|
||||||
.eft = CAN_MCAN_EFT_MASKED
|
.eft = CAN_MCAN_EFT_MASKED
|
||||||
};
|
};
|
||||||
int filter_id;
|
int filter_id = -ENOSPC;
|
||||||
int err;
|
int err;
|
||||||
|
int i;
|
||||||
|
|
||||||
k_mutex_lock(&data->lock, K_FOREVER);
|
k_mutex_lock(&data->lock, K_FOREVER);
|
||||||
filter_id = can_mcan_get_free_ext(dev);
|
|
||||||
|
|
||||||
if (filter_id < 0) {
|
for (i = 0; i < cbs->num_ext; i++) {
|
||||||
|
if (cbs->ext[i].function == NULL) {
|
||||||
|
filter_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_id == -ENOSPC) {
|
||||||
LOG_WRN("No free extended id filter left");
|
LOG_WRN("No free extended id filter left");
|
||||||
k_mutex_unlock(&data->lock);
|
k_mutex_unlock(&data->lock);
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
@ -1153,6 +1117,9 @@ void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cbs->ext[filter_id].function = NULL;
|
||||||
|
cbs->ext[filter_id].user_data = NULL;
|
||||||
|
|
||||||
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_ext_filter),
|
filter_id * sizeof(struct can_mcan_ext_filter),
|
||||||
sizeof(struct can_mcan_ext_filter));
|
sizeof(struct can_mcan_ext_filter));
|
||||||
|
@ -1160,6 +1127,9 @@ void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
||||||
LOG_ERR("failed to clear ext filter element (err %d)", err);
|
LOG_ERR("failed to clear ext filter element (err %d)", err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
cbs->std[filter_id].function = NULL;
|
||||||
|
cbs->std[filter_id].user_data = NULL;
|
||||||
|
|
||||||
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_std_filter),
|
filter_id * sizeof(struct can_mcan_std_filter),
|
||||||
sizeof(struct can_mcan_std_filter));
|
sizeof(struct can_mcan_std_filter));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue