Commit cac2a27c authored by Henry Tieman's avatar Henry Tieman Committed by Jeff Kirsher

ice: Support IPv4 Flow Director filters

Support the addition and deletion of IPv4 filters.

Supported fields are: src-ip, dst-ip, src-port, and dst-port
Supported flow-types are: tcp4, udp4, sctp4, ip4

Example usage:

ethtool -N eth0 flow-type tcp4 src-ip 192.168.0.55 dst-ip 172.16.0.55 \
src-port 16 dst-port 12 action 32
Signed-off-by: default avatarHenry Tieman <henry.w.tieman@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 4ab95646
......@@ -96,6 +96,7 @@ extern const char ice_drv_ver[];
#define ICE_TX_DESC(R, i) (&(((struct ice_tx_desc *)((R)->desc))[i]))
#define ICE_RX_DESC(R, i) (&(((union ice_32b_rx_flex_desc *)((R)->desc))[i]))
#define ICE_TX_CTX_DESC(R, i) (&(((struct ice_tx_ctx_desc *)((R)->desc))[i]))
#define ICE_TX_FDIRDESC(R, i) (&(((struct ice_fltr_desc *)((R)->desc))[i]))
/* Macro for each VSI in a PF */
#define ice_for_each_vsi(pf, i) \
......@@ -216,6 +217,7 @@ enum ice_state {
__ICE_CFG_BUSY,
__ICE_SERVICE_SCHED,
__ICE_SERVICE_DIS,
__ICE_FD_FLUSH_REQ,
__ICE_OICR_INTR_DIS, /* Global OICR interrupt disabled */
__ICE_MDD_VF_PRINT_PENDING, /* set when MDD event handle */
__ICE_VF_RESETS_DISABLED, /* disable resets during ice_remove */
......@@ -557,6 +559,8 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
const char *ice_stat_str(enum ice_status stat_err);
const char *ice_aq_str(enum ice_aq_err aq_err);
void ice_vsi_manage_fdir(struct ice_vsi *vsi, bool ena);
int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd);
int ice_del_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd);
int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd);
int
ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
......
......@@ -2537,6 +2537,10 @@ static int ice_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
struct ice_vsi *vsi = np->vsi;
switch (cmd->cmd) {
case ETHTOOL_SRXCLSRLINS:
return ice_add_fdir_ethtool(vsi, cmd);
case ETHTOOL_SRXCLSRLDEL:
return ice_del_fdir_ethtool(vsi, cmd);
case ETHTOOL_SRXFH:
return ice_set_rss_hash_opt(vsi, cmd);
default:
......
This diff is collapsed.
......@@ -4,11 +4,70 @@
#ifndef _ICE_FDIR_H_
#define _ICE_FDIR_H_
#define ICE_FDIR_TUN_PKT_OFF 50
#define ICE_FDIR_MAX_RAW_PKT_SIZE (512 + ICE_FDIR_TUN_PKT_OFF)
/* macros for offsets into packets for flow director programming */
#define ICE_IPV4_SRC_ADDR_OFFSET 26
#define ICE_IPV4_DST_ADDR_OFFSET 30
#define ICE_IPV4_TCP_SRC_PORT_OFFSET 34
#define ICE_IPV4_TCP_DST_PORT_OFFSET 36
#define ICE_IPV4_UDP_SRC_PORT_OFFSET 34
#define ICE_IPV4_UDP_DST_PORT_OFFSET 36
#define ICE_IPV4_SCTP_SRC_PORT_OFFSET 34
#define ICE_IPV4_SCTP_DST_PORT_OFFSET 36
#define ICE_IPV4_PROTO_OFFSET 23
#define ICE_IPV6_SRC_ADDR_OFFSET 22
#define ICE_IPV6_DST_ADDR_OFFSET 38
#define ICE_IPV6_TCP_SRC_PORT_OFFSET 54
#define ICE_IPV6_TCP_DST_PORT_OFFSET 56
#define ICE_IPV6_UDP_SRC_PORT_OFFSET 54
#define ICE_IPV6_UDP_DST_PORT_OFFSET 56
#define ICE_IPV6_SCTP_SRC_PORT_OFFSET 54
#define ICE_IPV6_SCTP_DST_PORT_OFFSET 56
/* IP v4 has 2 flag bits that enable fragment processing: DF and MF. DF
* requests that the packet not be fragmented. MF indicates that a packet has
* been fragmented.
*/
#define ICE_FDIR_IPV4_PKT_FLAG_DF 0x20
enum ice_fltr_prgm_desc_dest {
ICE_FLTR_PRGM_DESC_DEST_DROP_PKT,
ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX,
};
enum ice_fltr_prgm_desc_fd_status {
ICE_FLTR_PRGM_DESC_FD_STATUS_NONE,
ICE_FLTR_PRGM_DESC_FD_STATUS_FD_ID,
};
/* Flow Director (FD) Filter Programming descriptor */
struct ice_fd_fltr_desc_ctx {
u32 fdid;
u16 qindex;
u16 cnt_index;
u16 fd_vsi;
u16 flex_val;
u8 comp_q;
u8 comp_report;
u8 fd_space;
u8 cnt_ena;
u8 evict_ena;
u8 toq;
u8 toq_prio;
u8 dpu_recipe;
u8 drop;
u8 flex_prio;
u8 flex_mdid;
u8 dtype;
u8 pcmd;
u8 desc_prof_prio;
u8 desc_prof;
u8 swap;
u8 fdid_prio;
u8 fdid_mdid;
};
struct ice_fdir_v4 {
__be32 dst_ip;
__be32 src_ip;
......@@ -47,13 +106,33 @@ struct ice_fdir_fltr {
u32 fltr_id;
};
/* Dummy packet filter definition structure */
struct ice_fdir_base_pkt {
enum ice_fltr_ptype flow;
u16 pkt_len;
const u8 *pkt;
u16 tun_pkt_len;
const u8 *tun_pkt;
};
enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id);
enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id);
enum ice_status
ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr);
enum ice_status
ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr);
void
ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
struct ice_fltr_desc *fdesc, bool add);
enum ice_status
ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
u8 *pkt, bool frag, bool tun);
int ice_get_fdir_cnt_all(struct ice_hw *hw);
bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input);
bool ice_fdir_has_frag(enum ice_fltr_ptype flow);
struct ice_fdir_fltr *
ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx);
void
ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add);
void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input);
#endif /* _ICE_FDIR_H_ */
......@@ -1632,6 +1632,34 @@ ice_find_free_tunnel_entry(struct ice_hw *hw, enum ice_tunnel_type type,
return false;
}
/**
* ice_get_open_tunnel_port - retrieve an open tunnel port
* @hw: pointer to the HW structure
* @type: tunnel type (TNL_ALL will return any open port)
* @port: returns open port
*/
bool
ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type,
u16 *port)
{
bool res = false;
u16 i;
mutex_lock(&hw->tnl_lock);
for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++)
if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].in_use &&
(type == TNL_ALL || hw->tnl.tbl[i].type == type)) {
*port = hw->tnl.tbl[i].port;
res = true;
break;
}
mutex_unlock(&hw->tnl_lock);
return res;
}
/**
* ice_create_tunnel
* @hw: pointer to the HW structure
......@@ -2332,6 +2360,12 @@ ice_find_prof_id(struct ice_hw *hw, enum ice_block blk,
u16 off;
u8 i;
/* For FD, we don't want to re-use a existed profile with the same
* field vector and mask. This will cause rule interference.
*/
if (blk == ICE_BLK_FD)
return ICE_ERR_DOES_NOT_EXIST;
for (i = 0; i < (u8)es->count; i++) {
off = i * es->fvw;
......
......@@ -18,6 +18,9 @@
#define ICE_PKG_CNT 4
bool
ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type,
u16 *port);
enum ice_status
ice_create_tunnel(struct ice_hw *hw, enum ice_tunnel_type type, u16 port);
enum ice_status ice_destroy_tunnel(struct ice_hw *hw, u16 port, bool all);
......
......@@ -290,6 +290,9 @@
#define GL_PWR_MODE_CTL 0x000B820C
#define GL_PWR_MODE_CTL_CAR_MAX_BW_S 30
#define GL_PWR_MODE_CTL_CAR_MAX_BW_M ICE_M(0x3, 30)
#define GLQF_FD_CNT 0x00460018
#define GLQF_FD_CNT_FD_BCNT_S 16
#define GLQF_FD_CNT_FD_BCNT_M ICE_M(0x7FFF, 16)
#define GLQF_FD_SIZE 0x00460010
#define GLQF_FD_SIZE_FD_GSIZE_S 0
#define GLQF_FD_SIZE_FD_GSIZE_M ICE_M(0x7FFF, 0)
......@@ -355,6 +358,9 @@
#define GLV_TEPC(_VSI) (0x00312000 + ((_VSI) * 4))
#define GLV_UPRCL(_i) (0x003B2000 + ((_i) * 8))
#define GLV_UPTCL(_i) (0x0030A000 + ((_i) * 8))
#define VSIQF_FD_CNT(_VSI) (0x00464000 + ((_VSI) * 4))
#define VSIQF_FD_CNT_FD_GCNT_S 0
#define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0)
#define VSIQF_HKEY_MAX_INDEX 12
#define VSIQF_HLUT_MAX_INDEX 15
#define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4))
......
......@@ -40,6 +40,104 @@ union ice_32byte_rx_desc {
} wb; /* writeback */
};
struct ice_fltr_desc {
__le64 qidx_compq_space_stat;
__le64 dtype_cmd_vsi_fdid;
};
#define ICE_FXD_FLTR_QW0_QINDEX_S 0
#define ICE_FXD_FLTR_QW0_QINDEX_M (0x7FFULL << ICE_FXD_FLTR_QW0_QINDEX_S)
#define ICE_FXD_FLTR_QW0_COMP_Q_S 11
#define ICE_FXD_FLTR_QW0_COMP_Q_M BIT_ULL(ICE_FXD_FLTR_QW0_COMP_Q_S)
#define ICE_FXD_FLTR_QW0_COMP_Q_ZERO 0x0ULL
#define ICE_FXD_FLTR_QW0_COMP_REPORT_S 12
#define ICE_FXD_FLTR_QW0_COMP_REPORT_M \
(0x3ULL << ICE_FXD_FLTR_QW0_COMP_REPORT_S)
#define ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL 0x1ULL
#define ICE_FXD_FLTR_QW0_FD_SPACE_S 14
#define ICE_FXD_FLTR_QW0_FD_SPACE_M (0x3ULL << ICE_FXD_FLTR_QW0_FD_SPACE_S)
#define ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST 0x2ULL
#define ICE_FXD_FLTR_QW0_STAT_CNT_S 16
#define ICE_FXD_FLTR_QW0_STAT_CNT_M \
(0x1FFFULL << ICE_FXD_FLTR_QW0_STAT_CNT_S)
#define ICE_FXD_FLTR_QW0_STAT_ENA_S 29
#define ICE_FXD_FLTR_QW0_STAT_ENA_M (0x3ULL << ICE_FXD_FLTR_QW0_STAT_ENA_S)
#define ICE_FXD_FLTR_QW0_STAT_ENA_PKTS 0x1ULL
#define ICE_FXD_FLTR_QW0_EVICT_ENA_S 31
#define ICE_FXD_FLTR_QW0_EVICT_ENA_M BIT_ULL(ICE_FXD_FLTR_QW0_EVICT_ENA_S)
#define ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE 0x0ULL
#define ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE 0x1ULL
#define ICE_FXD_FLTR_QW0_TO_Q_S 32
#define ICE_FXD_FLTR_QW0_TO_Q_M (0x7ULL << ICE_FXD_FLTR_QW0_TO_Q_S)
#define ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX 0x0ULL
#define ICE_FXD_FLTR_QW0_TO_Q_PRI_S 35
#define ICE_FXD_FLTR_QW0_TO_Q_PRI_M (0x7ULL << ICE_FXD_FLTR_QW0_TO_Q_PRI_S)
#define ICE_FXD_FLTR_QW0_TO_Q_PRIO1 0x1ULL
#define ICE_FXD_FLTR_QW0_DPU_RECIPE_S 38
#define ICE_FXD_FLTR_QW0_DPU_RECIPE_M \
(0x3ULL << ICE_FXD_FLTR_QW0_DPU_RECIPE_S)
#define ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT 0x0ULL
#define ICE_FXD_FLTR_QW0_DROP_S 40
#define ICE_FXD_FLTR_QW0_DROP_M BIT_ULL(ICE_FXD_FLTR_QW0_DROP_S)
#define ICE_FXD_FLTR_QW0_DROP_NO 0x0ULL
#define ICE_FXD_FLTR_QW0_DROP_YES 0x1ULL
#define ICE_FXD_FLTR_QW0_FLEX_PRI_S 41
#define ICE_FXD_FLTR_QW0_FLEX_PRI_M (0x7ULL << ICE_FXD_FLTR_QW0_FLEX_PRI_S)
#define ICE_FXD_FLTR_QW0_FLEX_PRI_NONE 0x0ULL
#define ICE_FXD_FLTR_QW0_FLEX_MDID_S 44
#define ICE_FXD_FLTR_QW0_FLEX_MDID_M (0xFULL << ICE_FXD_FLTR_QW0_FLEX_MDID_S)
#define ICE_FXD_FLTR_QW0_FLEX_MDID0 0x0ULL
#define ICE_FXD_FLTR_QW0_FLEX_VAL_S 48
#define ICE_FXD_FLTR_QW0_FLEX_VAL_M \
(0xFFFFULL << ICE_FXD_FLTR_QW0_FLEX_VAL_S)
#define ICE_FXD_FLTR_QW0_FLEX_VAL0 0x0ULL
#define ICE_FXD_FLTR_QW1_DTYPE_S 0
#define ICE_FXD_FLTR_QW1_DTYPE_M (0xFULL << ICE_FXD_FLTR_QW1_DTYPE_S)
#define ICE_FXD_FLTR_QW1_PCMD_S 4
#define ICE_FXD_FLTR_QW1_PCMD_M BIT_ULL(ICE_FXD_FLTR_QW1_PCMD_S)
#define ICE_FXD_FLTR_QW1_PCMD_ADD 0x0ULL
#define ICE_FXD_FLTR_QW1_PCMD_REMOVE 0x1ULL
#define ICE_FXD_FLTR_QW1_PROF_PRI_S 5
#define ICE_FXD_FLTR_QW1_PROF_PRI_M (0x7ULL << ICE_FXD_FLTR_QW1_PROF_PRI_S)
#define ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO 0x0ULL
#define ICE_FXD_FLTR_QW1_PROF_S 8
#define ICE_FXD_FLTR_QW1_PROF_M (0x3FULL << ICE_FXD_FLTR_QW1_PROF_S)
#define ICE_FXD_FLTR_QW1_PROF_ZERO 0x0ULL
#define ICE_FXD_FLTR_QW1_FD_VSI_S 14
#define ICE_FXD_FLTR_QW1_FD_VSI_M (0x3FFULL << ICE_FXD_FLTR_QW1_FD_VSI_S)
#define ICE_FXD_FLTR_QW1_SWAP_S 24
#define ICE_FXD_FLTR_QW1_SWAP_M BIT_ULL(ICE_FXD_FLTR_QW1_SWAP_S)
#define ICE_FXD_FLTR_QW1_SWAP_NOT_SET 0x0ULL
#define ICE_FXD_FLTR_QW1_SWAP_SET 0x1ULL
#define ICE_FXD_FLTR_QW1_FDID_PRI_S 25
#define ICE_FXD_FLTR_QW1_FDID_PRI_M (0x7ULL << ICE_FXD_FLTR_QW1_FDID_PRI_S)
#define ICE_FXD_FLTR_QW1_FDID_PRI_ONE 0x1ULL
#define ICE_FXD_FLTR_QW1_FDID_MDID_S 28
#define ICE_FXD_FLTR_QW1_FDID_MDID_M (0xFULL << ICE_FXD_FLTR_QW1_FDID_MDID_S)
#define ICE_FXD_FLTR_QW1_FDID_MDID_FD 0x05ULL
#define ICE_FXD_FLTR_QW1_FDID_S 32
#define ICE_FXD_FLTR_QW1_FDID_M \
(0xFFFFFFFFULL << ICE_FXD_FLTR_QW1_FDID_S)
#define ICE_FXD_FLTR_QW1_FDID_ZERO 0x0ULL
struct ice_rx_ptype_decoded {
u32 ptype:10;
u32 known:1;
......@@ -346,6 +444,7 @@ struct ice_tx_desc {
enum ice_tx_desc_dtype_value {
ICE_TX_DESC_DTYPE_DATA = 0x0,
ICE_TX_DESC_DTYPE_CTX = 0x1,
ICE_TX_DESC_DTYPE_FLTR_PROG = 0x8,
/* DESC_DONE - HW has completed write-back of descriptor */
ICE_TX_DESC_DTYPE_DESC_DONE = 0xF,
};
......@@ -357,12 +456,14 @@ enum ice_tx_desc_cmd_bits {
ICE_TX_DESC_CMD_EOP = 0x0001,
ICE_TX_DESC_CMD_RS = 0x0002,
ICE_TX_DESC_CMD_IL2TAG1 = 0x0008,
ICE_TX_DESC_CMD_DUMMY = 0x0010,
ICE_TX_DESC_CMD_IIPT_IPV6 = 0x0020,
ICE_TX_DESC_CMD_IIPT_IPV4 = 0x0040,
ICE_TX_DESC_CMD_IIPT_IPV4_CSUM = 0x0060,
ICE_TX_DESC_CMD_L4T_EOFT_TCP = 0x0100,
ICE_TX_DESC_CMD_L4T_EOFT_SCTP = 0x0200,
ICE_TX_DESC_CMD_L4T_EOFT_UDP = 0x0300,
ICE_TX_DESC_CMD_RE = 0x0400,
};
#define ICE_TXD_QW1_OFFSET_S 16
......
......@@ -16,6 +16,88 @@
#define ICE_RX_HDR_SIZE 256
#define FDIR_DESC_RXDID 0x40
#define ICE_FDIR_CLEAN_DELAY 10
/**
* ice_prgm_fdir_fltr - Program a Flow Director filter
* @vsi: VSI to send dummy packet
* @fdir_desc: flow director descriptor
* @raw_packet: allocated buffer for flow director
*/
int
ice_prgm_fdir_fltr(struct ice_vsi *vsi, struct ice_fltr_desc *fdir_desc,
u8 *raw_packet)
{
struct ice_tx_buf *tx_buf, *first;
struct ice_fltr_desc *f_desc;
struct ice_tx_desc *tx_desc;
struct ice_ring *tx_ring;
struct device *dev;
dma_addr_t dma;
u32 td_cmd;
u16 i;
/* VSI and Tx ring */
if (!vsi)
return -ENOENT;
tx_ring = vsi->tx_rings[0];
if (!tx_ring || !tx_ring->desc)
return -ENOENT;
dev = tx_ring->dev;
/* we are using two descriptors to add/del a filter and we can wait */
for (i = ICE_FDIR_CLEAN_DELAY; ICE_DESC_UNUSED(tx_ring) < 2; i--) {
if (!i)
return -EAGAIN;
msleep_interruptible(1);
}
dma = dma_map_single(dev, raw_packet, ICE_FDIR_MAX_RAW_PKT_SIZE,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma))
return -EINVAL;
/* grab the next descriptor */
i = tx_ring->next_to_use;
first = &tx_ring->tx_buf[i];
f_desc = ICE_TX_FDIRDESC(tx_ring, i);
memcpy(f_desc, fdir_desc, sizeof(*f_desc));
i++;
i = (i < tx_ring->count) ? i : 0;
tx_desc = ICE_TX_DESC(tx_ring, i);
tx_buf = &tx_ring->tx_buf[i];
i++;
tx_ring->next_to_use = (i < tx_ring->count) ? i : 0;
memset(tx_buf, 0, sizeof(*tx_buf));
dma_unmap_len_set(tx_buf, len, ICE_FDIR_MAX_RAW_PKT_SIZE);
dma_unmap_addr_set(tx_buf, dma, dma);
tx_desc->buf_addr = cpu_to_le64(dma);
td_cmd = ICE_TXD_LAST_DESC_CMD | ICE_TX_DESC_CMD_DUMMY |
ICE_TX_DESC_CMD_RE;
tx_buf->tx_flags = ICE_TX_FLAGS_DUMMY_PKT;
tx_buf->raw_buf = raw_packet;
tx_desc->cmd_type_offset_bsz =
ice_build_ctob(td_cmd, 0, ICE_FDIR_MAX_RAW_PKT_SIZE, 0);
/* Force memory write to complete before letting h/w know
* there are new descriptors to fetch.
*/
wmb();
/* mark the data descriptor to be watched */
first->next_to_watch = tx_desc;
writel(tx_ring->next_to_use, tx_ring->tail);
return 0;
}
/**
* ice_unmap_and_free_tx_buf - Release a Tx buffer
......
......@@ -380,6 +380,9 @@ int ice_setup_rx_ring(struct ice_ring *rx_ring);
void ice_free_tx_ring(struct ice_ring *tx_ring);
void ice_free_rx_ring(struct ice_ring *rx_ring);
int ice_napi_poll(struct napi_struct *napi, int budget);
int
ice_prgm_fdir_fltr(struct ice_vsi *vsi, struct ice_fltr_desc *fdir_desc,
u8 *raw_packet);
int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget);
void ice_clean_ctrl_tx_irq(struct ice_ring *tx_ring);
#endif /* _ICE_TXRX_H_ */
......@@ -628,6 +628,12 @@ struct ice_hw {
struct mutex fdir_fltr_lock; /* protect Flow Director */
struct list_head fdir_list_head;
/* Book-keeping of side-band filter count per flow-type.
* This is used to detect and handle input set changes for
* respective flow-type.
*/
u16 fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX];
struct ice_fd_hw_prof **fdir_prof;
DECLARE_BITMAP(fdir_perfect_fltr, ICE_FLTR_PTYPE_MAX);
struct mutex rss_locks; /* protect RSS configuration */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment