Skip to content

Commit 4ab9564

Browse files
Henry TiemanJeff Kirsher
authored andcommitted
ice: Support displaying ntuple rules
Add functionality for ethtool --show-ntuple, allowing for filters to be displayed when set functionality is added. Add statistics related to Flow Director matches and status. Signed-off-by: Henry Tieman <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 148beb6 commit 4ab9564

File tree

8 files changed

+280
-0
lines changed

8 files changed

+280
-0
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@ static inline struct ice_vsi *ice_get_ctrl_vsi(struct ice_pf *pf)
525525
return pf->vsi[pf->ctrl_vsi_idx];
526526
}
527527

528+
#define ICE_FD_STAT_CTR_BLOCK_COUNT 256
529+
#define ICE_FD_STAT_PF_IDX(base_idx) \
530+
((base_idx) * ICE_FD_STAT_CTR_BLOCK_COUNT)
531+
#define ICE_FD_SB_STAT_IDX(base_idx) ICE_FD_STAT_PF_IDX(base_idx)
532+
528533
int ice_vsi_setup_tx_rings(struct ice_vsi *vsi);
529534
int ice_vsi_setup_rx_rings(struct ice_vsi *vsi);
530535
int ice_vsi_open_ctrl(struct ice_vsi *vsi);
@@ -552,6 +557,10 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
552557
const char *ice_stat_str(enum ice_status stat_err);
553558
const char *ice_aq_str(enum ice_aq_err aq_err);
554559
void ice_vsi_manage_fdir(struct ice_vsi *vsi, bool ena);
560+
int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd);
561+
int
562+
ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
563+
u32 *rule_locs);
555564
void ice_fdir_release_flows(struct ice_hw *hw);
556565
int ice_fdir_create_dflt_rules(struct ice_pf *pf);
557566
int ice_open(struct net_device *netdev);

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ static const struct ice_stats ice_gstrings_pf_stats[] = {
130130
ICE_PF_STAT("illegal_bytes.nic", stats.illegal_bytes),
131131
ICE_PF_STAT("mac_local_faults.nic", stats.mac_local_faults),
132132
ICE_PF_STAT("mac_remote_faults.nic", stats.mac_remote_faults),
133+
ICE_PF_STAT("fdir_sb_match.nic", stats.fd_sb_match),
134+
ICE_PF_STAT("fdir_sb_status.nic", stats.fd_sb_status),
133135
};
134136

135137
static const u32 ice_regs_dump_list[] = {
@@ -2558,12 +2560,27 @@ ice_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
25582560
struct ice_netdev_priv *np = netdev_priv(netdev);
25592561
struct ice_vsi *vsi = np->vsi;
25602562
int ret = -EOPNOTSUPP;
2563+
struct ice_hw *hw;
2564+
2565+
hw = &vsi->back->hw;
25612566

25622567
switch (cmd->cmd) {
25632568
case ETHTOOL_GRXRINGS:
25642569
cmd->data = vsi->rss_size;
25652570
ret = 0;
25662571
break;
2572+
case ETHTOOL_GRXCLSRLCNT:
2573+
cmd->rule_cnt = hw->fdir_active_fltr;
2574+
/* report total rule count */
2575+
cmd->data = ice_get_fdir_cnt_all(hw);
2576+
ret = 0;
2577+
break;
2578+
case ETHTOOL_GRXCLSRULE:
2579+
ret = ice_get_ethtool_fdir_entry(hw, cmd);
2580+
break;
2581+
case ETHTOOL_GRXCLSRLALL:
2582+
ret = ice_get_fdir_fltr_ids(hw, cmd, (u32 *)rule_locs);
2583+
break;
25672584
case ETHTOOL_GRXFH:
25682585
ice_get_rss_hash_opt(vsi, cmd);
25692586
ret = 0;

drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,167 @@
1212
*/
1313
#define TNL_SEG_CNT(_TNL_) ((_TNL_) + 1)
1414

15+
/**
16+
* ice_fltr_to_ethtool_flow - convert filter type values to ethtool
17+
* flow type values
18+
* @flow: filter type to be converted
19+
*
20+
* Returns the corresponding ethtool flow type.
21+
*/
22+
static int ice_fltr_to_ethtool_flow(enum ice_fltr_ptype flow)
23+
{
24+
switch (flow) {
25+
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
26+
return TCP_V4_FLOW;
27+
case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
28+
return UDP_V4_FLOW;
29+
case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
30+
return SCTP_V4_FLOW;
31+
case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
32+
return IPV4_USER_FLOW;
33+
default:
34+
/* 0 is undefined ethtool flow */
35+
return 0;
36+
}
37+
}
38+
39+
/**
40+
* ice_ethtool_flow_to_fltr - convert ethtool flow type to filter enum
41+
* @eth: Ethtool flow type to be converted
42+
*
43+
* Returns flow enum
44+
*/
45+
static enum ice_fltr_ptype ice_ethtool_flow_to_fltr(int eth)
46+
{
47+
switch (eth) {
48+
case TCP_V4_FLOW:
49+
return ICE_FLTR_PTYPE_NONF_IPV4_TCP;
50+
case UDP_V4_FLOW:
51+
return ICE_FLTR_PTYPE_NONF_IPV4_UDP;
52+
case SCTP_V4_FLOW:
53+
return ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
54+
case IPV4_USER_FLOW:
55+
return ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
56+
default:
57+
return ICE_FLTR_PTYPE_NONF_NONE;
58+
}
59+
}
60+
61+
/**
62+
* ice_get_ethtool_fdir_entry - fill ethtool structure with fdir filter data
63+
* @hw: hardware structure that contains filter list
64+
* @cmd: ethtool command data structure to receive the filter data
65+
*
66+
* Returns 0 on success and -EINVAL on failure
67+
*/
68+
int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd)
69+
{
70+
struct ethtool_rx_flow_spec *fsp;
71+
struct ice_fdir_fltr *rule;
72+
int ret = 0;
73+
u16 idx;
74+
75+
fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
76+
77+
mutex_lock(&hw->fdir_fltr_lock);
78+
79+
rule = ice_fdir_find_fltr_by_idx(hw, fsp->location);
80+
81+
if (!rule || fsp->location != rule->fltr_id) {
82+
ret = -EINVAL;
83+
goto release_lock;
84+
}
85+
86+
fsp->flow_type = ice_fltr_to_ethtool_flow(rule->flow_type);
87+
88+
memset(&fsp->m_u, 0, sizeof(fsp->m_u));
89+
memset(&fsp->m_ext, 0, sizeof(fsp->m_ext));
90+
91+
switch (fsp->flow_type) {
92+
case IPV4_USER_FLOW:
93+
fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
94+
fsp->h_u.usr_ip4_spec.proto = 0;
95+
fsp->h_u.usr_ip4_spec.l4_4_bytes = rule->ip.l4_header;
96+
fsp->h_u.usr_ip4_spec.tos = rule->ip.tos;
97+
fsp->h_u.usr_ip4_spec.ip4src = rule->ip.src_ip;
98+
fsp->h_u.usr_ip4_spec.ip4dst = rule->ip.dst_ip;
99+
fsp->m_u.usr_ip4_spec.ip4src = rule->mask.src_ip;
100+
fsp->m_u.usr_ip4_spec.ip4dst = rule->mask.dst_ip;
101+
fsp->m_u.usr_ip4_spec.ip_ver = 0xFF;
102+
fsp->m_u.usr_ip4_spec.proto = 0;
103+
fsp->m_u.usr_ip4_spec.l4_4_bytes = rule->mask.l4_header;
104+
fsp->m_u.usr_ip4_spec.tos = rule->mask.tos;
105+
break;
106+
case TCP_V4_FLOW:
107+
case UDP_V4_FLOW:
108+
case SCTP_V4_FLOW:
109+
fsp->h_u.tcp_ip4_spec.psrc = rule->ip.src_port;
110+
fsp->h_u.tcp_ip4_spec.pdst = rule->ip.dst_port;
111+
fsp->h_u.tcp_ip4_spec.ip4src = rule->ip.src_ip;
112+
fsp->h_u.tcp_ip4_spec.ip4dst = rule->ip.dst_ip;
113+
fsp->m_u.tcp_ip4_spec.psrc = rule->mask.src_port;
114+
fsp->m_u.tcp_ip4_spec.pdst = rule->mask.dst_port;
115+
fsp->m_u.tcp_ip4_spec.ip4src = rule->mask.src_ip;
116+
fsp->m_u.tcp_ip4_spec.ip4dst = rule->mask.dst_ip;
117+
break;
118+
default:
119+
break;
120+
}
121+
122+
if (rule->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT)
123+
fsp->ring_cookie = RX_CLS_FLOW_DISC;
124+
else
125+
fsp->ring_cookie = rule->q_index;
126+
127+
idx = ice_ethtool_flow_to_fltr(fsp->flow_type);
128+
if (idx == ICE_FLTR_PTYPE_NONF_NONE) {
129+
dev_err(ice_hw_to_dev(hw), "Missing input index for flow_type %d\n",
130+
rule->flow_type);
131+
ret = -EINVAL;
132+
}
133+
134+
release_lock:
135+
mutex_unlock(&hw->fdir_fltr_lock);
136+
return ret;
137+
}
138+
139+
/**
140+
* ice_get_fdir_fltr_ids - fill buffer with filter IDs of active filters
141+
* @hw: hardware structure containing the filter list
142+
* @cmd: ethtool command data structure
143+
* @rule_locs: ethtool array passed in from OS to receive filter IDs
144+
*
145+
* Returns 0 as expected for success by ethtool
146+
*/
147+
int
148+
ice_get_fdir_fltr_ids(struct ice_hw *hw, struct ethtool_rxnfc *cmd,
149+
u32 *rule_locs)
150+
{
151+
struct ice_fdir_fltr *f_rule;
152+
unsigned int cnt = 0;
153+
int val = 0;
154+
155+
/* report total rule count */
156+
cmd->data = ice_get_fdir_cnt_all(hw);
157+
158+
mutex_lock(&hw->fdir_fltr_lock);
159+
160+
list_for_each_entry(f_rule, &hw->fdir_list_head, fltr_node) {
161+
if (cnt == cmd->rule_cnt) {
162+
val = -EMSGSIZE;
163+
goto release_lock;
164+
}
165+
rule_locs[cnt] = f_rule->fltr_id;
166+
cnt++;
167+
}
168+
169+
release_lock:
170+
mutex_unlock(&hw->fdir_fltr_lock);
171+
if (!val)
172+
cmd->rule_cnt = cnt;
173+
return val;
174+
}
175+
15176
/**
16177
* ice_fdir_get_hw_prof - return the ice_fd_hw_proc associated with a flow
17178
* @hw: hardware structure containing the filter list

drivers/net/ethernet/intel/ice/ice_fdir.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,36 @@ ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr)
5252
ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr,
5353
cntr_id);
5454
}
55+
56+
/**
57+
* ice_get_fdir_cnt_all - get the number of Flow Director filters
58+
* @hw: hardware data structure
59+
*
60+
* Returns the number of filters available on device
61+
*/
62+
int ice_get_fdir_cnt_all(struct ice_hw *hw)
63+
{
64+
return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort;
65+
}
66+
67+
/**
68+
* ice_fdir_find_by_idx - find filter with idx
69+
* @hw: pointer to hardware structure
70+
* @fltr_idx: index to find.
71+
*
72+
* Returns pointer to filter if found or null
73+
*/
74+
struct ice_fdir_fltr *
75+
ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx)
76+
{
77+
struct ice_fdir_fltr *rule;
78+
79+
list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
80+
/* rule ID found in the list */
81+
if (fltr_idx == rule->fltr_id)
82+
return rule;
83+
if (fltr_idx < rule->fltr_id)
84+
break;
85+
}
86+
return NULL;
87+
}

drivers/net/ethernet/intel/ice/ice_fdir.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,57 @@
33

44
#ifndef _ICE_FDIR_H_
55
#define _ICE_FDIR_H_
6+
7+
enum ice_fltr_prgm_desc_dest {
8+
ICE_FLTR_PRGM_DESC_DEST_DROP_PKT,
9+
ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX,
10+
};
11+
12+
struct ice_fdir_v4 {
13+
__be32 dst_ip;
14+
__be32 src_ip;
15+
__be16 dst_port;
16+
__be16 src_port;
17+
__be32 l4_header;
18+
__be32 sec_parm_idx; /* security parameter index */
19+
u8 tos;
20+
u8 ip_ver;
21+
u8 proto;
22+
};
23+
24+
struct ice_fdir_extra {
25+
u8 dst_mac[ETH_ALEN]; /* dest MAC address */
26+
u32 usr_def[2]; /* user data */
27+
__be16 vlan_type; /* VLAN ethertype */
28+
__be16 vlan_tag; /* VLAN tag info */
29+
};
30+
31+
struct ice_fdir_fltr {
32+
struct list_head fltr_node;
33+
enum ice_fltr_ptype flow_type;
34+
35+
struct ice_fdir_v4 ip;
36+
struct ice_fdir_v4 mask;
37+
38+
struct ice_fdir_extra ext_data;
39+
struct ice_fdir_extra ext_mask;
40+
41+
/* filter control */
42+
u16 q_index;
43+
u16 dest_vsi;
44+
u8 dest_ctl;
45+
u8 fltr_status;
46+
u16 cnt_index;
47+
u32 fltr_id;
48+
};
49+
650
enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id);
751
enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id);
852
enum ice_status
953
ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr);
1054
enum ice_status
1155
ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr);
56+
int ice_get_fdir_cnt_all(struct ice_hw *hw);
57+
struct ice_fdir_fltr *
58+
ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx);
1259
#endif /* _ICE_FDIR_H_ */

drivers/net/ethernet/intel/ice/ice_hw_autogen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@
344344
#define GLPRT_TDOLD(_i) (0x00381280 + ((_i) * 8))
345345
#define GLPRT_UPRCL(_i) (0x00381300 + ((_i) * 8))
346346
#define GLPRT_UPTCL(_i) (0x003811C0 + ((_i) * 8))
347+
#define GLSTAT_FD_CNT0L(_i) (0x003A0000 + ((_i) * 8))
347348
#define GLV_BPRCL(_i) (0x003B6000 + ((_i) * 8))
348349
#define GLV_BPTCL(_i) (0x0030E000 + ((_i) * 8))
349350
#define GLV_GORCL(_i) (0x003B0000 + ((_i) * 8))

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4281,6 +4281,7 @@ void ice_update_pf_stats(struct ice_pf *pf)
42814281
{
42824282
struct ice_hw_port_stats *prev_ps, *cur_ps;
42834283
struct ice_hw *hw = &pf->hw;
4284+
u16 fd_ctr_base;
42844285
u8 port;
42854286

42864287
port = hw->port_info->lport;
@@ -4369,6 +4370,12 @@ void ice_update_pf_stats(struct ice_pf *pf)
43694370
ice_stat_update40(hw, GLPRT_PTC9522L(port), pf->stat_prev_loaded,
43704371
&prev_ps->tx_size_big, &cur_ps->tx_size_big);
43714372

4373+
fd_ctr_base = hw->fd_ctr_base;
4374+
4375+
ice_stat_update40(hw,
4376+
GLSTAT_FD_CNT0L(ICE_FD_SB_STAT_IDX(fd_ctr_base)),
4377+
pf->stat_prev_loaded, &prev_ps->fd_sb_match,
4378+
&cur_ps->fd_sb_match);
43724379
ice_stat_update32(hw, GLPRT_LXONRXC(port), pf->stat_prev_loaded,
43734380
&prev_ps->link_xon_rx, &cur_ps->link_xon_rx);
43744381

@@ -4412,6 +4419,8 @@ void ice_update_pf_stats(struct ice_pf *pf)
44124419
ice_stat_update32(hw, GLPRT_RJC(port), pf->stat_prev_loaded,
44134420
&prev_ps->rx_jabber, &cur_ps->rx_jabber);
44144421

4422+
cur_ps->fd_sb_status = test_bit(ICE_FLAG_FD_ENA, pf->flags) ? 1 : 0;
4423+
44154424
pf->stat_prev_loaded = true;
44164425
}
44174426

drivers/net/ethernet/intel/ice/ice_type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ struct ice_hw_port_stats {
691691
u64 tx_size_1023; /* ptc1023 */
692692
u64 tx_size_1522; /* ptc1522 */
693693
u64 tx_size_big; /* ptc9522 */
694+
/* flow director stats */
695+
u32 fd_sb_status;
696+
u64 fd_sb_match;
694697
};
695698

696699
/* Checksum and Shadow RAM pointers */

0 commit comments

Comments
 (0)