Skip to content

Commit e918c7b

Browse files
author
Paolo Abeni
committed
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== This series contains updates to ice driver only. Lukasz removes unnecessary argument from ice_fdir_comp_rules(). Jakub adds support for ethtool 'ether' flow-type rules. Jake moves setting of VF MSI-X value to initialization function and adds tracking of VF relative MSI-X index. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: ice: store VF relative MSI-X index in q_vector->vf_reg_idx ice: set vf->num_msix in ice_initialize_vf_entry() ice: Implement 'flow-type ether' rules ice: Remove unnecessary argument from ice_fdir_comp_rules() ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 81b095c + b80d01e commit e918c7b

File tree

10 files changed

+231
-68
lines changed

10 files changed

+231
-68
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ struct ice_q_vector {
459459
struct ice_vsi *vsi;
460460

461461
u16 v_idx; /* index in the vsi->q_vector array. */
462-
u16 reg_idx;
462+
u16 reg_idx; /* PF relative register index */
463463
u8 num_ring_rx; /* total number of Rx rings in vector */
464464
u8 num_ring_tx; /* total number of Tx rings in vector */
465465
u8 wb_on_itr:1; /* if true, WB on ITR is enabled */
@@ -481,6 +481,7 @@ struct ice_q_vector {
481481
char name[ICE_INT_NAME_STR_LEN];
482482

483483
u16 total_events; /* net_dim(): number of interrupts processed */
484+
u16 vf_reg_idx; /* VF relative register index */
484485
struct msi_map irq;
485486
} ____cacheline_internodealigned_in_smp;
486487

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx)
121121
q_vector->irq.index = -ENOENT;
122122

123123
if (vsi->type == ICE_VSI_VF) {
124-
q_vector->reg_idx = ice_calc_vf_reg_idx(vsi->vf, q_vector);
124+
ice_calc_vf_reg_idx(vsi->vf, q_vector);
125125
goto out;
126126
} else if (vsi->type == ICE_VSI_CTRL && vsi->vf) {
127127
struct ice_vsi *ctrl_vsi = ice_get_vf_ctrl_vsi(pf, vsi);
@@ -145,6 +145,7 @@ static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx)
145145

146146
skip_alloc:
147147
q_vector->reg_idx = q_vector->irq.index;
148+
q_vector->vf_reg_idx = q_vector->irq.index;
148149

149150
/* only set affinity_mask if the CPU is online */
150151
if (cpu_online(v_idx))

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

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ static struct in6_addr zero_ipv6_addr_mask = {
4141
static int ice_fltr_to_ethtool_flow(enum ice_fltr_ptype flow)
4242
{
4343
switch (flow) {
44+
case ICE_FLTR_PTYPE_NONF_ETH:
45+
return ETHER_FLOW;
4446
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
4547
return TCP_V4_FLOW;
4648
case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
@@ -72,6 +74,8 @@ static int ice_fltr_to_ethtool_flow(enum ice_fltr_ptype flow)
7274
static enum ice_fltr_ptype ice_ethtool_flow_to_fltr(int eth)
7375
{
7476
switch (eth) {
77+
case ETHER_FLOW:
78+
return ICE_FLTR_PTYPE_NONF_ETH;
7579
case TCP_V4_FLOW:
7680
return ICE_FLTR_PTYPE_NONF_IPV4_TCP;
7781
case UDP_V4_FLOW:
@@ -137,6 +141,10 @@ int ice_get_ethtool_fdir_entry(struct ice_hw *hw, struct ethtool_rxnfc *cmd)
137141
memset(&fsp->m_ext, 0, sizeof(fsp->m_ext));
138142

139143
switch (fsp->flow_type) {
144+
case ETHER_FLOW:
145+
fsp->h_u.ether_spec = rule->eth;
146+
fsp->m_u.ether_spec = rule->eth_mask;
147+
break;
140148
case IPV4_USER_FLOW:
141149
fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
142150
fsp->h_u.usr_ip4_spec.proto = 0;
@@ -1193,6 +1201,122 @@ ice_set_fdir_ip6_usr_seg(struct ice_flow_seg_info *seg,
11931201
return 0;
11941202
}
11951203

1204+
/**
1205+
* ice_fdir_vlan_valid - validate VLAN data for Flow Director rule
1206+
* @dev: network interface device structure
1207+
* @fsp: pointer to ethtool Rx flow specification
1208+
*
1209+
* Return: true if vlan data is valid, false otherwise
1210+
*/
1211+
static bool ice_fdir_vlan_valid(struct device *dev,
1212+
struct ethtool_rx_flow_spec *fsp)
1213+
{
1214+
if (fsp->m_ext.vlan_etype && !eth_type_vlan(fsp->h_ext.vlan_etype))
1215+
return false;
1216+
1217+
if (fsp->m_ext.vlan_tci && ntohs(fsp->h_ext.vlan_tci) >= VLAN_N_VID)
1218+
return false;
1219+
1220+
/* proto and vlan must have vlan-etype defined */
1221+
if (fsp->m_u.ether_spec.h_proto && fsp->m_ext.vlan_tci &&
1222+
!fsp->m_ext.vlan_etype) {
1223+
dev_warn(dev, "Filter with proto and vlan require also vlan-etype");
1224+
return false;
1225+
}
1226+
1227+
return true;
1228+
}
1229+
1230+
/**
1231+
* ice_set_ether_flow_seg - set address and protocol segments for ether flow
1232+
* @dev: network interface device structure
1233+
* @seg: flow segment for programming
1234+
* @eth_spec: mask data from ethtool
1235+
*
1236+
* Return: 0 on success and errno in case of error.
1237+
*/
1238+
static int ice_set_ether_flow_seg(struct device *dev,
1239+
struct ice_flow_seg_info *seg,
1240+
struct ethhdr *eth_spec)
1241+
{
1242+
ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ETH);
1243+
1244+
/* empty rules are not valid */
1245+
if (is_zero_ether_addr(eth_spec->h_source) &&
1246+
is_zero_ether_addr(eth_spec->h_dest) &&
1247+
!eth_spec->h_proto)
1248+
return -EINVAL;
1249+
1250+
/* Ethertype */
1251+
if (eth_spec->h_proto == htons(0xFFFF)) {
1252+
ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_ETH_TYPE,
1253+
ICE_FLOW_FLD_OFF_INVAL,
1254+
ICE_FLOW_FLD_OFF_INVAL,
1255+
ICE_FLOW_FLD_OFF_INVAL, false);
1256+
} else if (eth_spec->h_proto) {
1257+
dev_warn(dev, "Only 0x0000 or 0xffff proto mask is allowed for flow-type ether");
1258+
return -EOPNOTSUPP;
1259+
}
1260+
1261+
/* Source MAC address */
1262+
if (is_broadcast_ether_addr(eth_spec->h_source))
1263+
ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_ETH_SA,
1264+
ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1265+
ICE_FLOW_FLD_OFF_INVAL, false);
1266+
else if (!is_zero_ether_addr(eth_spec->h_source))
1267+
goto err_mask;
1268+
1269+
/* Destination MAC address */
1270+
if (is_broadcast_ether_addr(eth_spec->h_dest))
1271+
ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_ETH_DA,
1272+
ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL,
1273+
ICE_FLOW_FLD_OFF_INVAL, false);
1274+
else if (!is_zero_ether_addr(eth_spec->h_dest))
1275+
goto err_mask;
1276+
1277+
return 0;
1278+
1279+
err_mask:
1280+
dev_warn(dev, "Only 00:00:00:00:00:00 or ff:ff:ff:ff:ff:ff MAC address mask is allowed for flow-type ether");
1281+
return -EOPNOTSUPP;
1282+
}
1283+
1284+
/**
1285+
* ice_set_fdir_vlan_seg - set vlan segments for ether flow
1286+
* @seg: flow segment for programming
1287+
* @ext_masks: masks for additional RX flow fields
1288+
*
1289+
* Return: 0 on success and errno in case of error.
1290+
*/
1291+
static int
1292+
ice_set_fdir_vlan_seg(struct ice_flow_seg_info *seg,
1293+
struct ethtool_flow_ext *ext_masks)
1294+
{
1295+
ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_VLAN);
1296+
1297+
if (ext_masks->vlan_etype) {
1298+
if (ext_masks->vlan_etype != htons(0xFFFF))
1299+
return -EOPNOTSUPP;
1300+
1301+
ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_S_VLAN,
1302+
ICE_FLOW_FLD_OFF_INVAL,
1303+
ICE_FLOW_FLD_OFF_INVAL,
1304+
ICE_FLOW_FLD_OFF_INVAL, false);
1305+
}
1306+
1307+
if (ext_masks->vlan_tci) {
1308+
if (ext_masks->vlan_tci != htons(0xFFFF))
1309+
return -EOPNOTSUPP;
1310+
1311+
ice_flow_set_fld(seg, ICE_FLOW_FIELD_IDX_C_VLAN,
1312+
ICE_FLOW_FLD_OFF_INVAL,
1313+
ICE_FLOW_FLD_OFF_INVAL,
1314+
ICE_FLOW_FLD_OFF_INVAL, false);
1315+
}
1316+
1317+
return 0;
1318+
}
1319+
11961320
/**
11971321
* ice_cfg_fdir_xtrct_seq - Configure extraction sequence for the given filter
11981322
* @pf: PF structure
@@ -1209,7 +1333,7 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
12091333
struct device *dev = ice_pf_to_dev(pf);
12101334
enum ice_fltr_ptype fltr_idx;
12111335
struct ice_hw *hw = &pf->hw;
1212-
bool perfect_filter;
1336+
bool perfect_filter = false;
12131337
int ret;
12141338

12151339
seg = devm_kzalloc(dev, sizeof(*seg), GFP_KERNEL);
@@ -1262,6 +1386,16 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp,
12621386
ret = ice_set_fdir_ip6_usr_seg(seg, &fsp->m_u.usr_ip6_spec,
12631387
&perfect_filter);
12641388
break;
1389+
case ETHER_FLOW:
1390+
ret = ice_set_ether_flow_seg(dev, seg, &fsp->m_u.ether_spec);
1391+
if (!ret && (fsp->m_ext.vlan_etype || fsp->m_ext.vlan_tci)) {
1392+
if (!ice_fdir_vlan_valid(dev, fsp)) {
1393+
ret = -EINVAL;
1394+
break;
1395+
}
1396+
ret = ice_set_fdir_vlan_seg(seg, &fsp->m_ext);
1397+
}
1398+
break;
12651399
default:
12661400
ret = -EINVAL;
12671401
}
@@ -1823,6 +1957,10 @@ ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
18231957
input->mask.v6.tc = fsp->m_u.usr_ip6_spec.tclass;
18241958
input->mask.v6.proto = fsp->m_u.usr_ip6_spec.l4_proto;
18251959
break;
1960+
case ETHER_FLOW:
1961+
input->eth = fsp->h_u.ether_spec;
1962+
input->eth_mask = fsp->m_u.ether_spec;
1963+
break;
18261964
default:
18271965
/* not doing un-parsed flow types */
18281966
return -EINVAL;

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

Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "ice_common.h"
55

66
/* These are training packet headers used to program flow director filters. */
7+
static const u8 ice_fdir_eth_pkt[22];
8+
79
static const u8 ice_fdir_tcpv4_pkt[] = {
810
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
911
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
@@ -416,6 +418,11 @@ static const u8 ice_fdir_ip6_tun_pkt[] = {
416418

417419
/* Flow Director no-op training packet table */
418420
static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
421+
{
422+
ICE_FLTR_PTYPE_NONF_ETH,
423+
sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt,
424+
sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt,
425+
},
419426
{
420427
ICE_FLTR_PTYPE_NONF_IPV4_TCP,
421428
sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt,
@@ -914,6 +921,21 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
914921
* perspective. The input from user is from Rx filter perspective.
915922
*/
916923
switch (flow) {
924+
case ICE_FLTR_PTYPE_NONF_ETH:
925+
ice_pkt_insert_mac_addr(loc, input->eth.h_dest);
926+
ice_pkt_insert_mac_addr(loc + ETH_ALEN, input->eth.h_source);
927+
if (input->ext_data.vlan_tag || input->ext_data.vlan_type) {
928+
ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
929+
input->ext_data.vlan_type);
930+
ice_pkt_insert_u16(loc, ICE_ETH_VLAN_TCI_OFFSET,
931+
input->ext_data.vlan_tag);
932+
ice_pkt_insert_u16(loc, ICE_ETH_TYPE_VLAN_OFFSET,
933+
input->eth.h_proto);
934+
} else {
935+
ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
936+
input->eth.h_proto);
937+
}
938+
break;
917939
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
918940
ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
919941
input->ip.v4.src_ip);
@@ -1189,52 +1211,58 @@ static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b)
11891211
* ice_fdir_comp_rules - compare 2 filters
11901212
* @a: a Flow Director filter data structure
11911213
* @b: a Flow Director filter data structure
1192-
* @v6: bool true if v6 filter
11931214
*
11941215
* Returns true if the filters match
11951216
*/
11961217
static bool
1197-
ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6)
1218+
ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b)
11981219
{
11991220
enum ice_fltr_ptype flow_type = a->flow_type;
12001221

12011222
/* The calling function already checks that the two filters have the
12021223
* same flow_type.
12031224
*/
1204-
if (!v6) {
1205-
if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1206-
flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1207-
flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) {
1208-
if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1209-
a->ip.v4.src_ip == b->ip.v4.src_ip &&
1210-
a->ip.v4.dst_port == b->ip.v4.dst_port &&
1211-
a->ip.v4.src_port == b->ip.v4.src_port)
1212-
return true;
1213-
} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) {
1214-
if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1215-
a->ip.v4.src_ip == b->ip.v4.src_ip &&
1216-
a->ip.v4.l4_header == b->ip.v4.l4_header &&
1217-
a->ip.v4.proto == b->ip.v4.proto &&
1218-
a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1219-
a->ip.v4.tos == b->ip.v4.tos)
1220-
return true;
1221-
}
1222-
} else {
1223-
if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
1224-
flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
1225-
flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) {
1226-
if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1227-
a->ip.v6.src_port == b->ip.v6.src_port &&
1228-
!ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1229-
b->ip.v6.dst_ip) &&
1230-
!ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1231-
b->ip.v6.src_ip))
1232-
return true;
1233-
} else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
1234-
if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1235-
a->ip.v6.src_port == b->ip.v6.src_port)
1236-
return true;
1237-
}
1225+
switch (flow_type) {
1226+
case ICE_FLTR_PTYPE_NONF_ETH:
1227+
if (!memcmp(&a->eth, &b->eth, sizeof(a->eth)))
1228+
return true;
1229+
break;
1230+
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
1231+
case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
1232+
case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
1233+
if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1234+
a->ip.v4.src_ip == b->ip.v4.src_ip &&
1235+
a->ip.v4.dst_port == b->ip.v4.dst_port &&
1236+
a->ip.v4.src_port == b->ip.v4.src_port)
1237+
return true;
1238+
break;
1239+
case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
1240+
if (a->ip.v4.dst_ip == b->ip.v4.dst_ip &&
1241+
a->ip.v4.src_ip == b->ip.v4.src_ip &&
1242+
a->ip.v4.l4_header == b->ip.v4.l4_header &&
1243+
a->ip.v4.proto == b->ip.v4.proto &&
1244+
a->ip.v4.ip_ver == b->ip.v4.ip_ver &&
1245+
a->ip.v4.tos == b->ip.v4.tos)
1246+
return true;
1247+
break;
1248+
case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
1249+
case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
1250+
case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
1251+
if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1252+
a->ip.v6.src_port == b->ip.v6.src_port &&
1253+
!ice_cmp_ipv6_addr(a->ip.v6.dst_ip,
1254+
b->ip.v6.dst_ip) &&
1255+
!ice_cmp_ipv6_addr(a->ip.v6.src_ip,
1256+
b->ip.v6.src_ip))
1257+
return true;
1258+
break;
1259+
case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
1260+
if (a->ip.v6.dst_port == b->ip.v6.dst_port &&
1261+
a->ip.v6.src_port == b->ip.v6.src_port)
1262+
return true;
1263+
break;
1264+
default:
1265+
break;
12381266
}
12391267

12401268
return false;
@@ -1253,19 +1281,10 @@ bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input)
12531281
bool ret = false;
12541282

12551283
list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) {
1256-
enum ice_fltr_ptype flow_type;
1257-
12581284
if (rule->flow_type != input->flow_type)
12591285
continue;
12601286

1261-
flow_type = input->flow_type;
1262-
if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
1263-
flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
1264-
flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP ||
1265-
flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
1266-
ret = ice_fdir_comp_rules(rule, input, false);
1267-
else
1268-
ret = ice_fdir_comp_rules(rule, input, true);
1287+
ret = ice_fdir_comp_rules(rule, input);
12691288
if (ret) {
12701289
if (rule->fltr_id == input->fltr_id &&
12711290
rule->q_index != input->q_index)

0 commit comments

Comments
 (0)