mirror of
git://nv-tegra.nvidia.com/kernel/nvethernetrm.git
synced 2025-12-22 09:12:10 +03:00
osi: l3l4: support four tuple for l3l4 fitlers
Following implemented for non safety. - Moved l3l4 filter index assignment to OSI for better management. OSDs need not worry about managing l3l4 filter indexes. - Restructured code to support four tuple for osi l3 l4 filter. - Added a wildcard l3l4 filter at highest filter index to allow the the packets to receive on default dma channel (from l2 filter) for the packets which do not match with any of the configured l3 l4 filters. - For IPv4, allowed user to configure all SA+DA+SP+DP together at a single l3l4 filter index or user can selectively add any combination among them (e.g, only SA or SP+DA, etc.). - For IPV6, only restriction is to add either of the SA or DA only but not both at a time at a single l3l4 index. Bug 3576506 Bug 3825731 Change-Id: I20bd197f5bf793a77f5e723d1875875d442af66e Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2802626 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
20f52bb866
commit
3be2a1e7f3
@@ -63,12 +63,5 @@ typedef my_ulint_64 nveul64_t;
|
||||
typedef my_uint64_t nveu64_t;
|
||||
/** @} */
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** intermediate type for short */
|
||||
typedef short my_int16_t;
|
||||
/** typedef equivalent to short */
|
||||
typedef my_int16_t nve16_t;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
#endif /* INCLUDED_TYPE_H */
|
||||
|
||||
|
||||
89
include/nvethernetrm_l3l4.h
Normal file
89
include/nvethernetrm_l3l4.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_NVETHERNETRM_L3L4_H
|
||||
#define INCLUDED_NVETHERNETRM_L3L4_H
|
||||
|
||||
#include <nvethernet_type.h>
|
||||
|
||||
/** helper macro for enable */
|
||||
#define OSI_TRUE ((nveu32_t)1U)
|
||||
|
||||
/** helper macro to disable */
|
||||
#define OSI_FALSE ((nveu32_t)0U)
|
||||
|
||||
/**
|
||||
* @brief L3/L4 filter function dependent parameter
|
||||
*/
|
||||
struct osi_l3_l4_filter {
|
||||
/** filter data */
|
||||
struct {
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** udp (OSI_TRUE) or tcp (OSI_FALSE) */
|
||||
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 {
|
||||
/** ipv4 address */
|
||||
nveu8_t ip4_addr[4];
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** ipv6 address */
|
||||
nveu16_t ip6_addr[8];
|
||||
/** Port number */
|
||||
nveu16_t port_no;
|
||||
/** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t addr_match;
|
||||
/** port match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t port_match;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
} dst;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** ip address and port information */
|
||||
struct {
|
||||
/** ipv4 address */
|
||||
nveu8_t ip4_addr[4];
|
||||
/** ipv6 address */
|
||||
nveu16_t ip6_addr[8];
|
||||
/** Port number */
|
||||
nveu16_t port_no;
|
||||
/** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t addr_match;
|
||||
/** port match enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t port_match;
|
||||
} src;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
} data;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** Represents whether DMA routing enabled (OSI_TRUE) or not (OSI_FALSE) */
|
||||
nveu32_t dma_routing_enable;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
/** DMA channel number of routing enabled */
|
||||
nveu32_t dma_chan;
|
||||
/** filter enable (OSI_TRUE) or disable (OSI_FALSE) */
|
||||
nveu32_t filter_enb_dis;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_NVETHERNETRM_L3L4_H */
|
||||
@@ -228,7 +228,6 @@
|
||||
#define OSI_MGBE_MAC_3_10 0x31U
|
||||
|
||||
#define OSI_MAX_VM_IRQS 5U
|
||||
#define OSI_IP4_FILTER 0U
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define OSI_HASH_FILTER_MODE 1U
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define INCLUDED_OSI_CORE_H
|
||||
|
||||
#include "nvethernetrm_export.h"
|
||||
#include "nvethernetrm_l3l4.h"
|
||||
#include <osi_common.h>
|
||||
#include "mmc.h"
|
||||
|
||||
@@ -166,7 +167,9 @@ typedef my_lint_64 nvel64_t;
|
||||
#define EQOS_MAX_L3_L4_FILTER 8U
|
||||
#define OSI_MGBE_MAX_MAC_ADDRESS_FILTER 32U
|
||||
#define OSI_DA_MATCH 0U
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define OSI_INV_MATCH 1U
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#define OSI_AMASK_DISABLE 0U
|
||||
#define OSI_CHAN_ANY 0xFFU
|
||||
#define OSI_DFLT_MTU_SIZE 1500U
|
||||
@@ -182,11 +185,6 @@ typedef my_lint_64 nvel64_t;
|
||||
#define OSI_FULL_DUPLEX 1
|
||||
#define OSI_HALF_DUPLEX 0
|
||||
|
||||
#define OSI_IP4_FILTER 0U
|
||||
#define OSI_IP6_FILTER 1U
|
||||
#define OSI_IPV6_MATCH 1U
|
||||
#define OSI_IPV4_MATCH 0U
|
||||
|
||||
/* L2 filter operations supported by OSI layer. These operation modes shall be
|
||||
* set by OSD driver as input to update registers accordingly.
|
||||
*/
|
||||
@@ -201,7 +199,6 @@ typedef my_lint_64 nvel64_t;
|
||||
|
||||
#define OSI_PAUSE_FRAMES_DISABLE 1U
|
||||
#define OSI_PFT_MATCH 0U
|
||||
#define OSI_SOURCE_MATCH 0U
|
||||
#define OSI_SA_MATCH 1U
|
||||
|
||||
#define OSI_SPEED_10 10
|
||||
@@ -488,27 +485,6 @@ struct osi_rxq_route {
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief L3/L4 filter function dependent parameter
|
||||
*/
|
||||
struct osi_l3_l4_filter {
|
||||
/** Indicates the index of the filter to be modified.
|
||||
* Filter index must be between 0 - 7 */
|
||||
nveu32_t filter_no;
|
||||
/** filter enable(1) or disable(0) */
|
||||
nveu32_t filter_enb_dis;
|
||||
/** source(0) or destination(1) */
|
||||
nveu32_t src_dst_addr_match;
|
||||
/** perfect(0) or inverse(1) */
|
||||
nveu32_t perfect_inverse_match;
|
||||
/** ipv4 address */
|
||||
nveu8_t ip4_addr[4];
|
||||
/** ipv6 address */
|
||||
nveu16_t ip6_addr[8];
|
||||
/** Port number */
|
||||
nveu16_t port_no;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief struct osi_hw_features - MAC HW supported features.
|
||||
*/
|
||||
|
||||
@@ -332,10 +332,10 @@ done:
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*/
|
||||
static inline nve32_t osi_memcpy(void *dest, void *src, nveu64_t n)
|
||||
static inline nve32_t osi_memcpy(void *dest, const void *src, nveu64_t n)
|
||||
{
|
||||
nve8_t *cdest = (nve8_t *)dest;
|
||||
const nve8_t *csrc = (nve8_t *)src;
|
||||
nve8_t *cdest = dest;
|
||||
const nve8_t *csrc = src;
|
||||
nve32_t ret = 0;
|
||||
nveu64_t i = 0;
|
||||
|
||||
@@ -351,10 +351,10 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n)
|
||||
static inline nve32_t osi_memcmp(const void *dest, const void *src, nve32_t n)
|
||||
{
|
||||
const nve8_t *const cdest = (nve8_t *)dest;
|
||||
const nve8_t *const csrc = (nve8_t *)src;
|
||||
const nve8_t *const cdest = dest;
|
||||
const nve8_t *const csrc = src;
|
||||
nve32_t ret = 0;
|
||||
nve32_t i;
|
||||
|
||||
|
||||
@@ -1495,3 +1495,227 @@ void hsi_common_error_inject(struct osi_core_priv_data *osi_core,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief prepare_l3l4_ctr_reg - Prepare control register for L3L4 filters.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - This sequence is used to prepare L3L4 control register for SA and DA Port Number matching.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
* @param[out] ctr_reg: Pointer to L3L4 CTR register value
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
*
|
||||
* @retval L3L4 CTR register value
|
||||
*/
|
||||
static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4,
|
||||
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
|
||||
};
|
||||
nveu32_t value = 0U;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* set udp / tcp port matching bit (for l4) */
|
||||
value |= l3_l4->data.is_udp << MAC_L3L4_CTR_L4PEN_SHIFT;
|
||||
|
||||
/* set ipv4 / ipv6 protocol matching bit (for l3) */
|
||||
value |= l3_l4->data.is_ipv6 << MAC_L3L4_CTR_L3PEN_SHIFT;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
*ctr_reg = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief prepare_l3_addr_registers - prepare register data for IPv4/IPv6 address filtering
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Update IPv4/IPv6 source/destination address for L3 layer filtering.
|
||||
* - For IPv4, both source/destination address can be configured but
|
||||
* for IPv6, only one of the source/destination address can be configured.
|
||||
*
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
* @param[out] l3_addr1_reg: Pointer to L3 ADDR1 register value
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
*/
|
||||
static void prepare_l3_addr_registers(const struct osi_l3_l4_filter *const l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t *l3_addr0_reg,
|
||||
nveu32_t *l3_addr2_reg,
|
||||
nveu32_t *l3_addr3_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nveu32_t *l3_addr1_reg)
|
||||
{
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
if (l3_l4->data.is_ipv6 == OSI_TRUE) {
|
||||
const nveu16_t *addr;
|
||||
/* For IPv6, either source address or destination
|
||||
* address only one of them can be enabled
|
||||
*/
|
||||
if (l3_l4->data.src.addr_match == OSI_TRUE) {
|
||||
/* select src address only */
|
||||
addr = l3_l4->data.src.ip6_addr;
|
||||
} else {
|
||||
/* select dst address only */
|
||||
addr = l3_l4->data.dst.ip6_addr;
|
||||
}
|
||||
/* update Bits[31:0] of 128-bit IP addr */
|
||||
*l3_addr0_reg = addr[7] | ((nveu32_t)addr[6] << 16);
|
||||
|
||||
/* update Bits[63:32] of 128-bit IP addr */
|
||||
*l3_addr1_reg = addr[5] | ((nveu32_t)addr[4] << 16);
|
||||
|
||||
/* update Bits[95:64] of 128-bit IP addr */
|
||||
*l3_addr2_reg = addr[3] | ((nveu32_t)addr[2] << 16);
|
||||
|
||||
/* update Bits[127:96] of 128-bit IP addr */
|
||||
*l3_addr3_reg = addr[1] | ((nveu32_t)addr[0] << 16);
|
||||
} else {
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
const nveu8_t *addr;
|
||||
nveu32_t value;
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* set source address */
|
||||
addr = l3_l4->data.src.ip4_addr;
|
||||
value = addr[3];
|
||||
value |= (nveu32_t)addr[2] << 8;
|
||||
value |= (nveu32_t)addr[1] << 16;
|
||||
value |= (nveu32_t)addr[0] << 24;
|
||||
*l3_addr0_reg = value;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/* set destination address */
|
||||
addr = l3_l4->data.dst.ip4_addr;
|
||||
value = addr[3];
|
||||
value |= (nveu32_t)addr[2] << 8;
|
||||
value |= (nveu32_t)addr[1] << 16;
|
||||
value |= (nveu32_t)addr[0] << 24;
|
||||
*l3_addr1_reg = value;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief prepare_l4_port_register - program source and destination port number
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Program l4 address register with source and destination port numbers.
|
||||
*
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
* @param[out] l4_addr_reg: Pointer to L3 ADDR0 register value
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 3) DCS bits should be enabled in RXQ to DMA mapping register
|
||||
*/
|
||||
static void prepare_l4_port_register(const struct osi_l3_l4_filter *const l3_l4,
|
||||
nveu32_t *l4_addr_reg)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
|
||||
/* set source port */
|
||||
value |= ((nveu32_t)l3_l4->data.src.port_no
|
||||
& MGBE_MAC_L4_ADDR_SP_MASK);
|
||||
|
||||
/* set destination port */
|
||||
value |= (((nveu32_t)l3_l4->data.dst.port_no <<
|
||||
MGBE_MAC_L4_ADDR_DP_SHIFT) & MGBE_MAC_L4_ADDR_DP_MASK);
|
||||
|
||||
*l4_addr_reg = value;
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/**
|
||||
* @brief prepare_l3l4_registers - function to prepare l3l4 registers
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - If filter to be enabled,
|
||||
* - Prepare l3 ip address registers using prepare_l3_addr_registers().
|
||||
* - Prepare l4 port register using prepare_l4_port_register().
|
||||
* - Prepare l3l4 control register using prepare_l3l4_ctr_reg().
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
* @param[out] l4_addr_reg: Pointer to L3 ADDR0 register value
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 2) osi_core->osd should be populated
|
||||
* 3) DCS bits should be enabled in RXQ to DMA mapping register
|
||||
*/
|
||||
void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t *l3_addr0_reg,
|
||||
nveu32_t *l3_addr2_reg,
|
||||
nveu32_t *l3_addr3_reg,
|
||||
nveu32_t *l4_addr_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nveu32_t *l3_addr1_reg,
|
||||
nveu32_t *ctr_reg)
|
||||
{
|
||||
/* prepare regiser data if filter to be enabled */
|
||||
if (l3_l4->filter_enb_dis == OSI_TRUE) {
|
||||
/* prepare l3 filter ip address register data */
|
||||
prepare_l3_addr_registers(l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
l3_addr0_reg,
|
||||
l3_addr2_reg,
|
||||
l3_addr3_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
l3_addr1_reg);
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* prepare l4 filter port register data */
|
||||
prepare_l4_port_register(l3_l4, l4_addr_reg);
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/* prepare control register data */
|
||||
prepare_l3l4_ctr_reg(osi_core, l3_l4, ctr_reg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,27 @@
|
||||
#define MAC_PKT_FILTER_REG 0x0008
|
||||
#define HW_MAC_IER 0x00B4U
|
||||
#define WRAP_COMMON_INTR_ENABLE 0x8704U
|
||||
|
||||
/* common l3 l4 register bit fields for eqos and mgbe */
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define MAC_L3L4_CTR_L3PEN_SHIFT 0
|
||||
#define MAC_L3L4_CTR_L3SAM_SHIFT 2
|
||||
#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_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 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
|
||||
|
||||
/**
|
||||
* @addtogroup typedef related info
|
||||
*
|
||||
@@ -142,6 +163,16 @@ nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_fpe_config *const fpe);
|
||||
void hw_tsn_init(struct osi_core_priv_data *osi_core,
|
||||
nveu32_t est_sel, nveu32_t fpe_sel);
|
||||
void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t *l3_addr0_reg,
|
||||
nveu32_t *l3_addr2_reg,
|
||||
nveu32_t *l3_addr3_reg,
|
||||
nveu32_t *l4_addr_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nveu32_t *l3_addr1_reg,
|
||||
nveu32_t *ctr_reg);
|
||||
#ifdef HSI_SUPPORT
|
||||
void hsi_common_error_inject(struct osi_core_priv_data *osi_core,
|
||||
nveu32_t error_code);
|
||||
|
||||
@@ -118,15 +118,10 @@ struct core_ops {
|
||||
nve32_t (*update_mac_addr_low_high_reg)(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_filter *filter);
|
||||
/** Called to configure L3 filter */
|
||||
nve32_t (*config_l3_filters)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t ipv4_ipv6_match,
|
||||
const nveu32_t src_dst_addr_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan);
|
||||
/** Called to configure L3L4 filter */
|
||||
nve32_t (*config_l3l4_filters)(struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t filter_no,
|
||||
const struct osi_l3_l4_filter *const l3_l4);
|
||||
/** Called to adjust the mac time */
|
||||
nve32_t (*adjust_mactime)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t sec,
|
||||
@@ -147,11 +142,6 @@ struct core_ops {
|
||||
/** Called to get HW features */
|
||||
nve32_t (*get_hw_features)(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_hw_features *hw_feat);
|
||||
/** Called to update ip4 src or desc address */
|
||||
nve32_t (*update_ip4_addr)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu8_t addr[],
|
||||
const nveu32_t src_dst_addr_match);
|
||||
/** Called to read reg */
|
||||
nveu32_t (*read_reg)(struct osi_core_priv_data *const osi_core,
|
||||
const nve32_t reg);
|
||||
@@ -173,25 +163,6 @@ struct core_ops {
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#endif /* MACSEC_SUPPORT */
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/** Called to update ip6 address */
|
||||
nve32_t (*update_ip6_addr)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t addr[]);
|
||||
/** Called to configure L4 filter */
|
||||
nve32_t (*config_l4_filters)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t tcp_udp_match,
|
||||
const nveu32_t src_dst_port_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan);
|
||||
/** Called to update L4 Port for filter packet */
|
||||
nve32_t (*update_l4_port_no)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t port_no,
|
||||
const nveu32_t src_dst_port_match);
|
||||
|
||||
/** Called to configure the MTL to forward/drop tx status */
|
||||
nve32_t (*config_tx_status)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t tx_status);
|
||||
@@ -315,24 +286,6 @@ struct core_ptp_servo {
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief L3/L4 dynamic config storage structure.
|
||||
*/
|
||||
struct l3_l4_filters {
|
||||
/** Represent whether index used or not */
|
||||
nveu32_t used;
|
||||
/** Type of filter */
|
||||
nveu32_t type;
|
||||
/** Represents whether DMA routing enabled or not */
|
||||
nveu32_t dma_routing_enable;
|
||||
/** DMA channel number of routing enabled */
|
||||
nveu32_t dma_chan;
|
||||
/** Tells whether its L4 or L3 filter */
|
||||
nveu32_t is_l4_filter;
|
||||
/** Filter information */
|
||||
struct osi_l3_l4_filter l3l4_filter;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief AVB dynamic config storage structure
|
||||
*/
|
||||
@@ -367,7 +320,7 @@ struct core_l2 {
|
||||
struct dynamic_cfg {
|
||||
nveu32_t flags;
|
||||
/** L3_L4 filters */
|
||||
struct l3_l4_filters l3_l4[OSI_MGBE_MAX_L3_L4_FILTER];
|
||||
struct osi_l3_l4_filter l3_l4[OSI_MGBE_MAX_L3_L4_FILTER];
|
||||
/** flow control */
|
||||
nveu32_t flow_ctrl;
|
||||
/** AVB */
|
||||
@@ -441,6 +394,12 @@ struct core_local {
|
||||
nveu32_t lane_status;
|
||||
/** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */
|
||||
nveu32_t l_mac_ver;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#ifdef L3L4_WILDCARD_FILTER
|
||||
/** l3l4 wildcard filter configured (OSI_ENABLE) / not configured (OSI_DISABLE) */
|
||||
nveu32_t l3l4_wildcard_filter_configured;
|
||||
#endif /* L3L4_WILDCARD_FILTER */
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1231,7 +1231,8 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core)
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_006
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure. Used params are
|
||||
* - base, dcs_en, num_mtl_queues, mtl_queues, mtu, stip_vlan_tag, pause_frames, l3l4_filter_bitmask
|
||||
* - base, dcs_en, num_mtl_queues, mtl_queues, mtu, stip_vlan_tag, pause_frames,
|
||||
* l3l4_filter_bitmask
|
||||
* @param[in] tx_fifo_size: MTL TX FIFO size. Max 11.
|
||||
* @param[in] rx_fifo_size: MTL RX FIFO size. Max 11.
|
||||
*
|
||||
@@ -2209,72 +2210,6 @@ static nve32_t eqos_update_mac_addr_low_high_reg(
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_update_ip4_addr - configure register for IPV4 address filtering
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate addr for null, filter_no for max value and return -1 on failure.
|
||||
* - Update IPv4 source/destination address for L3 layer filtering.
|
||||
* - Refer to EQOS column of <<RM_19, (sequence diagram)>> for API details.
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_019
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure. Used param base.
|
||||
* @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details.
|
||||
* @param[in] addr: ipv4 address. Refer #osi_l3_l4_filter->ip4_addr for details.
|
||||
* @param[in] src_dst_addr_match: Refer #osi_l3_l4_filter->src_dst_addr_match for details.
|
||||
*
|
||||
* @pre 1) MAC should be initialized and started. see osi_start_mac()
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu8_t addr[],
|
||||
const nveu32_t src_dst_addr_match)
|
||||
{
|
||||
void *base = osi_core->base;
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
|
||||
if (addr == OSI_NULL) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid address\n", 0ULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = addr[3];
|
||||
temp = (nveu32_t)addr[2] << 8;
|
||||
value |= temp;
|
||||
temp = (nveu32_t)addr[1] << 16;
|
||||
value |= temp;
|
||||
temp = (nveu32_t)addr[0] << 24;
|
||||
value |= temp;
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD0R(filter_no));
|
||||
} else {
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD1R(filter_no));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief eqos_config_ptp_offload - Enable/Disable PTP offload
|
||||
@@ -2376,548 +2311,76 @@ static nve32_t eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_update_ip6_addr - add ipv6 address in register
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate addr for null, filter_no for max value and return -1 on failure.
|
||||
* - Update IPv6 source/destination address for L3 layer filtering.
|
||||
* - Refer to EQOS column of <<RM_19, (sequence diagram)>> for API details.
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_019
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure. Used param base.
|
||||
* @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details.
|
||||
* @param[in] addr: ipv4 address. Refer #osi_l3_l4_filter->ip6_addr for details.
|
||||
*
|
||||
* @pre MAC should be initialized and started. see osi_start_mac()
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: No
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t addr[])
|
||||
{
|
||||
void *base = osi_core->base;
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
|
||||
if (addr == OSI_NULL) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid address\n", 0ULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* update Bits[31:0] of 128-bit IP addr */
|
||||
value = addr[7];
|
||||
temp = (nveu32_t)addr[6] << 16;
|
||||
value |= temp;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD0R(filter_no));
|
||||
/* update Bits[63:32] of 128-bit IP addr */
|
||||
value = addr[5];
|
||||
temp = (nveu32_t)addr[4] << 16;
|
||||
value |= temp;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD1R(filter_no));
|
||||
/* update Bits[95:64] of 128-bit IP addr */
|
||||
value = addr[3];
|
||||
temp = (nveu32_t)addr[2] << 16;
|
||||
value |= temp;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD2R(filter_no));
|
||||
/* update Bits[127:96] of 128-bit IP addr */
|
||||
value = addr[1];
|
||||
temp = (nveu32_t)addr[0] << 16;
|
||||
value |= temp;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3_AD3R(filter_no));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_update_l4_port_no -program source port no
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate filter_no for max value and return -1 on failure.
|
||||
* - Update port_no based on src_dst_port_match to confiure L4 layer filtering.
|
||||
* - Refer to EQOS column of <<RM_19, (sequence diagram)>> for API details.
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_019
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure. Used param base.
|
||||
* @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details.
|
||||
* @param[in] port_no: ipv4 address. Refer #osi_l3_l4_filter->port_no for details.
|
||||
* @param[in] src_dst_port_match: Refer #osi_l3_l4_filter->src_dst_port_match for details.
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
* - osi_core->osd should be populated.
|
||||
* - DCS bits should be enabled in RXQ to DMA mapping register
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_update_l4_port_no(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t port_no,
|
||||
const nveu32_t src_dst_port_match)
|
||||
{
|
||||
void *base = osi_core->base;
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
|
||||
if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = osi_readla(osi_core,
|
||||
(nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no));
|
||||
if (src_dst_port_match == OSI_SOURCE_MATCH) {
|
||||
value &= ~EQOS_MAC_L4_SP_MASK;
|
||||
value |= ((nveu32_t)port_no & EQOS_MAC_L4_SP_MASK);
|
||||
} else {
|
||||
value &= ~EQOS_MAC_L4_DP_MASK;
|
||||
temp = port_no;
|
||||
value |= ((temp << EQOS_MAC_L4_DP_SHIFT) & EQOS_MAC_L4_DP_MASK);
|
||||
}
|
||||
osi_writela(osi_core, value,
|
||||
(nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/** \cond DO_NOT_DOCUMENT */
|
||||
/**
|
||||
* @brief eqos_set_dcs - check and update dma routing register
|
||||
* @brief eqos_config_l3l4_filters - Config L3L4 filters.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Check for request for DCS_enable as well as validate chan
|
||||
* number and dcs_enable is set. After validation, this sequence is used
|
||||
* to configure L3((IPv4/IPv6) filters for address matching.
|
||||
* - This sequence is used to configure L3L4 filters for SA and DA Port Number matching.
|
||||
* - Prepare register data using prepare_l3l4_registers().
|
||||
* - Write l3l4 reigsters using mgbe_l3l4_filter_write().
|
||||
* - Return 0 on success.
|
||||
* - Return -1 on any register failure.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] value: nveu32_t value for caller
|
||||
* @param[in] dma_routing_enable: filter based dma routing enable(1)
|
||||
* @param[in] dma_chan: dma channel for routing based on filter
|
||||
* @param[in] filter_no_r: filter index
|
||||
* @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()
|
||||
* - DCS bit of RxQ should be enabled for dynamic channel selection
|
||||
* in filter support
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
*@return updated nveu32_t value
|
||||
*/
|
||||
static inline nveu32_t eqos_set_dcs(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t value,
|
||||
nveu32_t dma_routing_enable,
|
||||
nveu32_t dma_chan)
|
||||
{
|
||||
nveu32_t t_val = value;
|
||||
|
||||
if ((dma_routing_enable == OSI_ENABLE) && (dma_chan <
|
||||
OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en ==
|
||||
OSI_ENABLE)) {
|
||||
t_val |= ((dma_routing_enable <<
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT) &
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0);
|
||||
t_val |= ((dma_chan <<
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT) &
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0);
|
||||
}
|
||||
|
||||
return t_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_helper_l3l4_bitmask - helper function to set L3L4
|
||||
* bitmask.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - set bit corresponding to L3l4 filter index
|
||||
*
|
||||
* @param[out] bitmask: bit mask OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] value: 0 - disable otherwise - l3/l4 filter enabled
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @pre MAC should be initialized and started. see osi_start_mac()
|
||||
*
|
||||
*/
|
||||
static inline void eqos_helper_l3l4_bitmask(nveu32_t *bitmask,
|
||||
nveu32_t filter_no,
|
||||
nveu32_t value)
|
||||
{
|
||||
nveu32_t temp;
|
||||
|
||||
/* Set bit mask for index */
|
||||
temp = OSI_ENABLE;
|
||||
temp = temp << filter_no;
|
||||
/* check against all bit fields for L3L4 filter enable */
|
||||
if ((value & EQOS_MAC_L3L4_CTRL_ALL) != OSI_DISABLE) {
|
||||
*bitmask |= temp;
|
||||
} else {
|
||||
*bitmask &= ~temp;
|
||||
}
|
||||
}
|
||||
/** \endcond */
|
||||
|
||||
/**
|
||||
* @brief eqos_config_l3_filters - config L3 filters.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate filter_no for maximum and hannel number if dma_routing_enable
|
||||
* is OSI_ENABLE and reitrn -1 if fails.
|
||||
* - Configure L3 filter register based on all arguments(except for osi_core and dma_routing_enable)
|
||||
* - Refer to EQOS column of <<RM_19, (sequence diagram)>> for API details.
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_019
|
||||
*
|
||||
* @param[in, out] osi_core: OSI core private data structure. Used param is base.
|
||||
* @param[in] filter_no: filter index. Max EQOS_MAX_L3_L4_FILTER - 1.
|
||||
* @param[in] enb_dis: OSI_ENABLE - enable otherwise - disable L3 filter.
|
||||
* @param[in] ipv4_ipv6_match: OSI_IPV6_MATCH - IPv6, otherwise - IPv4.
|
||||
* @param[in] src_dst_addr_match: OSI_SOURCE_MATCH - source, otherwise - destination.
|
||||
* @param[in] perfect_inverse_match: normal match(0) or inverse map(1).
|
||||
* @param[in] dma_routing_enable: Valid value OSI_ENABLE, invalid otherwise.
|
||||
* @param[in] dma_chan: dma channel for routing based on filter. Max OSI_EQOS_MAX_NUM_CHANS-1.
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
* - osi_core->osd should be populated.
|
||||
* - DCS bit of RxQ should be enabled for dynamic channel selection
|
||||
* in filter support
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 2) osi_core->osd should be populated
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_config_l3_filters(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t ipv4_ipv6_match,
|
||||
const nveu32_t src_dst_addr_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan)
|
||||
static nve32_t eqos_config_l3l4_filters(struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t filter_no_r,
|
||||
const struct osi_l3_l4_filter *const l3_l4)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
void *base = osi_core->base;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t l3_addr0_reg = 0;
|
||||
nveu32_t l3_addr2_reg = 0;
|
||||
nveu32_t l3_addr3_reg = 0;
|
||||
nveu32_t l4_addr_reg = 0;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nveu32_t l3_addr1_reg = 0;
|
||||
nveu32_t ctr_reg = 0;
|
||||
nveu32_t filter_no = filter_no_r & (OSI_MGBE_MAX_L3_L4_FILTER - 1U);
|
||||
|
||||
if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((dma_routing_enable == OSI_ENABLE) &&
|
||||
(dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"Wrong DMA channel\n", (nveul64_t)dma_chan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3L4_CTR_L3PEN0;
|
||||
value |= (ipv4_ipv6_match & EQOS_MAC_L3L4_CTR_L3PEN0);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
|
||||
/* For IPv6 either SA/DA can be checked not both */
|
||||
if (ipv4_ipv6_match == OSI_IPV6_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
/* Enable L3 filters for IPv6 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L3SAI_SHIFT)) &
|
||||
((EQOS_MAC_L3L4_CTR_L3SAM0 |
|
||||
EQOS_MAC_L3L4_CTR_L3SAIM0)));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
|
||||
} else {
|
||||
/* Enable L3 filters for IPv6 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L3DAI_SHIFT)) &
|
||||
((EQOS_MAC_L3L4_CTR_L3DAM0 |
|
||||
EQOS_MAC_L3L4_CTR_L3DAIM0)));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
} else {
|
||||
/* Disable L3 filters for IPv6 SOURCE/DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~(EQOS_MAC_L3_IP6_CTRL_CLEAR |
|
||||
EQOS_MAC_L3L4_CTR_L3PEN0);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
} else {
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L3 filters for IPv4 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L3SAI_SHIFT)) &
|
||||
((EQOS_MAC_L3L4_CTR_L3SAM0 |
|
||||
EQOS_MAC_L3L4_CTR_L3SAIM0)));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
} else {
|
||||
/* Disable L3 filters for IPv4 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
} else {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L3 filters for IPv4 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L3DAI_SHIFT)) &
|
||||
((EQOS_MAC_L3L4_CTR_L3DAM0 |
|
||||
EQOS_MAC_L3L4_CTR_L3DAIM0)));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
} else {
|
||||
/* Disable L3 filters for IPv4 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set bit corresponding to filter index if value is non-zero */
|
||||
eqos_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask,
|
||||
filter_no, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
prepare_l3l4_registers(osi_core, l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
&l3_addr0_reg,
|
||||
&l3_addr2_reg,
|
||||
&l3_addr3_reg,
|
||||
&l4_addr_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
&l3_addr1_reg,
|
||||
&ctr_reg);
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief eqos_config_l4_filters - Config L4 filters.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate filter_no for maximum and hannel number if dma_routing_enable
|
||||
* is OSI_ENABLE and reitrn -1 if fails.
|
||||
* - Configure L4 filter register based on all arguments(except for osi_core and dma_routing_enable)
|
||||
* - Refer to EQOS column of <<RM_19, (sequence diagram)>> for API details.
|
||||
* - TraceID:ETHERNET_NVETHERNETRM_019
|
||||
*
|
||||
* @param[in, out] osi_core: OSI core private data structure. Used param is base.
|
||||
* @param[in] filter_no: filter index. Max EQOS_MAX_L3_L4_FILTER - 1.
|
||||
* @param[in] enb_dis: OSI_ENABLE - enable, otherwise - disable L4 filter
|
||||
* @param[in] tcp_udp_match: 1 - udp, 0 - tcp
|
||||
* @param[in] src_dst_port_match: OSI_SOURCE_MATCH - source port, otherwise - dest port
|
||||
* @param[in] perfect_inverse_match: normal match(0) or inverse map(1)
|
||||
* @param[in] dma_routing_enable: Valid value OSI_ENABLE, invalid otherwise.
|
||||
* @param[in] dma_chan: dma channel for routing based on filter. Max OSI_EQOS_MAX_NUM_CHANS-1.
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
* - osi_core->osd should be populated.
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_config_l4_filters(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t tcp_udp_match,
|
||||
const nveu32_t src_dst_port_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan)
|
||||
{
|
||||
void *base = osi_core->base;
|
||||
nveu32_t value = 0U;
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD0R register */
|
||||
osi_writela(osi_core, l3_addr0_reg, (nveu8_t *)base + EQOS_MAC_L3_AD0R(filter_no));
|
||||
|
||||
if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD2R register */
|
||||
osi_writela(osi_core, l3_addr2_reg, (nveu8_t *)base + EQOS_MAC_L3_AD2R(filter_no));
|
||||
|
||||
if ((dma_routing_enable == OSI_ENABLE) &&
|
||||
(dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"Wrong DMA channel\n", (nveu32_t)dma_chan);
|
||||
return -1;
|
||||
}
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD3R register */
|
||||
osi_writela(osi_core, l3_addr3_reg, (nveu8_t *)base + EQOS_MAC_L3_AD3R(filter_no));
|
||||
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L3L4_CTR_L4PEN0;
|
||||
value |= ((tcp_udp_match << EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT)
|
||||
& EQOS_MAC_L3L4_CTR_L4PEN0);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
/* Update l4 port EQOS_MAC_L4_ADR register */
|
||||
osi_writela(osi_core, l4_addr_reg, (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no));
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
if (src_dst_port_match == OSI_SOURCE_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L4 filters for SOURCE Port No matching */
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L4SPM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L4SPI_SHIFT)) &
|
||||
(EQOS_MAC_L3L4_CTR_L4SPM0 |
|
||||
EQOS_MAC_L3L4_CTR_L4SPIM0));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
} else {
|
||||
/* Disable L4 filters for SOURCE Port No matching */
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
} else {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L4 filters for DESTINATION port No
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR;
|
||||
value |= ((EQOS_MAC_L3L4_CTR_L4DPM0 |
|
||||
(perfect_inverse_match <<
|
||||
EQOS_MAC_L3L4_CTR_L4DPI_SHIFT)) &
|
||||
(EQOS_MAC_L3L4_CTR_L4DPM0 |
|
||||
EQOS_MAC_L3L4_CTR_L4DPIM0));
|
||||
value |= eqos_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
} else {
|
||||
/* Disable L4 filters for DESTINATION port No
|
||||
* matching
|
||||
*/
|
||||
value = osi_readla(osi_core, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR;
|
||||
osi_writela(osi_core, value, (nveu8_t *)base +
|
||||
EQOS_MAC_L3L4_CTR(filter_no));
|
||||
}
|
||||
}
|
||||
/* Set bit corresponding to filter index if value is non-zero */
|
||||
eqos_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask,
|
||||
filter_no, value);
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD1R register */
|
||||
osi_writela(osi_core, l3_addr1_reg, (nveu8_t *)base + EQOS_MAC_L3_AD1R(filter_no));
|
||||
|
||||
/* Write CTR register */
|
||||
osi_writela(osi_core, ctr_reg, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/**
|
||||
* @brief eqos_poll_for_update_ts_complete - Poll for update time stamp
|
||||
@@ -4725,13 +4188,11 @@ void eqos_init_core_ops(struct core_ops *ops)
|
||||
ops->handle_common_intr = eqos_handle_common_intr;
|
||||
ops->pad_calibrate = eqos_pad_calibrate;
|
||||
ops->update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg;
|
||||
ops->config_l3_filters = eqos_config_l3_filters;
|
||||
ops->adjust_mactime = eqos_adjust_mactime;
|
||||
ops->read_mmc = eqos_read_mmc;
|
||||
ops->write_phy_reg = eqos_write_phy_reg;
|
||||
ops->read_phy_reg = eqos_read_phy_reg;
|
||||
ops->get_hw_features = eqos_get_hw_features;
|
||||
ops->update_ip4_addr = eqos_update_ip4_addr;
|
||||
ops->read_reg = eqos_read_reg;
|
||||
ops->write_reg = eqos_write_reg;
|
||||
ops->set_avb_algorithm = eqos_set_avb_algorithm;
|
||||
@@ -4746,10 +4207,8 @@ void eqos_init_core_ops(struct core_ops *ops)
|
||||
ops->macsec_config_mac = eqos_config_for_macsec;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#endif /* MACSEC_SUPPORT */
|
||||
ops->config_l3l4_filters = eqos_config_l3l4_filters;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
ops->update_ip6_addr = eqos_update_ip6_addr;
|
||||
ops->config_l4_filters = eqos_config_l4_filters;
|
||||
ops->update_l4_port_no = eqos_update_l4_port_no;
|
||||
ops->config_tx_status = eqos_config_tx_status;
|
||||
ops->config_rx_crc_check = eqos_config_rx_crc_check;
|
||||
ops->config_flow_control = eqos_config_flow_control;
|
||||
|
||||
@@ -64,19 +64,10 @@
|
||||
(EQOS_5_30_SID_CH5) |\
|
||||
(EQOS_5_30_SID))
|
||||
#define EQOS_MAC_MA0HR_MASK 0xFFFFFU
|
||||
#define EQOS_MAC_L4_SP_MASK 0x0000FFFFU
|
||||
#define EQOS_MAC_L4_DP_MASK 0xFFFF0000U
|
||||
#define EQOS_MAC_L4_DP_SHIFT 16
|
||||
#define EQOS_MAC_L3L4_CTR_L4SPI_SHIFT 19
|
||||
#define EQOS_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16)
|
||||
#define EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT 16
|
||||
#define EQOS_MAC_IMR_MASK 0x67039U
|
||||
#define EQOS_MAC_HTR_MASK 0xFFFFFFFFU
|
||||
#define EQOS_MAC_HTR0_IDX 2U
|
||||
#define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U)
|
||||
#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U)
|
||||
#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU)
|
||||
#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U)
|
||||
#define EQOS_DMA_SBUS_MASK 0xDF1F3CFFU
|
||||
#define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10)
|
||||
#define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2)
|
||||
@@ -84,7 +75,6 @@
|
||||
#define EQOS_DMA_CHX_STATUS_RPS OSI_BIT(8)
|
||||
#define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9)
|
||||
#define EQOS_DMA_CHX_STATUS_TPS OSI_BIT(1)
|
||||
#define EQOS_MAC_L3L4_CTR_L4DPI_SHIFT 21
|
||||
#define EQOS_MAC_RQC0R_MASK 0xFFU
|
||||
#define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1)
|
||||
#define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U
|
||||
@@ -285,8 +275,13 @@
|
||||
#define EQOS_MMC_RX_INTR_MASK 0x070C
|
||||
#define EQOS_MMC_IPC_RX_INTR_MASK 0x0800
|
||||
#define EQOS_MAC_L3L4_CTR(x) ((0x0030U * (x)) + 0x0900U)
|
||||
#define EQOS_MAC_L3_AD0R(x) ((0x0030U * (x)) + 0x0910U)
|
||||
#define EQOS_MAC_L3_AD1R(x) ((0x0030U * (x)) + 0x0914U)
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define EQOS_MAC_L3_AD0R(x) ((0x0030U * (x)) + 0x0910U)
|
||||
#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U)
|
||||
#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU)
|
||||
#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U)
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#define EQOS_MAC_TCR 0x0B00
|
||||
#define EQOS_MAC_SSIR 0x0B04
|
||||
#define EQOS_MAC_STSUR 0x0B10
|
||||
@@ -449,49 +444,11 @@
|
||||
#define EQOS_MTL_RXQ_OP_MODE_RFA_MASK 0x00003F00U
|
||||
#define EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT 14U
|
||||
#define EQOS_MTL_RXQ_OP_MODE_RFD_MASK 0x000FC000U
|
||||
#define EQOS_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18)
|
||||
#define EQOS_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19)
|
||||
#define EQOS_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20)
|
||||
#define EQOS_MAC_L3L4_CTR_L4DPIM0 OSI_BIT(21)
|
||||
#define EQOS_MAC_L3L4_CTR_L3PEN0 OSI_BIT(0)
|
||||
#define EQOS_MAC_L3L4_CTR_L3SAM0 OSI_BIT(2)
|
||||
#define EQOS_MAC_L3L4_CTR_L3SAIM0 OSI_BIT(3)
|
||||
#define EQOS_MAC_L3L4_CTR_L3SAI_SHIFT 3
|
||||
#define EQOS_MAC_L3L4_CTR_L3DAM0 OSI_BIT(4)
|
||||
#define EQOS_MAC_L3L4_CTR_L3DAIM0 OSI_BIT(5)
|
||||
#define EQOS_MAC_L3L4_CTR_L3DAI_SHIFT 5
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHEN0 OSI_BIT(28)
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT 28
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHN0 (OSI_BIT(24) | OSI_BIT(25) | \
|
||||
OSI_BIT(26) | OSI_BIT(27))
|
||||
#define EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT 24
|
||||
#define EQOS_MAC_L3_IP6_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L3SAIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L3DAM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L3DAIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0)
|
||||
#define EQOS_MAC_L3_IP4_SA_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L3SAIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0)
|
||||
#define EQOS_MAC_L3_IP4_DA_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3DAM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L3DAIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0)
|
||||
#define EQOS_MAC_L4_SP_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L4SPM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L4SPIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0)
|
||||
#define EQOS_MAC_L4_DP_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L4DPM0 | \
|
||||
EQOS_MAC_L3L4_CTR_L4DPIM0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
EQOS_MAC_L3L4_CTR_DMCHN0)
|
||||
#define EQOS_MAC_L3L4_CTRL_ALL (EQOS_MAC_L3_IP6_CTRL_CLEAR | \
|
||||
EQOS_MAC_L3_IP4_SA_CTRL_CLEAR | \
|
||||
EQOS_MAC_L3_IP4_DA_CTRL_CLEAR | \
|
||||
EQOS_MAC_L4_SP_CTRL_CLEAR | \
|
||||
EQOS_MAC_L4_DP_CTRL_CLEAR)
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define EQOS_MAC_L4_SP_MASK 0x0000FFFFU
|
||||
#define EQOS_MAC_L4_DP_MASK 0xFFFF0000U
|
||||
#define EQOS_MAC_L4_DP_SHIFT 16
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#define EQOS_MAC_ADDRH_DCS (OSI_BIT(23) | OSI_BIT(22) | \
|
||||
OSI_BIT(21) | OSI_BIT(20) | \
|
||||
OSI_BIT(19) | OSI_BIT(18) | \
|
||||
|
||||
@@ -484,672 +484,105 @@ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_l3l4_filter_read - L3_L4 filter register read.
|
||||
* @brief mgbe_config_l3l4_filters - Config L3L4 filters.
|
||||
*
|
||||
* Algorithm: writes L3_L4 filter register
|
||||
*
|
||||
* @param[in] base: MGBE virtual base address.
|
||||
* @param[in] filter_no: MGBE L3_L4 filter number
|
||||
* @param[in] filter_type: MGBE L3_L4 filter register type.
|
||||
* @param[in] *value: Pointer MGBE L3_L4 filter register value
|
||||
*
|
||||
* @note MAC needs to be out of reset and proper clock configured.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core,
|
||||
nveu32_t filter_no,
|
||||
nveu32_t filter_type,
|
||||
nveu32_t *value)
|
||||
{
|
||||
void *base = osi_core->base;
|
||||
nveu32_t addr = 0;
|
||||
|
||||
/* Program MAC_L3_L4_Address_Control */
|
||||
addr = osi_readla(osi_core,
|
||||
(nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR);
|
||||
|
||||
/* update filter number */
|
||||
addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM);
|
||||
addr |= ((filter_no << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM_SHIFT) &
|
||||
MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM);
|
||||
|
||||
/* update filter type */
|
||||
addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE);
|
||||
addr |= ((filter_type << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE_SHIFT) &
|
||||
MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE);
|
||||
|
||||
/* Set TT field 1 for read */
|
||||
addr |= MGBE_MAC_L3L4_ADDR_CTR_TT;
|
||||
|
||||
/* Set XB bit to initiate write */
|
||||
addr |= MGBE_MAC_L3L4_ADDR_CTR_XB;
|
||||
|
||||
/* Write MGBE_MAC_L3L4_ADDR_CTR */
|
||||
osi_writela(osi_core, addr,
|
||||
(nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR);
|
||||
|
||||
/* Wait untile XB bit reset */
|
||||
if (mgbe_poll_for_l3l4crtl(osi_core) < 0) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"Fail to read L3L4 Address\n",
|
||||
filter_type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read the MGBE_MAC_L3L4_DATA for filter register data */
|
||||
*value = osi_readla(osi_core,
|
||||
(nveu8_t *)base + MGBE_MAC_L3L4_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_update_ip4_addr - configure register for IPV4 address filtering
|
||||
*
|
||||
* Algorithm: This sequence is used to update IPv4 source/destination
|
||||
* Address for L3 layer filtering
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - This sequence is used to configure L3L4 filters for SA and DA Port Number matching.
|
||||
* - Prepare register data using prepare_l3l4_registers().
|
||||
* - Write l3l4 reigsters using mgbe_l3l4_filter_write().
|
||||
* - Return 0 on success.
|
||||
* - Return -1 on any register failure.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] addr: ipv4 address
|
||||
* @param[in] src_dst_addr_match: 0 - source addr otherwise - dest addr
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu8_t addr[],
|
||||
const nveu32_t src_dst_addr_match)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
nve32_t ret = 0;
|
||||
|
||||
if (addr == OSI_NULL) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid address\n",
|
||||
0ULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* validate src_dst_addr_match argument */
|
||||
if ((src_dst_addr_match != OSI_SOURCE_MATCH) &&
|
||||
(src_dst_addr_match != OSI_INV_MATCH)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid src_dst_addr_match value\n",
|
||||
src_dst_addr_match);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = addr[3];
|
||||
temp = (nveu32_t)addr[2] << 8;
|
||||
value |= temp;
|
||||
temp = (nveu32_t)addr[1] << 16;
|
||||
value |= temp;
|
||||
temp = (nveu32_t)addr[0] << 24;
|
||||
value |= temp;
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
ret = mgbe_l3l4_filter_write(osi_core,
|
||||
filter_no,
|
||||
MGBE_MAC_L3_AD0R,
|
||||
value);
|
||||
} else {
|
||||
ret = mgbe_l3l4_filter_write(osi_core,
|
||||
filter_no,
|
||||
MGBE_MAC_L3_AD1R,
|
||||
value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief mgbe_update_ip6_addr - add ipv6 address in register
|
||||
*
|
||||
* Algorithm: This sequence is used to update IPv6 source/destination
|
||||
* Address for L3 layer filtering
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] addr: ipv6 adderss
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t addr[])
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
nve32_t ret = 0;
|
||||
|
||||
if (addr == OSI_NULL) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid address\n",
|
||||
0ULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* update Bits[31:0] of 128-bit IP addr */
|
||||
value = addr[7];
|
||||
temp = (nveu32_t)addr[6] << 16;
|
||||
value |= temp;
|
||||
|
||||
ret = mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3_AD0R, value);
|
||||
if (ret < 0) {
|
||||
/* Write MGBE_MAC_L3_AD0R fail return error */
|
||||
return ret;
|
||||
}
|
||||
/* update Bits[63:32] of 128-bit IP addr */
|
||||
value = addr[5];
|
||||
temp = (nveu32_t)addr[4] << 16;
|
||||
value |= temp;
|
||||
|
||||
ret = mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3_AD1R, value);
|
||||
if (ret < 0) {
|
||||
/* Write MGBE_MAC_L3_AD1R fail return error */
|
||||
return ret;
|
||||
}
|
||||
/* update Bits[95:64] of 128-bit IP addr */
|
||||
value = addr[3];
|
||||
temp = (nveu32_t)addr[2] << 16;
|
||||
value |= temp;
|
||||
|
||||
ret = mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3_AD2R, value);
|
||||
if (ret < 0) {
|
||||
/* Write MGBE_MAC_L3_AD2R fail return error */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* update Bits[127:96] of 128-bit IP addr */
|
||||
value = addr[1];
|
||||
temp = (nveu32_t)addr[0] << 16;
|
||||
value |= temp;
|
||||
|
||||
return mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3_AD3R, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_update_l4_port_no -program source port no
|
||||
*
|
||||
* Algorithm: sequence is used to update Source Port Number for
|
||||
* L4(TCP/UDP) layer filtering.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] port_no: port number
|
||||
* @param[in] src_dst_port_match: 0 - source port, otherwise - dest port
|
||||
* @param[in] filter_no_r: filter index
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 2) osi_core->osd should be populated
|
||||
* 3) DCS bits should be enabled in RXQ to DMA mapping register
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu16_t port_no,
|
||||
const nveu32_t src_dst_port_match)
|
||||
static nve32_t mgbe_config_l3l4_filters(struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t filter_no_r,
|
||||
const struct osi_l3_l4_filter *const l3_l4)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
nveu32_t temp = 0U;
|
||||
nve32_t ret = 0;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
nveu32_t l3_addr0_reg = 0;
|
||||
nveu32_t l3_addr2_reg = 0;
|
||||
nveu32_t l3_addr3_reg = 0;
|
||||
nveu32_t l4_addr_reg = 0;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
nveu32_t l3_addr1_reg = 0;
|
||||
nveu32_t ctr_reg = 0;
|
||||
nveu32_t filter_no = filter_no_r & (OSI_MGBE_MAX_L3_L4_FILTER - 1U);
|
||||
nve32_t err;
|
||||
nve32_t ret = -1;
|
||||
|
||||
if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
prepare_l3l4_registers(osi_core, l3_l4,
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
&l3_addr0_reg,
|
||||
&l3_addr2_reg,
|
||||
&l3_addr3_reg,
|
||||
&l4_addr_reg,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
&l3_addr1_reg,
|
||||
&ctr_reg);
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD0R register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD0R, l3_addr0_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L3_AD0R fail return error */
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
ret = mgbe_l3l4_filter_read(osi_core, filter_no,
|
||||
MGBE_MAC_L4_ADDR, &value);
|
||||
if (ret < 0) {
|
||||
/* Read MGBE_MAC_L4_ADDR fail return error */
|
||||
return ret;
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD2R register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD2R, l3_addr2_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L3_AD2R fail return error */
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
if (src_dst_port_match == OSI_SOURCE_MATCH) {
|
||||
value &= ~MGBE_MAC_L4_ADDR_SP_MASK;
|
||||
value |= ((nveu32_t)port_no & MGBE_MAC_L4_ADDR_SP_MASK);
|
||||
} else {
|
||||
value &= ~MGBE_MAC_L4_ADDR_DP_MASK;
|
||||
temp = port_no;
|
||||
value |= ((temp << MGBE_MAC_L4_ADDR_DP_SHIFT) &
|
||||
MGBE_MAC_L4_ADDR_DP_MASK);
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD3R register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, l3_addr3_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L3_AD3R fail return error */
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
return mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L4_ADDR, value);
|
||||
}
|
||||
/* Update l4 port register MGBE_MAC_L4_ADDR register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, l4_addr_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L4_ADDR fail return error */
|
||||
goto exit_func;
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/**
|
||||
* @brief mgbe_set_dcs - check and update dma routing register
|
||||
*
|
||||
* Algorithm: Check for request for DCS_enable as well as validate chan
|
||||
* number and dcs_enable is set. After validation, this sequence is used
|
||||
* to configure L3((IPv4/IPv6) filters for address matching.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] value: nveu32_t value for caller
|
||||
* @param[in] dma_routing_enable: filter based dma routing enable(1)
|
||||
* @param[in] dma_chan: dma channel for routing based on filter
|
||||
*
|
||||
* @note 1) MAC IP should be out of reset and need to be initialized
|
||||
* as the requirements.
|
||||
* 2) DCS bit of RxQ should be enabled for dynamic channel selection
|
||||
* in filter support
|
||||
*
|
||||
* @retval updated nveu32_t value param
|
||||
*/
|
||||
static inline nveu32_t mgbe_set_dcs(struct osi_core_priv_data *osi_core,
|
||||
nveu32_t value,
|
||||
nveu32_t dma_routing_enable,
|
||||
nveu32_t dma_chan)
|
||||
{
|
||||
nveu32_t temp = value;
|
||||
|
||||
if ((dma_routing_enable == OSI_ENABLE) && (dma_chan <
|
||||
OSI_MGBE_MAX_NUM_CHANS) && (osi_core->dcs_en ==
|
||||
OSI_ENABLE)) {
|
||||
temp |= ((dma_routing_enable <<
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT) &
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0);
|
||||
temp |= ((dma_chan <<
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT) &
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0);
|
||||
/* Update l3 ip addr MGBE_MAC_L3_AD1R register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD1R, l3_addr1_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L3_AD1R fail return error */
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_helper_l3l4_bitmask - helper function to set L3L4
|
||||
* bitmask.
|
||||
*
|
||||
* Algorithm: set bit corresponding to L3l4 filter index
|
||||
*
|
||||
* @param[in] bitmask: bit mask OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] value: 0 - disable otherwise - l3/l4 filter enabled
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
*/
|
||||
static inline void mgbe_helper_l3l4_bitmask(nveu32_t *bitmask,
|
||||
nveu32_t filter_no,
|
||||
nveu32_t value)
|
||||
{
|
||||
nveu32_t temp;
|
||||
|
||||
temp = OSI_ENABLE;
|
||||
temp = temp << filter_no;
|
||||
|
||||
/* check against all bit fields for L3L4 filter enable */
|
||||
if ((value & MGBE_MAC_L3L4_CTRL_ALL) != OSI_DISABLE) {
|
||||
/* Set bit mask for index */
|
||||
*bitmask |= temp;
|
||||
} else {
|
||||
/* Reset bit mask for index */
|
||||
*bitmask &= ~temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_config_l3_filters - config L3 filters.
|
||||
*
|
||||
* Algorithm: Check for DCS_enable as well as validate channel
|
||||
* number and if dcs_enable is set. After validation, code flow
|
||||
* is used to configure L3((IPv4/IPv6) filters resister
|
||||
* for address matching.
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] enb_dis: 1 - enable otherwise - disable L3 filter
|
||||
* @param[in] ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4
|
||||
* @param[in] src_dst_addr_match: 0 - source, otherwise - destination
|
||||
* @param[in] perfect_inverse_match: normal match(0) or inverse map(1)
|
||||
* @param[in] dma_routing_enable: filter based dma routing enable(1)
|
||||
* @param[in] dma_chan: dma channel for routing based on filter
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 2) osi_core->osd should be populated
|
||||
* 3) DCS bit of RxQ should be enabled for dynamic channel selection
|
||||
* in filter support
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t ipv4_ipv6_match,
|
||||
const nveu32_t src_dst_addr_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
nve32_t ret = 0;
|
||||
|
||||
if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
/* validate enb_dis argument */
|
||||
if ((enb_dis != OSI_ENABLE) && (enb_dis != OSI_DISABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid filter_enb_dis value\n",
|
||||
enb_dis);
|
||||
return -1;
|
||||
}
|
||||
/* validate ipv4_ipv6_match argument */
|
||||
if ((ipv4_ipv6_match != OSI_IPV6_MATCH) &&
|
||||
(ipv4_ipv6_match != OSI_IPV4_MATCH)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid ipv4_ipv6_match value\n",
|
||||
ipv4_ipv6_match);
|
||||
return -1;
|
||||
}
|
||||
/* validate src_dst_addr_match argument */
|
||||
if ((src_dst_addr_match != OSI_SOURCE_MATCH) &&
|
||||
(src_dst_addr_match != OSI_INV_MATCH)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid src_dst_addr_match value\n",
|
||||
src_dst_addr_match);
|
||||
return -1;
|
||||
}
|
||||
/* validate perfect_inverse_match argument */
|
||||
if ((perfect_inverse_match != OSI_ENABLE) &&
|
||||
(perfect_inverse_match != OSI_DISABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid perfect_inverse_match value\n",
|
||||
perfect_inverse_match);
|
||||
return -1;
|
||||
}
|
||||
if ((dma_routing_enable == OSI_ENABLE) &&
|
||||
(dma_chan > (OSI_MGBE_MAX_NUM_CHANS - 1U))) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"Wrong DMA channel\n",
|
||||
(nveul64_t)dma_chan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mgbe_l3l4_filter_read(osi_core, filter_no,
|
||||
MGBE_MAC_L3L4_CTR, &value);
|
||||
if (ret < 0) {
|
||||
/* MGBE_MAC_L3L4_CTR read fail return here */
|
||||
return ret;
|
||||
}
|
||||
|
||||
value &= ~MGBE_MAC_L3L4_CTR_L3PEN0;
|
||||
value |= (ipv4_ipv6_match & MGBE_MAC_L3L4_CTR_L3PEN0);
|
||||
|
||||
/* For IPv6 either SA/DA can be checked not both */
|
||||
if (ipv4_ipv6_match == OSI_IPV6_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
/* Enable L3 filters for IPv6 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR;
|
||||
value |= ((MGBE_MAC_L3L4_CTR_L3SAM0) |
|
||||
((perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) &
|
||||
(MGBE_MAC_L3L4_CTR_L3SAM0 |
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0)));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
|
||||
} else {
|
||||
/* Enable L3 filters for IPv6 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR;
|
||||
value |= ((MGBE_MAC_L3L4_CTR_L3DAM0) |
|
||||
((perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) &
|
||||
(MGBE_MAC_L3L4_CTR_L3DAM0 |
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0)));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
}
|
||||
} else {
|
||||
/* Disable L3 filters for IPv6 SOURCE/DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~(MGBE_MAC_L3_IP6_CTRL_CLEAR |
|
||||
MGBE_MAC_L3L4_CTR_L3PEN0);
|
||||
}
|
||||
} else {
|
||||
if (src_dst_addr_match == OSI_SOURCE_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L3 filters for IPv4 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP4_SA_CTRL_CLEAR;
|
||||
value |= ((MGBE_MAC_L3L4_CTR_L3SAM0) |
|
||||
((perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) &
|
||||
(MGBE_MAC_L3L4_CTR_L3SAM0 |
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0)));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
} else {
|
||||
/* Disable L3 filters for IPv4 SOURCE addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP4_SA_CTRL_CLEAR;
|
||||
}
|
||||
} else {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L3 filters for IPv4 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP4_DA_CTRL_CLEAR;
|
||||
value |= ((MGBE_MAC_L3L4_CTR_L3DAM0) |
|
||||
((perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) &
|
||||
(MGBE_MAC_L3L4_CTR_L3DAM0 |
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0)));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
} else {
|
||||
/* Disable L3 filters for IPv4 DESTINATION addr
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L3_IP4_DA_CTRL_CLEAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3L4_CTR, value);
|
||||
if (ret < 0) {
|
||||
/* Write CTR register */
|
||||
err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, ctr_reg);
|
||||
if (err < 0) {
|
||||
/* Write MGBE_MAC_L3L4_CTR fail return error */
|
||||
return ret;
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* Set bit corresponding to filter index if value is non-zero */
|
||||
mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask,
|
||||
filter_no, value);
|
||||
/* success */
|
||||
ret = 0;
|
||||
|
||||
exit_func:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief mgbe_config_l4_filters - Config L4 filters.
|
||||
*
|
||||
* Algorithm: This sequence is used to configure L4(TCP/UDP) filters for
|
||||
* SA and DA Port Number matching
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] filter_no: filter index
|
||||
* @param[in] enb_dis: 1 - enable, otherwise - disable L4 filter
|
||||
* @param[in] tcp_udp_match: 1 - udp, 0 - tcp
|
||||
* @param[in] src_dst_port_match: 0 - source port, otherwise - dest port
|
||||
* @param[in] perfect_inverse_match: normal match(0) or inverse map(1)
|
||||
* @param[in] dma_routing_enable: filter based dma routing enable(1)
|
||||
* @param[in] dma_chan: dma channel for routing based on filter
|
||||
*
|
||||
* @note 1) MAC should be init and started. see osi_start_mac()
|
||||
* 2) osi_core->osd should be populated
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_config_l4_filters(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t filter_no,
|
||||
const nveu32_t enb_dis,
|
||||
const nveu32_t tcp_udp_match,
|
||||
const nveu32_t src_dst_port_match,
|
||||
const nveu32_t perfect_inverse_match,
|
||||
const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan)
|
||||
{
|
||||
nveu32_t value = 0U;
|
||||
nve32_t ret = 0;
|
||||
|
||||
if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"invalid filter index for L3/L4 filter\n",
|
||||
(nveul64_t)filter_no);
|
||||
return -1;
|
||||
}
|
||||
/* validate enb_dis argument */
|
||||
if ((enb_dis != OSI_ENABLE) && (enb_dis != OSI_DISABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid filter_enb_dis value\n",
|
||||
enb_dis);
|
||||
return -1;
|
||||
}
|
||||
/* validate tcp_udp_match argument */
|
||||
if ((tcp_udp_match != OSI_ENABLE) && (tcp_udp_match != OSI_DISABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid tcp_udp_match value\n",
|
||||
tcp_udp_match);
|
||||
return -1;
|
||||
}
|
||||
/* validate src_dst_port_match argument */
|
||||
if ((src_dst_port_match != OSI_SOURCE_MATCH) &&
|
||||
(src_dst_port_match != OSI_INV_MATCH)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid src_dst_port_match value\n",
|
||||
src_dst_port_match);
|
||||
return -1;
|
||||
}
|
||||
/* validate perfect_inverse_match argument */
|
||||
if ((perfect_inverse_match != OSI_ENABLE) &&
|
||||
(perfect_inverse_match != OSI_DISABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid perfect_inverse_match value\n",
|
||||
perfect_inverse_match);
|
||||
return -1;
|
||||
}
|
||||
if ((dma_routing_enable == OSI_ENABLE) &&
|
||||
(dma_chan > (OSI_MGBE_MAX_NUM_CHANS - 1U))) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND,
|
||||
"Wrong DMA channel\n",
|
||||
(nveu32_t)dma_chan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mgbe_l3l4_filter_read(osi_core, filter_no,
|
||||
MGBE_MAC_L3L4_CTR, &value);
|
||||
if (ret < 0) {
|
||||
/* MGBE_MAC_L3L4_CTR read fail return here */
|
||||
return ret;
|
||||
}
|
||||
|
||||
value &= ~MGBE_MAC_L3L4_CTR_L4PEN0;
|
||||
value |= ((tcp_udp_match << 16) & MGBE_MAC_L3L4_CTR_L4PEN0);
|
||||
|
||||
if (src_dst_port_match == OSI_SOURCE_MATCH) {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L4 filters for SOURCE Port No matching */
|
||||
value &= ~MGBE_MAC_L4_SP_CTRL_CLEAR;
|
||||
value |= ((MGBE_MAC_L3L4_CTR_L4SPM0) |
|
||||
((perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT) &
|
||||
(MGBE_MAC_L3L4_CTR_L4SPM0 |
|
||||
MGBE_MAC_L3L4_CTR_L4SPIM0)));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
} else {
|
||||
/* Disable L4 filters for SOURCE Port No matching */
|
||||
value &= ~MGBE_MAC_L4_SP_CTRL_CLEAR;
|
||||
}
|
||||
} else {
|
||||
if (enb_dis == OSI_ENABLE) {
|
||||
/* Enable L4 filters for DESTINATION port No
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR;
|
||||
value |= (((MGBE_MAC_L3L4_CTR_L4DPM0) |
|
||||
(perfect_inverse_match <<
|
||||
MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT)) &
|
||||
(MGBE_MAC_L3L4_CTR_L4DPM0 |
|
||||
MGBE_MAC_L3L4_CTR_L4DPIM0));
|
||||
value |= mgbe_set_dcs(osi_core, value,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
} else {
|
||||
/* Disable L4 filters for DESTINATION port No
|
||||
* matching
|
||||
*/
|
||||
value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mgbe_l3l4_filter_write(osi_core, filter_no,
|
||||
MGBE_MAC_L3L4_CTR, value);
|
||||
if (ret < 0) {
|
||||
/* Write MGBE_MAC_L3L4_CTR fail return error */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set bit corresponding to filter index if value is non-zero */
|
||||
mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask,
|
||||
filter_no, value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_config_vlan_filter_reg - config vlan filter register
|
||||
*
|
||||
@@ -4560,13 +3993,11 @@ void mgbe_init_core_ops(struct core_ops *ops)
|
||||
ops->handle_common_intr = mgbe_handle_common_intr;
|
||||
ops->pad_calibrate = mgbe_pad_calibrate;
|
||||
ops->update_mac_addr_low_high_reg = mgbe_update_mac_addr_low_high_reg;
|
||||
ops->config_l3_filters = mgbe_config_l3_filters;
|
||||
ops->adjust_mactime = mgbe_adjust_mactime;
|
||||
ops->read_mmc = mgbe_read_mmc;
|
||||
ops->write_phy_reg = mgbe_write_phy_reg;
|
||||
ops->read_phy_reg = mgbe_read_phy_reg;
|
||||
ops->get_hw_features = mgbe_get_hw_features;
|
||||
ops->update_ip4_addr = mgbe_update_ip4_addr;
|
||||
ops->read_reg = mgbe_read_reg;
|
||||
ops->write_reg = mgbe_write_reg;
|
||||
ops->set_avb_algorithm = mgbe_set_avb_algorithm;
|
||||
@@ -4581,10 +4012,8 @@ void mgbe_init_core_ops(struct core_ops *ops)
|
||||
ops->macsec_config_mac = mgbe_config_for_macsec;
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
#endif /* MACSEC_SUPPORT */
|
||||
ops->config_l3l4_filters = mgbe_config_l3l4_filters;
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
ops->update_ip6_addr = mgbe_update_ip6_addr;
|
||||
ops->config_l4_filters = mgbe_config_l4_filters;
|
||||
ops->update_l4_port_no = mgbe_update_l4_port_no;
|
||||
ops->config_tx_status = mgbe_config_tx_status;
|
||||
ops->config_rx_crc_check = mgbe_config_rx_crc_check;
|
||||
ops->config_flow_control = mgbe_config_flow_control;
|
||||
|
||||
@@ -78,11 +78,6 @@
|
||||
/** @} */
|
||||
|
||||
#define MGBE_MAX_VLAN_FILTER 32U
|
||||
#define MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT 21
|
||||
#define MGBE_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16)
|
||||
#define MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT 19
|
||||
#define MGBE_MAC_L3_AD2R 0x6
|
||||
#define MGBE_MAC_L3_AD3R 0x7
|
||||
#define MGBE_MAC_RX_FLW_CTRL_RFE OSI_BIT(0)
|
||||
#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU
|
||||
#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U
|
||||
@@ -151,10 +146,6 @@
|
||||
#define MGBE_DMA_CHX_STATUS_RBU OSI_BIT(7)
|
||||
#define MGBE_DMA_CHX_STATUS_FBE OSI_BIT(12)
|
||||
|
||||
#define MGBE_MAC_L4_ADDR 0x1
|
||||
#define MGBE_MAC_L4_ADDR_SP_MASK 0x0000FFFFU
|
||||
#define MGBE_MAC_L4_ADDR_DP_MASK 0xFFFF0000U
|
||||
#define MGBE_MAC_L4_ADDR_DP_SHIFT 16
|
||||
#define MGBE_MAC_LPI_CSR_LPITE OSI_BIT(20)
|
||||
#define MGBE_MAC_LPI_CSR_LPITXA OSI_BIT(19)
|
||||
#define MGBE_MAC_LPI_CSR_PLS OSI_BIT(17)
|
||||
@@ -433,52 +424,16 @@
|
||||
*/
|
||||
#define MGBE_MAC_XB_WAIT 10U
|
||||
#define MGBE_MAC_L3L4_CTR 0x0
|
||||
#define MGBE_MAC_L3_AD0R 0x4
|
||||
#define MGBE_MAC_L3_AD1R 0x5
|
||||
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHEN0 OSI_BIT(31)
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT 31
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHN0 (OSI_BIT(24) | OSI_BIT(25) | \
|
||||
OSI_BIT(26) | OSI_BIT(27))
|
||||
#define MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT 24
|
||||
#define MGBE_MAC_L3L4_CTR_L4DPIM0 OSI_BIT(21)
|
||||
#define MGBE_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20)
|
||||
#define MGBE_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19)
|
||||
#define MGBE_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18)
|
||||
#define MGBE_MAC_L3L4_CTR_L3DAIM0 OSI_BIT(5)
|
||||
#define MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT 5
|
||||
#define MGBE_MAC_L3L4_CTR_L3DAM0 OSI_BIT(4)
|
||||
#define MGBE_MAC_L3L4_CTR_L3SAIM0 OSI_BIT(3)
|
||||
#define MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT 3
|
||||
#define MGBE_MAC_L3L4_CTR_L3SAM0 OSI_BIT(2)
|
||||
#define MGBE_MAC_L3L4_CTR_L3PEN0 OSI_BIT(0)
|
||||
#define MGBE_MAC_L3_IP6_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3SAM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L3DAM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0)
|
||||
#define MGBE_MAC_L3_IP4_SA_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3SAM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L3SAIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0)
|
||||
#define MGBE_MAC_L3_IP4_DA_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3DAM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L3DAIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0)
|
||||
#define MGBE_MAC_L4_SP_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L4SPM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L4SPIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0)
|
||||
#define MGBE_MAC_L4_DP_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L4DPM0 | \
|
||||
MGBE_MAC_L3L4_CTR_L4DPIM0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHEN0 | \
|
||||
MGBE_MAC_L3L4_CTR_DMCHN0)
|
||||
#define MGBE_MAC_L3L4_CTRL_ALL (MGBE_MAC_L3_IP6_CTRL_CLEAR | \
|
||||
MGBE_MAC_L3_IP4_SA_CTRL_CLEAR | \
|
||||
MGBE_MAC_L3_IP4_DA_CTRL_CLEAR | \
|
||||
MGBE_MAC_L4_SP_CTRL_CLEAR | \
|
||||
MGBE_MAC_L4_DP_CTRL_CLEAR)
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#define MGBE_MAC_L3_AD0R 0x4
|
||||
#define MGBE_MAC_L3_AD2R 0x6
|
||||
#define MGBE_MAC_L3_AD3R 0x7
|
||||
#define MGBE_MAC_L4_ADDR 0x1
|
||||
#define MGBE_MAC_L4_ADDR_SP_MASK 0x0000FFFFU
|
||||
#define MGBE_MAC_L4_ADDR_DP_MASK 0xFFFF0000U
|
||||
#define MGBE_MAC_L4_ADDR_DP_SHIFT 16
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -729,158 +729,356 @@ static nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief helper_l4_filter helper function for l4 filtering
|
||||
*
|
||||
* @param[in] osi_core: OSI Core private data structure.
|
||||
* @param[in] l_filter: filter structure
|
||||
* @param[in] type: filter type l3 or l4
|
||||
* @param[in] dma_routing_enable: dma routing enable (1) or disable (0)
|
||||
* @param[in] dma_chan: dma channel
|
||||
*
|
||||
* @pre MAC needs to be out of reset and proper clock configured.
|
||||
* @brief l3l4_find_match - function to find filter match
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
* Algorithm:
|
||||
* - Search through filter list l_core->cfg.l3_l4[] and find for a
|
||||
* match with l3_l4 input data.
|
||||
* - Filter data matches, store the filter index into filter_no.
|
||||
* - Store first found filter index into free_filter_no.
|
||||
* - Return 0 on match.
|
||||
* - Return -1 on failure.
|
||||
*
|
||||
* @retval 0 on Success
|
||||
* @retval -1 on Failure
|
||||
* @param[in] l_core: OSI local core data structure.
|
||||
* @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter)
|
||||
* @param[out] filter_no: pointer to filter index
|
||||
* @param[out] free_filter_no: pointer to free filter index
|
||||
* @param[in] max_filter_no: maximum allowed filter number
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static inline nve32_t helper_l4_filter(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
struct core_ops *ops_p,
|
||||
struct osi_l3_l4_filter *l_filter,
|
||||
nveu32_t type,
|
||||
nveu32_t dma_routing_enable,
|
||||
nveu32_t dma_chan)
|
||||
static nve32_t l3l4_find_match(const struct core_local *const l_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4,
|
||||
nveu32_t *filter_no,
|
||||
nveu32_t *free_filter_no,
|
||||
nveu32_t max_filter_no)
|
||||
{
|
||||
nve32_t ret = 0;
|
||||
nveu32_t i;
|
||||
nve32_t ret = -1;
|
||||
nveu32_t found_free_index = 0;
|
||||
nve32_t filter_size = (nve32_t)sizeof(l3_l4->data);
|
||||
|
||||
ret = ops_p->config_l4_filters(osi_core,
|
||||
l_filter->filter_no,
|
||||
l_filter->filter_enb_dis,
|
||||
type,
|
||||
l_filter->src_dst_addr_match,
|
||||
l_filter->perfect_inverse_match,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
if (ret < 0) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"failed to configure L4 filters\n", 0ULL);
|
||||
return ret;
|
||||
}
|
||||
/* init free index value to invalid value */
|
||||
*free_filter_no = UINT_MAX;
|
||||
|
||||
return ops_p->update_l4_port_no(osi_core,
|
||||
l_filter->filter_no,
|
||||
l_filter->port_no,
|
||||
l_filter->src_dst_addr_match);
|
||||
}
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
for (i = 0; i < max_filter_no; i++) {
|
||||
if (l_core->cfg.l3_l4[i].filter_enb_dis == OSI_FALSE) {
|
||||
/* filter not enabled, save free index */
|
||||
if (found_free_index == 0U) {
|
||||
*free_filter_no = i;
|
||||
found_free_index = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief helper_l3_filter helper function for l3 filtering
|
||||
*
|
||||
* @param[in] osi_core: OSI Core private data structure.
|
||||
* @param[in] l_filter: filter structure
|
||||
* @param[in] type: filter type l3 or l4
|
||||
* @param[in] dma_routing_enable: dma routing enable (1) or disable (0)
|
||||
* @param[in] dma_chan: dma channel
|
||||
*
|
||||
* @pre MAC needs to be out of reset and proper clock configured.
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: No
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @retval 0 on Success
|
||||
* @retval -1 on Failure
|
||||
*/
|
||||
static inline nve32_t helper_l3_filter(
|
||||
struct osi_core_priv_data *const osi_core,
|
||||
struct core_ops *ops_p,
|
||||
struct osi_l3_l4_filter *l_filter,
|
||||
nveu32_t type,
|
||||
nveu32_t dma_routing_enable,
|
||||
nveu32_t dma_chan)
|
||||
{
|
||||
nve32_t ret = 0;
|
||||
if (osi_memcmp(&(l_core->cfg.l3_l4[i].data), &(l3_l4->data),
|
||||
filter_size) != 0) {
|
||||
/* data do not match */
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = ops_p->config_l3_filters(osi_core,
|
||||
l_filter->filter_no,
|
||||
l_filter->filter_enb_dis,
|
||||
type,
|
||||
l_filter->src_dst_addr_match,
|
||||
l_filter->perfect_inverse_match,
|
||||
dma_routing_enable,
|
||||
dma_chan);
|
||||
if (ret < 0) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
|
||||
"failed to configure L3 filters\n", 0ULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (type == OSI_IP6_FILTER) {
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
ret = ops_p->update_ip6_addr(osi_core, l_filter->filter_no,
|
||||
l_filter->ip6_addr);
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
} else if (type == OSI_IP4_FILTER) {
|
||||
ret = ops_p->update_ip4_addr(osi_core, l_filter->filter_no,
|
||||
l_filter->ip4_addr,
|
||||
l_filter->src_dst_addr_match);
|
||||
} else {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"Invalid L3 filter type\n", 0ULL);
|
||||
return -1;
|
||||
/* found a match */
|
||||
ret = 0;
|
||||
*filter_no = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_l3_l4_filter *const l_filter,
|
||||
const nveu32_t type, const nveu32_t dma_routing_enable,
|
||||
const nveu32_t dma_chan, const nveu32_t is_l4_filter)
|
||||
/**
|
||||
* @brief configure_l3l4_filter_helper - helper function for l3l4 configuration
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Validate all the l3_l4 structure parameter.
|
||||
* Return -1 if parameter validation fails.
|
||||
* - 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
|
||||
* l3l4 filter if any of the filter index enabled currently.
|
||||
*
|
||||
* @param[inout] l_core: OSI local core data structure.
|
||||
* @param[in] filter_no: pointer to filter number
|
||||
* @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_helper(struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t filter_no,
|
||||
const struct osi_l3_l4_filter *const l3_l4)
|
||||
{
|
||||
struct core_local *l_core = (struct core_local *)(void *)osi_core;
|
||||
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;
|
||||
|
||||
if ((dma_routing_enable == OSI_ENABLE) &&
|
||||
(osi_core->dcs_en != OSI_ENABLE)) {
|
||||
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"dma routing enabled but dcs disabled in DT\n",
|
||||
0ULL);
|
||||
return ret;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (is_l4_filter == OSI_ENABLE) {
|
||||
/* 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
|
||||
ret = helper_l4_filter(osi_core, l_core->ops_p, l_filter, type,
|
||||
dma_routing_enable, dma_chan);
|
||||
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 */
|
||||
} else {
|
||||
ret = helper_l3_filter(osi_core, l_core->ops_p, l_filter, type,
|
||||
dma_routing_enable, dma_chan);
|
||||
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 */
|
||||
|
||||
ret = l_core->ops_p->config_l3l4_filters(osi_core, filter_no, l3_l4);
|
||||
if (ret < 0) {
|
||||
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID,
|
||||
"L3/L4 helper function failed\n", 0ULL);
|
||||
return ret;
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("Failed to config L3L4 filters: "), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) {
|
||||
cfg_l3_l4 = &(l_core->cfg.l3_l4[filter_no]);
|
||||
if (l3_l4->filter_enb_dis == OSI_TRUE) {
|
||||
/* Store the filter.
|
||||
* osi_memcpy is an internal function and it cannot fail, hence
|
||||
* ignoring return value.
|
||||
*/
|
||||
(void)osi_memcpy(cfg_l3_l4, l3_l4, sizeof(struct osi_l3_l4_filter));
|
||||
OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: ADD: "), (filter_no));
|
||||
|
||||
/* update filter mask bit */
|
||||
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
|
||||
* ignoring return value.
|
||||
*/
|
||||
(void)osi_memset(cfg_l3_l4, 0, sizeof(struct osi_l3_l4_filter));
|
||||
OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND),
|
||||
("L3L4: DELETE: "), (filter_no));
|
||||
|
||||
/* update filter mask bit */
|
||||
osi_core->l3l4_filter_bitmask &= ~(((nveu32_t)1U << filter_no) & 0x1FU);
|
||||
}
|
||||
|
||||
if (osi_core->l3l4_filter_bitmask != 0U) {
|
||||
/* enable l3l4 filter */
|
||||
ret = hw_config_l3_l4_filter_enable(osi_core, OSI_ENABLE);
|
||||
} else {
|
||||
/* disable l3l4 filter */
|
||||
ret = hw_config_l3_l4_filter_enable(osi_core, OSI_DISABLE);
|
||||
}
|
||||
|
||||
exit_func:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#ifdef L3L4_WILDCARD_FILTER
|
||||
/**
|
||||
* @brief l3l4_add_wildcard_filter - function to configure wildcard filter.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Configure wildcard filter with all 4 tuple as 0s using configure_l3l4_filter_helper().
|
||||
*
|
||||
* @param[in] osi_core: OSI Core private data structure.
|
||||
* @param[in] max_filter_no: maximum allowed filter number
|
||||
*
|
||||
* @pre
|
||||
* - MAC should be initialized and started. see osi_start_mac()
|
||||
*/
|
||||
static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core,
|
||||
nveu32_t max_filter_no)
|
||||
{
|
||||
nve32_t err;
|
||||
struct osi_l3_l4_filter *l3l4_filter;
|
||||
struct core_local *l_core = (struct core_local *)(void *)osi_core;
|
||||
|
||||
/* use max filter index to confiture wildcard filter */
|
||||
if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) {
|
||||
/* configure INV filter for IPV4/UDP with DA(0) + SP (0) +
|
||||
* DP (0) with routing not enabled
|
||||
*/
|
||||
l3l4_filter = &(l_core->cfg.l3_l4[max_filter_no]);
|
||||
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.addr_match = OSI_TRUE;
|
||||
l3l4_filter->data.dst.addr_match = OSI_TRUE;
|
||||
|
||||
/* configure wildcard at last filter index */
|
||||
err = configure_l3l4_filter_helper(osi_core, max_filter_no, l3l4_filter);
|
||||
if (err < 0) {
|
||||
/* wildcard config failed */
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_INVALID),
|
||||
("L3L4: Wildcard config failed: "), (max_filter_no));
|
||||
} else {
|
||||
/* wildcard config success */
|
||||
l_core->l3l4_wildcard_filter_configured = OSI_ENABLE;
|
||||
OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_INVALID),
|
||||
("L3L4: Wildcard config success"), (max_filter_no));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* L3L4_WILDCARD_FILTER */
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/**
|
||||
* @brief configure_l3l4_filter - function to configure l3l4 filter.
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - 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().
|
||||
* - For filter disable case,
|
||||
* -> If filter match not found, return 0 to report caller that filter already removed.
|
||||
* -> Otherwise disable filter using configure_l3l4_filter_helper().
|
||||
* - Return -1 if configure_l3l4_filter_helper() fails.
|
||||
* - Return 0 on success.
|
||||
*
|
||||
* @param[in] osi_core: OSI Core private 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(struct osi_core_priv_data *const osi_core,
|
||||
const struct osi_l3_l4_filter *const l3_l4)
|
||||
{
|
||||
nve32_t err;
|
||||
nveu32_t filter_no = 0;
|
||||
nveu32_t free_filter_no = UINT_MAX;
|
||||
const struct core_local *l_core = (struct core_local *)(void *)osi_core;
|
||||
const nveu32_t max_filter_no[2] = {
|
||||
/* max usable filter number is less by 1 for accommodating
|
||||
* wildcard filter at last index.
|
||||
*/
|
||||
EQOS_MAX_L3_L4_FILTER - 1U,
|
||||
OSI_MGBE_MAX_L3_L4_FILTER - 1U,
|
||||
};
|
||||
nve32_t ret = -1;
|
||||
|
||||
/* 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]);
|
||||
|
||||
if (l3_l4->filter_enb_dis == OSI_TRUE) {
|
||||
if (err == 0) {
|
||||
/* duplicate filter request */
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("L3L4: Failed: duplicate filter: "), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* check free index */
|
||||
if (free_filter_no >= max_filter_no[osi_core->mac]) {
|
||||
/* no free entry found */
|
||||
OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("L3L4: Failed: no free filter: "), (free_filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
filter_no = free_filter_no;
|
||||
} else {
|
||||
if (err < 0) {
|
||||
/* no match found */
|
||||
OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("L3L4: delete: no filter match: "), (filter_no));
|
||||
/* filter already deleted, return success */
|
||||
ret = 0;
|
||||
goto exit_func;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#ifdef L3L4_WILDCARD_FILTER
|
||||
/* setup l3l4 wildcard filter for l3l4 */
|
||||
l3l4_add_wildcard_filter(osi_core, max_filter_no[osi_core->mac]);
|
||||
if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) {
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("L3L4: Rejected: wildcard is not enabled: "), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
#endif /* L3L4_WILDCARD_FILTER */
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
|
||||
/* configure l3l4 filter */
|
||||
err = configure_l3l4_filter_helper(osi_core, filter_no, l3_l4);
|
||||
if (err < 0) {
|
||||
/* filter config failed */
|
||||
OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL),
|
||||
("L3L4: configure_l3l4_filter_helper() failed"), (filter_no));
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
/* success */
|
||||
ret = 0;
|
||||
|
||||
exit_func:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1723,16 +1921,23 @@ static void cfg_l3_l4_filter(struct core_local *l_core)
|
||||
nveu32_t i = 0U;
|
||||
|
||||
for (i = 0U; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) {
|
||||
if (l_core->cfg.l3_l4[i].used == OSI_DISABLE) {
|
||||
if (l_core->cfg.l3_l4[i].filter_enb_dis == OSI_FALSE) {
|
||||
/* filter not enabled */
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)osi_l3l4_filter((struct osi_core_priv_data *)(void *)l_core,
|
||||
&l_core->cfg.l3_l4[i].l3l4_filter,
|
||||
l_core->cfg.l3_l4[i].type,
|
||||
l_core->cfg.l3_l4[i].dma_routing_enable,
|
||||
l_core->cfg.l3_l4[i].dma_chan,
|
||||
l_core->cfg.l3_l4[i].is_l4_filter);
|
||||
(void)configure_l3l4_filter_helper(
|
||||
(struct osi_core_priv_data *)(void *)l_core,
|
||||
i, &l_core->cfg.l3_l4[i]);
|
||||
|
||||
#ifdef L3L4_WILDCARD_FILTER
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
if (i == (OSI_MGBE_MAX_L3_L4_FILTER - 1U)) {
|
||||
/* last filter supposed to be wildcard filter */
|
||||
l_core->l3l4_wildcard_filter_configured = OSI_ENABLE;
|
||||
}
|
||||
#endif /* L3L4_WILDCARD_FILTER */
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1856,27 +2061,6 @@ static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core)
|
||||
}
|
||||
}
|
||||
|
||||
static void store_l3l4_filter(struct osi_core_priv_data *osi_core,
|
||||
struct osi_l3_l4_filter *l3l4_filter,
|
||||
nveu32_t type, nveu32_t dma_routing_enable,
|
||||
nveu32_t dma_chan, nveu32_t is_l4_filter)
|
||||
{
|
||||
struct core_local *l_core = (struct core_local *)(void *)osi_core;
|
||||
struct l3_l4_filters *l3_l4 = &l_core->cfg.l3_l4[l3l4_filter->filter_no];
|
||||
|
||||
if (l3l4_filter->filter_enb_dis == OSI_ENABLE) {
|
||||
l3_l4->type = type;
|
||||
l3_l4->dma_routing_enable = dma_routing_enable;
|
||||
l3_l4->dma_chan = dma_chan;
|
||||
l3_l4->is_l4_filter = is_l4_filter;
|
||||
(void)osi_memcpy(&l3_l4->l3l4_filter, l3l4_filter,
|
||||
sizeof(struct osi_l3_l4_filter));
|
||||
l3_l4->used = OSI_ENABLE;
|
||||
} else {
|
||||
l3_l4->used = OSI_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
static void store_l2_filter(struct osi_core_priv_data *osi_core,
|
||||
struct osi_filter *filter)
|
||||
{
|
||||
@@ -2081,16 +2265,10 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core,
|
||||
|
||||
switch (data->cmd) {
|
||||
case OSI_CMD_L3L4_FILTER:
|
||||
ret = osi_l3l4_filter(osi_core, &data->l3l4_filter,
|
||||
data->arg1_u32, data->arg2_u32,
|
||||
data->arg3_u32, data->arg4_u32);
|
||||
ret = configure_l3l4_filter(osi_core, &data->l3l4_filter);
|
||||
if (ret == 0) {
|
||||
store_l3l4_filter(osi_core, &data->l3l4_filter,
|
||||
data->arg1_u32, data->arg2_u32,
|
||||
data->arg3_u32, data->arg4_u32);
|
||||
l_core->cfg.flags |= DYNAMIC_CFG_L3_L4;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
|
||||
Reference in New Issue
Block a user