mirror of
git://nv-tegra.nvidia.com/kernel/nvethernetrm.git
synced 2025-12-22 17:34:29 +03:00
osi: l3l4: split perfect inv bit for each field
- HW has separate Inverse Match bits in l3l4 control register for each source address, destination address, source port and destination port. - Hence, added separate Inverse match bits for all the 4 fields in osi l3l4 structure to provide flexibility for l3l4 users. - Fixed validation parameter sequence to validate l3l4 parameters before processing filter data. Bug 3576506 Bug 3825731 Change-Id: Id7f8939acd92ad5799f2ad0d7cef5d4fcb7e00c5 Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2820517 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Bhadram Varka
parent
424f7987df
commit
e2cf4313dc
@@ -42,8 +42,6 @@ struct osi_l3_l4_filter {
|
||||
nveu32_t is_udp;
|
||||
/** ipv6 (OSI_TRUE) or ipv4 (OSI_FALSE) */
|
||||
nveu32_t is_ipv6;
|
||||
/** perfect(OSI_FALSE) or inverse(OSI_TRUE) */
|
||||
nveu32_t perfect_inverse_match;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
/** destination ip address information */
|
||||
struct {
|
||||
@@ -56,8 +54,12 @@ struct osi_l3_l4_filter {
|
||||
nveu16_t port_no;
|
||||
/** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t addr_match;
|
||||
/** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for address */
|
||||
nveu32_t addr_match_inv;
|
||||
/** port match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t port_match;
|
||||
/** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for port */
|
||||
nveu32_t port_match_inv;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
} dst;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
@@ -71,8 +73,12 @@ struct osi_l3_l4_filter {
|
||||
nveu16_t port_no;
|
||||
/** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t addr_match;
|
||||
/** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for address */
|
||||
nveu32_t addr_match_inv;
|
||||
/** port match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t port_match;
|
||||
/** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for port */
|
||||
nveu32_t port_match_inv;
|
||||
} src;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
} data;
|
||||
|
||||
@@ -1516,19 +1516,12 @@ static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core
|
||||
nveu32_t *ctr_reg)
|
||||
{
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t perfect_inverse_match = l3_l4->data.perfect_inverse_match;
|
||||
nveu32_t dma_routing_enable = l3_l4->dma_routing_enable;
|
||||
nveu32_t dst_addr_match = l3_l4->data.dst.addr_match;
|
||||
#else
|
||||
nveu32_t perfect_inverse_match = OSI_FALSE;
|
||||
nveu32_t dma_routing_enable = OSI_TRUE;
|
||||
nveu32_t dst_addr_match = OSI_TRUE;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
const nveu32_t dma_chan_shift[2] = {
|
||||
EQOS_MAC_L3L4_CTR_DMCHN_SHIFT,
|
||||
MGBE_MAC_L3L4_CTR_DMCHN_SHIFT
|
||||
};
|
||||
|
||||
const nveu32_t dma_chan_en_shift[2] = {
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT,
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT
|
||||
@@ -1537,24 +1530,26 @@ static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core
|
||||
|
||||
/* set routing dma channel */
|
||||
value |= dma_routing_enable << (dma_chan_en_shift[osi_core->mac] & 0x1FU);
|
||||
value |= l3_l4->dma_chan << (dma_chan_shift[osi_core->mac] & 0x1FU);
|
||||
value |= l3_l4->dma_chan << MAC_L3L4_CTR_DMCHN_SHIFT;
|
||||
|
||||
/* Enable L3 filters for IPv4 DESTINATION addr matching */
|
||||
value |= (dst_addr_match << MAC_L3L4_CTR_L3DAM_SHIFT) |
|
||||
(perfect_inverse_match << MAC_L3L4_CTR_L3DAIM_SHIFT);
|
||||
value |= dst_addr_match << MAC_L3L4_CTR_L3DAM_SHIFT;
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* Enable L3 filters for IPv4 DESTINATION addr INV matching */
|
||||
value |= l3_l4->data.dst.addr_match_inv << MAC_L3L4_CTR_L3DAIM_SHIFT;
|
||||
|
||||
/* Enable L3 filters for IPv4 SOURCE addr matching */
|
||||
value |= (l3_l4->data.src.addr_match << MAC_L3L4_CTR_L3SAM_SHIFT) |
|
||||
(perfect_inverse_match << MAC_L3L4_CTR_L3SAIM_SHIFT);
|
||||
(l3_l4->data.src.addr_match_inv << MAC_L3L4_CTR_L3SAIM_SHIFT);
|
||||
|
||||
/* Enable L4 filters for DESTINATION port No matching */
|
||||
value |= (l3_l4->data.dst.port_match << MAC_L3L4_CTR_L4DPM_SHIFT) |
|
||||
(perfect_inverse_match << MAC_L3L4_CTR_L4DPIM_SHIFT);
|
||||
(l3_l4->data.dst.port_match_inv << MAC_L3L4_CTR_L4DPIM_SHIFT);
|
||||
|
||||
/* Enable L4 filters for SOURCE Port No matching */
|
||||
value |= (l3_l4->data.src.port_match << MAC_L3L4_CTR_L4SPM_SHIFT) |
|
||||
(perfect_inverse_match << MAC_L3L4_CTR_L4SPIM_SHIFT);
|
||||
(l3_l4->data.src.port_match_inv << MAC_L3L4_CTR_L4SPIM_SHIFT);
|
||||
|
||||
/* set udp / tcp port matching bit (for l4) */
|
||||
value |= l3_l4->data.is_udp << MAC_L3L4_CTR_L4PEN_SHIFT;
|
||||
|
||||
@@ -105,17 +105,16 @@
|
||||
#define MAC_L3L4_CTR_L3SAIM_SHIFT 3
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#define MAC_L3L4_CTR_L3DAM_SHIFT 4
|
||||
#define MAC_L3L4_CTR_L3DAIM_SHIFT 5
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define MAC_L3L4_CTR_L3DAIM_SHIFT 5
|
||||
#define MAC_L3L4_CTR_L4PEN_SHIFT 16
|
||||
#define MAC_L3L4_CTR_L4SPM_SHIFT 18
|
||||
#define MAC_L3L4_CTR_L4SPIM_SHIFT 19
|
||||
#define MAC_L3L4_CTR_L4DPM_SHIFT 20
|
||||
#define MAC_L3L4_CTR_L4DPIM_SHIFT 21
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 3 bits */
|
||||
#define MAC_L3L4_CTR_DMCHN_SHIFT 24
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT 28
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 4 bits */
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT 31
|
||||
|
||||
/**
|
||||
|
||||
@@ -793,12 +793,94 @@ static nve32_t l3l4_find_match(const struct core_local *const l_core,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configure_l3l4_filter_helper - helper function for l3l4 configuration
|
||||
* @brief configure_l3l4_filter_valid_params - parameter validation function for l3l4 configuration
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate all the l3_l4 structure parameter.
|
||||
* Return -1 if parameter validation fails.
|
||||
* - Verify routing dma channel id value.
|
||||
* - Vefify each enable/disable parameters is <= OSI_TRUE.
|
||||
* - Return -1 if parameter validation fails.
|
||||
* - Return 0 on success.
|
||||
*
|
||||
* @param[inout] l_core: OSI local core data structure.
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t configure_l3l4_filter_valid_params(const struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4)
|
||||
{
|
||||
const nveu32_t max_dma_chan[2] = {
|
||||
OSI_EQOS_MAX_NUM_CHANS,
|
||||
OSI_MGBE_MAX_NUM_CHANS
|
||||
};
|
||||
nve32_t ret = -1;
|
||||
|
||||
/* validate dma channel */
|
||||
if (l3_l4->dma_chan > max_dma_chan[osi_core->mac]) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: Wrong DMA channel: "), (l3_l4->dma_chan));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* valate enb parameters */
|
||||
if ((l3_l4->filter_enb_dis
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
| l3_l4->dma_routing_enable |
|
||||
l3_l4->data.is_udp |
|
||||
l3_l4->data.is_ipv6 |
|
||||
l3_l4->data.src.port_match |
|
||||
l3_l4->data.src.addr_match |
|
||||
l3_l4->data.dst.port_match |
|
||||
l3_l4->data.dst.addr_match |
|
||||
l3_l4->data.src.port_match_inv |
|
||||
l3_l4->data.src.addr_match_inv |
|
||||
l3_l4->data.dst.port_match_inv |
|
||||
l3_l4->data.dst.addr_match_inv
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
) > OSI_TRUE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: one of the enb param > OSI_TRUE: "), 0);
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* validate port/addr enb bits */
|
||||
if (l3_l4->filter_enb_dis == OSI_TRUE) {
|
||||
if ((l3_l4->data.src.port_match | l3_l4->data.src.addr_match |
|
||||
l3_l4->data.dst.port_match | l3_l4->data.dst.addr_match)
|
||||
== OSI_FALSE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: None of the enb bits are not set: "), 0);
|
||||
goto exit_func;
|
||||
}
|
||||
if ((l3_l4->data.is_ipv6 & l3_l4->data.src.addr_match &
|
||||
l3_l4->data.dst.addr_match) != OSI_FALSE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: Both ip6 addr match bits are set\n"), 0);
|
||||
goto exit_func;
|
||||
}
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/* success */
|
||||
ret = 0;
|
||||
|
||||
exit_func:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configure_l3l4_filter_helper - helper function for l3l4 configuration
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Confifure l3l4 filter using l_core->ops_p->config_l3l4_filters().
|
||||
* Return -1 if config_l3l4_filters() fails.
|
||||
* - Store the filter into l_core->cfg.l3_l4[] and enable
|
||||
@@ -820,69 +902,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi
|
||||
{
|
||||
struct osi_l3_l4_filter *cfg_l3_l4;
|
||||
struct core_local *const l_core = (struct core_local *)(void *)osi_core;
|
||||
const nveu32_t max_filter_no[2] = {
|
||||
EQOS_MAX_L3_L4_FILTER,
|
||||
OSI_MGBE_MAX_L3_L4_FILTER
|
||||
};
|
||||
const nveu32_t max_dma_chan[2] = {
|
||||
OSI_EQOS_MAX_NUM_CHANS,
|
||||
OSI_MGBE_MAX_NUM_CHANS
|
||||
};
|
||||
nve32_t ret = -1;
|
||||
|
||||
/* validate filter index */
|
||||
if (filter_no >= max_filter_no[osi_core->mac]) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("invalid filter index for L3/L4 filter\n"), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* validate dma channel */
|
||||
if (l3_l4->dma_chan > max_dma_chan[osi_core->mac]) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: Wrong DMA channel: "), (l3_l4->dma_chan));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* valate enb parameters */
|
||||
if ((
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
l3_l4->dma_routing_enable |
|
||||
l3_l4->data.is_udp |
|
||||
l3_l4->data.is_ipv6 |
|
||||
l3_l4->data.perfect_inverse_match |
|
||||
l3_l4->data.src.port_match |
|
||||
l3_l4->data.src.addr_match |
|
||||
l3_l4->data.dst.port_match |
|
||||
l3_l4->data.dst.addr_match |
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
l3_l4->filter_enb_dis
|
||||
) > OSI_TRUE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: one of the enb param > OSI_TRUE: "), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* validate port/addr enb bits */
|
||||
if (l3_l4->filter_enb_dis == OSI_TRUE) {
|
||||
if ((l3_l4->data.src.port_match | l3_l4->data.src.addr_match |
|
||||
l3_l4->data.dst.port_match | l3_l4->data.dst.addr_match)
|
||||
== OSI_FALSE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: None of the enb bits are not set: "),
|
||||
(filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
if ((l3_l4->data.is_ipv6 & l3_l4->data.src.addr_match &
|
||||
l3_l4->data.dst.addr_match) != OSI_FALSE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: Both ip6 addr match bits are set\n"),
|
||||
(filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nve32_t ret;
|
||||
|
||||
ret = l_core->ops_p->config_l3l4_filters(osi_core, filter_no, l3_l4);
|
||||
if (ret < 0) {
|
||||
@@ -902,7 +922,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi
|
||||
("L3L4: ADD: "), (filter_no));
|
||||
|
||||
/* update filter mask bit */
|
||||
osi_core->l3l4_filter_bitmask |= (((nveu32_t)1U << filter_no) & 0x1FU);
|
||||
osi_core->l3l4_filter_bitmask |= ((nveu32_t)1U << (filter_no & 0x1FU));
|
||||
} else {
|
||||
/* Clear the filter data.
|
||||
* osi_memset is an internal function and it cannot fail, hence
|
||||
@@ -913,7 +933,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi
|
||||
("L3L4: DELETE: "), (filter_no));
|
||||
|
||||
/* update filter mask bit */
|
||||
osi_core->l3l4_filter_bitmask &= ~(((nveu32_t)1U << filter_no) & 0x1FU);
|
||||
osi_core->l3l4_filter_bitmask &= ~((nveu32_t)1U << (filter_no & 0x1FU));
|
||||
}
|
||||
|
||||
if (osi_core->l3l4_filter_bitmask != 0U) {
|
||||
@@ -960,11 +980,14 @@ static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core,
|
||||
osi_memset(l3l4_filter, 0, sizeof(struct osi_l3_l4_filter));
|
||||
l3l4_filter->filter_enb_dis = OSI_TRUE;
|
||||
l3l4_filter->data.is_udp = OSI_TRUE;
|
||||
l3l4_filter->data.perfect_inverse_match = OSI_TRUE;
|
||||
l3l4_filter->data.src.port_match = OSI_TRUE;
|
||||
l3l4_filter->data.dst.port_match = OSI_TRUE;
|
||||
l3l4_filter->data.src.port_match_inv = OSI_TRUE;
|
||||
l3l4_filter->data.src.addr_match = OSI_TRUE;
|
||||
l3l4_filter->data.src.addr_match_inv = OSI_TRUE;
|
||||
l3l4_filter->data.dst.port_match = OSI_TRUE;
|
||||
l3l4_filter->data.dst.port_match_inv = OSI_TRUE;
|
||||
l3l4_filter->data.dst.addr_match = OSI_TRUE;
|
||||
l3l4_filter->data.dst.addr_match_inv = OSI_TRUE;
|
||||
|
||||
/* configure wildcard at last filter index */
|
||||
err = configure_l3l4_filter_helper(osi_core, max_filter_no, l3l4_filter);
|
||||
@@ -988,6 +1011,8 @@ static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core,
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate all the l3_l4 structure parameter using configure_l3l4_filter_valid_params().
|
||||
* Return -1 if parameter validation fails.
|
||||
* - For filter enable case,
|
||||
* -> If filter already enabled, return -1 to report error.
|
||||
* -> Otherwise find free index and configure filter using configure_l3l4_filter_helper().
|
||||
@@ -1022,6 +1047,11 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core,
|
||||
};
|
||||
nve32_t ret = -1;
|
||||
|
||||
if (configure_l3l4_filter_valid_params(osi_core, l3_l4) < 0) {
|
||||
/* parameter validation failed */
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* search for a duplicate filter request or find for free index */
|
||||
err = l3l4_find_match(l_core, l3_l4, &filter_no, &free_filter_no,
|
||||
max_filter_no[osi_core->mac]);
|
||||
|
||||
Reference in New Issue
Block a user