ixgbe: use generic filter control for ethertype filter
This patch removes old functions which deal with ethertype filter in ixgbe driver. It also defines ixgbe_dev_filter_ctrl which is binding to filter_ctrl API, and ethertype filter can be dealt with through this new entrance. Signed-off-by: Jingjing Wu <jingjing.wu@intel.com> Acked-by: Helin Zhang <helin.zhang@intel.com>
This commit is contained in:
parent
dd5c2dd7e5
commit
748198ae82
@ -231,12 +231,6 @@ static int ixgbe_add_syn_filter(struct rte_eth_dev *dev,
|
||||
static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev);
|
||||
static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,
|
||||
struct rte_syn_filter *filter, uint16_t *rx_queue);
|
||||
static int ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
|
||||
struct rte_ethertype_filter *filter, uint16_t rx_queue);
|
||||
static int ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev,
|
||||
uint16_t index);
|
||||
static int ixgbe_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
|
||||
struct rte_ethertype_filter *filter, uint16_t *rx_queue);
|
||||
static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
|
||||
struct rte_5tuple_filter *filter, uint16_t rx_queue);
|
||||
static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
|
||||
@ -245,6 +239,18 @@ static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
|
||||
struct rte_5tuple_filter *filter, uint16_t *rx_queue);
|
||||
|
||||
static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
|
||||
static int ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
|
||||
struct rte_eth_ethertype_filter *filter,
|
||||
bool add);
|
||||
static int ixgbe_ethertype_filter_handle(struct rte_eth_dev *dev,
|
||||
enum rte_filter_op filter_op,
|
||||
void *arg);
|
||||
static int ixgbe_get_ethertype_filter(struct rte_eth_dev *dev,
|
||||
struct rte_eth_ethertype_filter *filter);
|
||||
static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
|
||||
enum rte_filter_type filter_type,
|
||||
enum rte_filter_op filter_op,
|
||||
void *arg);
|
||||
|
||||
/*
|
||||
* Define VF Stats MACRO for Non "cleared on read" register
|
||||
@ -380,12 +386,10 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
|
||||
.add_syn_filter = ixgbe_add_syn_filter,
|
||||
.remove_syn_filter = ixgbe_remove_syn_filter,
|
||||
.get_syn_filter = ixgbe_get_syn_filter,
|
||||
.add_ethertype_filter = ixgbe_add_ethertype_filter,
|
||||
.remove_ethertype_filter = ixgbe_remove_ethertype_filter,
|
||||
.get_ethertype_filter = ixgbe_get_ethertype_filter,
|
||||
.add_5tuple_filter = ixgbe_add_5tuple_filter,
|
||||
.remove_5tuple_filter = ixgbe_remove_5tuple_filter,
|
||||
.get_5tuple_filter = ixgbe_get_5tuple_filter,
|
||||
.filter_ctrl = ixgbe_dev_filter_ctrl,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -3774,125 +3778,6 @@ ixgbe_get_syn_filter(struct rte_eth_dev *dev,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* add an ethertype filter
|
||||
*
|
||||
* @param
|
||||
* dev: Pointer to struct rte_eth_dev.
|
||||
* index: the index the filter allocates.
|
||||
* filter: ponter to the filter that will be added.
|
||||
* rx_queue: the queue id the filter assigned to.
|
||||
*
|
||||
* @return
|
||||
* - On success, zero.
|
||||
* - On failure, a negative value.
|
||||
*/
|
||||
static int
|
||||
ixgbe_add_ethertype_filter(struct rte_eth_dev *dev,
|
||||
uint16_t index, struct rte_ethertype_filter *filter,
|
||||
uint16_t rx_queue)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
uint32_t etqf, etqs = 0;
|
||||
|
||||
if (hw->mac.type != ixgbe_mac_82599EB)
|
||||
return -ENOSYS;
|
||||
|
||||
if (index >= IXGBE_MAX_ETQF_FILTERS ||
|
||||
rx_queue >= IXGBE_MAX_RX_QUEUE_NUM)
|
||||
return -EINVAL;
|
||||
|
||||
etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index));
|
||||
if (etqf & IXGBE_ETQF_FILTER_EN)
|
||||
return -EINVAL; /* filter index is in use. */
|
||||
|
||||
etqf = 0;
|
||||
etqf |= IXGBE_ETQF_FILTER_EN;
|
||||
etqf |= (uint32_t)filter->ethertype;
|
||||
|
||||
if (filter->priority_en) {
|
||||
if (filter->priority > IXGBE_ETQF_MAX_PRI)
|
||||
return -EINVAL;
|
||||
etqf |= (uint32_t)((filter->priority << IXGBE_ETQF_SHIFT) & IXGBE_ETQF_UP);
|
||||
etqf |= IXGBE_ETQF_UP_EN;
|
||||
}
|
||||
etqs |= (uint32_t)((rx_queue << IXGBE_ETQS_RX_QUEUE_SHIFT) & IXGBE_ETQS_RX_QUEUE);
|
||||
etqs |= IXGBE_ETQS_QUEUE_EN;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), etqf);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), etqs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove an ethertype filter
|
||||
*
|
||||
* @param
|
||||
* dev: Pointer to struct rte_eth_dev.
|
||||
* index: the index the filter allocates.
|
||||
*
|
||||
* @return
|
||||
* - On success, zero.
|
||||
* - On failure, a negative value.
|
||||
*/
|
||||
static int
|
||||
ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev,
|
||||
uint16_t index)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
|
||||
if (hw->mac.type != ixgbe_mac_82599EB)
|
||||
return -ENOSYS;
|
||||
|
||||
if (index >= IXGBE_MAX_ETQF_FILTERS)
|
||||
return -EINVAL;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get an ethertype filter
|
||||
*
|
||||
* @param
|
||||
* dev: Pointer to struct rte_eth_dev.
|
||||
* index: the index the filter allocates.
|
||||
* filter: ponter to the filter that will be gotten.
|
||||
* *rx_queue: the ponited of the queue id the filter assigned to.
|
||||
*
|
||||
* @return
|
||||
* - On success, zero.
|
||||
* - On failure, a negative value.
|
||||
*/
|
||||
static int
|
||||
ixgbe_get_ethertype_filter(struct rte_eth_dev *dev,
|
||||
uint16_t index, struct rte_ethertype_filter *filter,
|
||||
uint16_t *rx_queue)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
uint32_t etqf, etqs;
|
||||
|
||||
if (hw->mac.type != ixgbe_mac_82599EB)
|
||||
return -ENOSYS;
|
||||
|
||||
if (index >= IXGBE_MAX_ETQF_FILTERS)
|
||||
return -EINVAL;
|
||||
|
||||
etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index));
|
||||
etqs = IXGBE_READ_REG(hw, IXGBE_ETQS(index));
|
||||
if (etqf & IXGBE_ETQF_FILTER_EN) {
|
||||
filter->ethertype = etqf & IXGBE_ETQF_ETHERTYPE;
|
||||
filter->priority_en = (etqf & IXGBE_ETQF_UP_EN) ? 1 : 0;
|
||||
if (filter->priority_en)
|
||||
filter->priority = (etqf & IXGBE_ETQF_UP) >> 16;
|
||||
*rx_queue = (etqs & IXGBE_ETQS_RX_QUEUE) >> IXGBE_ETQS_RX_QUEUE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline enum ixgbe_5tuple_protocol
|
||||
convert_protocol_type(uint8_t protocol_value)
|
||||
{
|
||||
@ -4119,6 +4004,219 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAC_TYPE_FILTER_SUP(type) do {\
|
||||
if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\
|
||||
(type) != ixgbe_mac_X550)\
|
||||
return -ENOTSUP;\
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,
|
||||
uint16_t ethertype)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
|
||||
if (filter_info->ethertype_filters[i] == ethertype &&
|
||||
(filter_info->ethertype_mask & (1 << i)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ixgbe_ethertype_filter_insert(struct ixgbe_filter_info *filter_info,
|
||||
uint16_t ethertype)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
|
||||
if (!(filter_info->ethertype_mask & (1 << i))) {
|
||||
filter_info->ethertype_mask |= 1 << i;
|
||||
filter_info->ethertype_filters[i] = ethertype;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ixgbe_ethertype_filter_remove(struct ixgbe_filter_info *filter_info,
|
||||
uint8_t idx)
|
||||
{
|
||||
if (idx >= IXGBE_MAX_ETQF_FILTERS)
|
||||
return -1;
|
||||
filter_info->ethertype_mask &= ~(1 << idx);
|
||||
filter_info->ethertype_filters[idx] = 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int
|
||||
ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
|
||||
struct rte_eth_ethertype_filter *filter,
|
||||
bool add)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
struct ixgbe_filter_info *filter_info =
|
||||
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
|
||||
uint32_t etqf = 0;
|
||||
uint32_t etqs = 0;
|
||||
int ret;
|
||||
|
||||
if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM)
|
||||
return -EINVAL;
|
||||
|
||||
if (filter->ether_type == ETHER_TYPE_IPv4 ||
|
||||
filter->ether_type == ETHER_TYPE_IPv6) {
|
||||
PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in"
|
||||
" ethertype filter.", filter->ether_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
|
||||
PMD_DRV_LOG(ERR, "mac compare is unsupported.");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
|
||||
PMD_DRV_LOG(ERR, "drop option is unsupported.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ixgbe_ethertype_filter_lookup(filter_info, filter->ether_type);
|
||||
if (ret >= 0 && add) {
|
||||
PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter exists.",
|
||||
filter->ether_type);
|
||||
return -EEXIST;
|
||||
}
|
||||
if (ret < 0 && !add) {
|
||||
PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter doesn't exist.",
|
||||
filter->ether_type);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (add) {
|
||||
ret = ixgbe_ethertype_filter_insert(filter_info,
|
||||
filter->ether_type);
|
||||
if (ret < 0) {
|
||||
PMD_DRV_LOG(ERR, "ethertype filters are full.");
|
||||
return -ENOSYS;
|
||||
}
|
||||
etqf = IXGBE_ETQF_FILTER_EN;
|
||||
etqf |= (uint32_t)filter->ether_type;
|
||||
etqs |= (uint32_t)((filter->queue <<
|
||||
IXGBE_ETQS_RX_QUEUE_SHIFT) &
|
||||
IXGBE_ETQS_RX_QUEUE);
|
||||
etqs |= IXGBE_ETQS_QUEUE_EN;
|
||||
} else {
|
||||
ret = ixgbe_ethertype_filter_remove(filter_info, (uint8_t)ret);
|
||||
if (ret < 0)
|
||||
return -ENOSYS;
|
||||
}
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQF(ret), etqf);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQS(ret), etqs);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ixgbe_get_ethertype_filter(struct rte_eth_dev *dev,
|
||||
struct rte_eth_ethertype_filter *filter)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
struct ixgbe_filter_info *filter_info =
|
||||
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
|
||||
uint32_t etqf, etqs;
|
||||
int ret;
|
||||
|
||||
ret = ixgbe_ethertype_filter_lookup(filter_info, filter->ether_type);
|
||||
if (ret < 0) {
|
||||
PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter doesn't exist.",
|
||||
filter->ether_type);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(ret));
|
||||
if (etqf & IXGBE_ETQF_FILTER_EN) {
|
||||
etqs = IXGBE_READ_REG(hw, IXGBE_ETQS(ret));
|
||||
filter->ether_type = etqf & IXGBE_ETQF_ETHERTYPE;
|
||||
filter->flags = 0;
|
||||
filter->queue = (etqs & IXGBE_ETQS_RX_QUEUE) >>
|
||||
IXGBE_ETQS_RX_QUEUE_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* ixgbe_ethertype_filter_handle - Handle operations for ethertype filter.
|
||||
* @dev: pointer to rte_eth_dev structure
|
||||
* @filter_op:operation will be taken.
|
||||
* @arg: a pointer to specific structure corresponding to the filter_op
|
||||
*/
|
||||
static int
|
||||
ixgbe_ethertype_filter_handle(struct rte_eth_dev *dev,
|
||||
enum rte_filter_op filter_op,
|
||||
void *arg)
|
||||
{
|
||||
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
int ret;
|
||||
|
||||
MAC_TYPE_FILTER_SUP(hw->mac.type);
|
||||
|
||||
if (filter_op == RTE_ETH_FILTER_NOP)
|
||||
return 0;
|
||||
|
||||
if (arg == NULL) {
|
||||
PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
|
||||
filter_op);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (filter_op) {
|
||||
case RTE_ETH_FILTER_ADD:
|
||||
ret = ixgbe_add_del_ethertype_filter(dev,
|
||||
(struct rte_eth_ethertype_filter *)arg,
|
||||
TRUE);
|
||||
break;
|
||||
case RTE_ETH_FILTER_DELETE:
|
||||
ret = ixgbe_add_del_ethertype_filter(dev,
|
||||
(struct rte_eth_ethertype_filter *)arg,
|
||||
FALSE);
|
||||
break;
|
||||
case RTE_ETH_FILTER_GET:
|
||||
ret = ixgbe_get_ethertype_filter(dev,
|
||||
(struct rte_eth_ethertype_filter *)arg);
|
||||
break;
|
||||
default:
|
||||
PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
|
||||
enum rte_filter_type filter_type,
|
||||
enum rte_filter_op filter_op,
|
||||
void *arg)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (filter_type) {
|
||||
case RTE_ETH_FILTER_ETHERTYPE:
|
||||
ret = ixgbe_ethertype_filter_handle(dev, filter_op, arg);
|
||||
break;
|
||||
default:
|
||||
PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
|
||||
filter_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct rte_driver rte_ixgbe_driver = {
|
||||
.type = PMD_PDEV,
|
||||
.init = rte_ixgbe_pmd_init,
|
||||
|
@ -162,6 +162,15 @@ struct ixgbe_vf_info {
|
||||
uint8_t api_version;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store filters' info.
|
||||
*/
|
||||
struct ixgbe_filter_info {
|
||||
uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
|
||||
/* store used ethertype filters*/
|
||||
uint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to store private data for each driver instance (for each port).
|
||||
*/
|
||||
@ -180,6 +189,7 @@ struct ixgbe_adapter {
|
||||
#ifdef RTE_NIC_BYPASS
|
||||
struct ixgbe_bypass_info bps;
|
||||
#endif /* RTE_NIC_BYPASS */
|
||||
struct ixgbe_filter_info filter;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -225,6 +235,9 @@ enum ixgbe_5tuple_protocol {
|
||||
#define IXGBE_DEV_PRIVATE_TO_UTA(adapter) \
|
||||
(&((struct ixgbe_adapter *)adapter)->uta_info)
|
||||
|
||||
#define IXGBE_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
|
||||
(&((struct ixgbe_adapter *)adapter)->filter)
|
||||
|
||||
/*
|
||||
* RX/TX function prototypes
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user