net/ixgbe: restore ether type filter
Add support for restoring ether type filter in SW. Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com> Signed-off-by: Wei Zhao <wei.zhao1@intel.com> Acked-by: Beilei Xing <beilei.xing@intel.com> Acked-by: Wei Dai <wei.dai@intel.com>
This commit is contained in:
parent
e6a410c268
commit
a51f64eda3
@ -6473,47 +6473,6 @@ ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
@ -6525,6 +6484,7 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
|
||||
uint32_t etqf = 0;
|
||||
uint32_t etqs = 0;
|
||||
int ret;
|
||||
struct ixgbe_ethertype_filter ethertype_filter;
|
||||
|
||||
if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM)
|
||||
return -EINVAL;
|
||||
@ -6558,18 +6518,22 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ethertype_filter.ethertype = filter->ether_type;
|
||||
ethertype_filter.etqf = etqf;
|
||||
ethertype_filter.etqs = etqs;
|
||||
ret = ixgbe_ethertype_filter_insert(filter_info,
|
||||
ðertype_filter);
|
||||
if (ret < 0) {
|
||||
PMD_DRV_LOG(ERR, "ethertype filters are full.");
|
||||
return -ENOSPC;
|
||||
}
|
||||
} else {
|
||||
ret = ixgbe_ethertype_filter_remove(filter_info, (uint8_t)ret);
|
||||
if (ret < 0)
|
||||
@ -8499,10 +8463,31 @@ ixgbe_ntuple_filter_restore(struct rte_eth_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* restore ethernet type filter */
|
||||
static inline void
|
||||
ixgbe_ethertype_filter_restore(struct rte_eth_dev *dev)
|
||||
{
|
||||
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);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
|
||||
if (filter_info->ethertype_mask & (1 << i)) {
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQF(i),
|
||||
filter_info->ethertype_filters[i].etqf);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_ETQS(i),
|
||||
filter_info->ethertype_filters[i].etqs);
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ixgbe_filter_restore(struct rte_eth_dev *dev)
|
||||
{
|
||||
ixgbe_ntuple_filter_restore(dev);
|
||||
ixgbe_ethertype_filter_restore(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -275,13 +275,19 @@ struct ixgbe_5tuple_filter {
|
||||
(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, (sizeof(uint32_t) * NBBY)) / \
|
||||
(sizeof(uint32_t) * NBBY))
|
||||
|
||||
struct ixgbe_ethertype_filter {
|
||||
uint16_t ethertype;
|
||||
uint32_t etqf;
|
||||
uint32_t etqs;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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];
|
||||
struct ixgbe_ethertype_filter ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
|
||||
/* Bit mask for every used 5tuple filter */
|
||||
uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
|
||||
struct ixgbe_5tuple_filter_list fivetuple_list;
|
||||
@ -536,4 +542,53 @@ int ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev,
|
||||
int ixgbe_disable_sec_tx_path_generic(struct ixgbe_hw *hw);
|
||||
|
||||
int ixgbe_enable_sec_tx_path_generic(struct ixgbe_hw *hw);
|
||||
|
||||
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 == ethertype &&
|
||||
(filter_info->ethertype_mask & (1 << i)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ixgbe_ethertype_filter_insert(struct ixgbe_filter_info *filter_info,
|
||||
struct ixgbe_ethertype_filter *ethertype_filter)
|
||||
{
|
||||
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 =
|
||||
ethertype_filter->ethertype;
|
||||
filter_info->ethertype_filters[i].etqf =
|
||||
ethertype_filter->etqf;
|
||||
filter_info->ethertype_filters[i].etqs =
|
||||
ethertype_filter->etqs;
|
||||
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].ethertype = 0;
|
||||
filter_info->ethertype_filters[idx].etqf = 0;
|
||||
filter_info->ethertype_filters[idx].etqs = 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
#endif /* _IXGBE_ETHDEV_H_ */
|
||||
|
@ -178,6 +178,7 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev)
|
||||
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
|
||||
uint16_t vf_num;
|
||||
int i;
|
||||
struct ixgbe_ethertype_filter ethertype_filter;
|
||||
|
||||
if (!hw->mac.ops.set_ethertype_anti_spoofing) {
|
||||
RTE_LOG(INFO, PMD, "ether type anti-spoofing is not"
|
||||
@ -185,16 +186,22 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev)
|
||||
return;
|
||||
}
|
||||
|
||||
/* occupy an entity of ether type filter */
|
||||
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] =
|
||||
IXGBE_ETHERTYPE_FLOW_CTRL;
|
||||
break;
|
||||
}
|
||||
i = ixgbe_ethertype_filter_lookup(filter_info,
|
||||
IXGBE_ETHERTYPE_FLOW_CTRL);
|
||||
if (i >= 0) {
|
||||
RTE_LOG(ERR, PMD, "A ether type filter"
|
||||
" entity for flow control already exists!\n");
|
||||
return;
|
||||
}
|
||||
if (i == IXGBE_MAX_ETQF_FILTERS) {
|
||||
|
||||
ethertype_filter.ethertype = IXGBE_ETHERTYPE_FLOW_CTRL;
|
||||
ethertype_filter.etqf = IXGBE_ETQF_FILTER_EN |
|
||||
IXGBE_ETQF_TX_ANTISPOOF |
|
||||
IXGBE_ETHERTYPE_FLOW_CTRL;
|
||||
ethertype_filter.etqs = 0;
|
||||
i = ixgbe_ethertype_filter_insert(filter_info,
|
||||
ðertype_filter);
|
||||
if (i < 0) {
|
||||
RTE_LOG(ERR, PMD, "Cannot find an unused ether type filter"
|
||||
" entity for flow control.\n");
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user