Lines Matching +full:stream +full:- +full:match +full:- +full:mask

1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
35 return -EOPNOTSUPP; in ocelot_chain_to_block()
38 /* Backwards compatibility with older, single-chain tc-flower in ocelot_chain_to_block()
56 return -EOPNOTSUPP; in ocelot_chain_to_block()
64 /* Backwards compatibility with older, single-chain tc-flower in ocelot_chain_to_lookup()
80 /* Backwards compatibility with older, single-chain tc-flower in ocelot_chain_to_pag()
89 return chain - VCAP_IS2_CHAIN(lookup, 0); in ocelot_chain_to_pag()
101 /* Non-optional GOTOs */ in ocelot_is_goto_target_valid()
117 /* Lookup 2 of VCAP IS1 can really support non-optional GOTOs, in ocelot_is_goto_target_valid()
118 * using a Policy Association Group (PAG) value, which is an 8-bit in ocelot_is_goto_target_valid()
129 /* Non-optional GOTO from VCAP IS2 lookup 0 to lookup 1. in ocelot_is_goto_target_valid()
156 block = &ocelot->block[VCAP_IS1]; in ocelot_find_vcap_filter_that_points_at()
158 list_for_each_entry(filter, &block->rules, list) in ocelot_find_vcap_filter_that_points_at()
159 if (filter->type == OCELOT_VCAP_FILTER_PAG && in ocelot_find_vcap_filter_that_points_at()
160 filter->goto_target == chain) in ocelot_find_vcap_filter_that_points_at()
164 list_for_each_entry(filter, &ocelot->dummy_rules, list) in ocelot_find_vcap_filter_that_points_at()
165 if (filter->goto_target == chain) in ocelot_find_vcap_filter_that_points_at()
177 struct ocelot_port *ocelot_port = ocelot->ports[port]; in ocelot_flower_parse_ingress_vlan_modify()
179 if (filter->goto_target != -1) { in ocelot_flower_parse_ingress_vlan_modify()
182 return -EOPNOTSUPP; in ocelot_flower_parse_ingress_vlan_modify()
185 if (!ocelot_port->vlan_aware) { in ocelot_flower_parse_ingress_vlan_modify()
188 return -EOPNOTSUPP; in ocelot_flower_parse_ingress_vlan_modify()
191 filter->action.vid_replace_ena = true; in ocelot_flower_parse_ingress_vlan_modify()
192 filter->action.pcp_dei_ena = true; in ocelot_flower_parse_ingress_vlan_modify()
193 filter->action.vid = a->vlan.vid; in ocelot_flower_parse_ingress_vlan_modify()
194 filter->action.pcp = a->vlan.prio; in ocelot_flower_parse_ingress_vlan_modify()
195 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_ingress_vlan_modify()
207 switch (ntohs(a->vlan.proto)) { in ocelot_flower_parse_egress_vlan_modify()
217 return -EOPNOTSUPP; in ocelot_flower_parse_egress_vlan_modify()
220 filter->action.tag_a_tpid_sel = tpid; in ocelot_flower_parse_egress_vlan_modify()
221 filter->action.push_outer_tag = OCELOT_ES0_TAG; in ocelot_flower_parse_egress_vlan_modify()
222 filter->action.tag_a_vid_sel = OCELOT_ES0_VID_PLUS_CLASSIFIED_VID; in ocelot_flower_parse_egress_vlan_modify()
223 filter->action.vid_a_val = a->vlan.vid; in ocelot_flower_parse_egress_vlan_modify()
224 filter->action.pcp_a_val = a->vlan.prio; in ocelot_flower_parse_egress_vlan_modify()
225 filter->action.tag_a_pcp_sel = OCELOT_ES0_PCP; in ocelot_flower_parse_egress_vlan_modify()
226 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_egress_vlan_modify()
235 const struct flow_action *action = &f->rule->action; in ocelot_flower_parse_action()
236 struct netlink_ext_ack *extack = f->common.extack; in ocelot_flower_parse_action()
245 if (!flow_action_basic_hw_stats_check(&f->rule->action, in ocelot_flower_parse_action()
246 f->common.extack)) in ocelot_flower_parse_action()
247 return -EOPNOTSUPP; in ocelot_flower_parse_action()
249 chain = f->common.chain_index; in ocelot_flower_parse_action()
250 filter->block_id = ocelot_chain_to_block(chain, ingress); in ocelot_flower_parse_action()
251 if (filter->block_id < 0) { in ocelot_flower_parse_action()
253 return -EOPNOTSUPP; in ocelot_flower_parse_action()
255 if (filter->block_id == VCAP_IS1 || filter->block_id == VCAP_IS2) in ocelot_flower_parse_action()
256 filter->lookup = ocelot_chain_to_lookup(chain); in ocelot_flower_parse_action()
257 if (filter->block_id == VCAP_IS2) in ocelot_flower_parse_action()
258 filter->pag = ocelot_chain_to_pag(chain); in ocelot_flower_parse_action()
260 filter->goto_target = -1; in ocelot_flower_parse_action()
261 filter->type = OCELOT_VCAP_FILTER_DUMMY; in ocelot_flower_parse_action()
264 switch (a->id) { in ocelot_flower_parse_action()
266 if (filter->block_id != VCAP_IS2) { in ocelot_flower_parse_action()
269 return -EOPNOTSUPP; in ocelot_flower_parse_action()
271 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
274 return -EOPNOTSUPP; in ocelot_flower_parse_action()
276 filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; in ocelot_flower_parse_action()
277 filter->action.port_mask = 0; in ocelot_flower_parse_action()
278 filter->action.police_ena = true; in ocelot_flower_parse_action()
279 filter->action.pol_ix = OCELOT_POLICER_DISCARD; in ocelot_flower_parse_action()
280 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
283 if (filter->block_id != VCAP_ES0 && in ocelot_flower_parse_action()
284 filter->block_id != VCAP_IS1 && in ocelot_flower_parse_action()
285 filter->block_id != VCAP_IS2) { in ocelot_flower_parse_action()
288 return -EOPNOTSUPP; in ocelot_flower_parse_action()
290 if (filter->block_id != VCAP_ES0 && in ocelot_flower_parse_action()
291 filter->goto_target != -1) { in ocelot_flower_parse_action()
294 return -EOPNOTSUPP; in ocelot_flower_parse_action()
296 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
299 if (filter->block_id != VCAP_IS2 || in ocelot_flower_parse_action()
300 filter->lookup != 0) { in ocelot_flower_parse_action()
303 return -EOPNOTSUPP; in ocelot_flower_parse_action()
305 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
308 return -EOPNOTSUPP; in ocelot_flower_parse_action()
310 filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; in ocelot_flower_parse_action()
311 filter->action.port_mask = 0; in ocelot_flower_parse_action()
312 filter->action.cpu_copy_ena = true; in ocelot_flower_parse_action()
313 filter->action.cpu_qu_num = 0; in ocelot_flower_parse_action()
314 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
315 filter->is_trap = true; in ocelot_flower_parse_action()
318 if (filter->block_id == PSFP_BLOCK_ID) { in ocelot_flower_parse_action()
319 filter->type = OCELOT_PSFP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
322 if (filter->block_id != VCAP_IS2 || in ocelot_flower_parse_action()
323 filter->lookup != 0) { in ocelot_flower_parse_action()
326 return -EOPNOTSUPP; in ocelot_flower_parse_action()
328 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
331 return -EOPNOTSUPP; in ocelot_flower_parse_action()
338 filter->action.police_ena = true; in ocelot_flower_parse_action()
340 pol_ix = a->hw_index + ocelot->vcap_pol.base; in ocelot_flower_parse_action()
341 pol_max = ocelot->vcap_pol.max; in ocelot_flower_parse_action()
343 if (ocelot->vcap_pol.max2 && pol_ix > pol_max) { in ocelot_flower_parse_action()
344 pol_ix += ocelot->vcap_pol.base2 - pol_max - 1; in ocelot_flower_parse_action()
345 pol_max = ocelot->vcap_pol.max2; in ocelot_flower_parse_action()
349 return -EINVAL; in ocelot_flower_parse_action()
351 filter->action.pol_ix = pol_ix; in ocelot_flower_parse_action()
353 rate = a->police.rate_bytes_ps; in ocelot_flower_parse_action()
354 filter->action.pol.rate = div_u64(rate, 1000) * 8; in ocelot_flower_parse_action()
355 filter->action.pol.burst = a->police.burst; in ocelot_flower_parse_action()
356 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
359 if (filter->block_id != VCAP_IS2) { in ocelot_flower_parse_action()
362 return -EOPNOTSUPP; in ocelot_flower_parse_action()
364 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
367 return -EOPNOTSUPP; in ocelot_flower_parse_action()
369 egress_port = ocelot->ops->netdev_to_port(a->dev); in ocelot_flower_parse_action()
373 return -EOPNOTSUPP; in ocelot_flower_parse_action()
375 filter->action.mask_mode = OCELOT_MASK_MODE_REDIRECT; in ocelot_flower_parse_action()
376 filter->action.port_mask = BIT(egress_port); in ocelot_flower_parse_action()
377 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
380 if (filter->block_id != VCAP_IS2) { in ocelot_flower_parse_action()
383 return -EOPNOTSUPP; in ocelot_flower_parse_action()
385 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
388 return -EOPNOTSUPP; in ocelot_flower_parse_action()
390 egress_port = ocelot->ops->netdev_to_port(a->dev); in ocelot_flower_parse_action()
394 return -EOPNOTSUPP; in ocelot_flower_parse_action()
396 filter->egress_port.value = egress_port; in ocelot_flower_parse_action()
397 filter->action.mirror_ena = true; in ocelot_flower_parse_action()
398 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
401 if (filter->block_id != VCAP_IS1) { in ocelot_flower_parse_action()
404 return -EOPNOTSUPP; in ocelot_flower_parse_action()
406 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
409 return -EOPNOTSUPP; in ocelot_flower_parse_action()
411 filter->action.vlan_pop_cnt_ena = true; in ocelot_flower_parse_action()
412 filter->action.vlan_pop_cnt++; in ocelot_flower_parse_action()
413 if (filter->action.vlan_pop_cnt > 2) { in ocelot_flower_parse_action()
416 return -EOPNOTSUPP; in ocelot_flower_parse_action()
418 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
421 if (filter->block_id == VCAP_IS1) { in ocelot_flower_parse_action()
425 } else if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_action()
431 err = -EOPNOTSUPP; in ocelot_flower_parse_action()
437 if (filter->block_id != VCAP_IS1) { in ocelot_flower_parse_action()
440 return -EOPNOTSUPP; in ocelot_flower_parse_action()
442 if (filter->goto_target != -1) { in ocelot_flower_parse_action()
445 return -EOPNOTSUPP; in ocelot_flower_parse_action()
447 filter->action.qos_ena = true; in ocelot_flower_parse_action()
448 filter->action.qos_val = a->priority; in ocelot_flower_parse_action()
449 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
452 filter->goto_target = a->chain_index; in ocelot_flower_parse_action()
454 if (filter->block_id == VCAP_IS1 && filter->lookup == 2) { in ocelot_flower_parse_action()
455 int pag = ocelot_chain_to_pag(filter->goto_target); in ocelot_flower_parse_action()
457 filter->action.pag_override_mask = 0xff; in ocelot_flower_parse_action()
458 filter->action.pag_val = pag; in ocelot_flower_parse_action()
459 filter->type = OCELOT_VCAP_FILTER_PAG; in ocelot_flower_parse_action()
463 if (filter->block_id != VCAP_ES0) { in ocelot_flower_parse_action()
466 return -EOPNOTSUPP; in ocelot_flower_parse_action()
468 switch (ntohs(a->vlan.proto)) { in ocelot_flower_parse_action()
478 return -EOPNOTSUPP; in ocelot_flower_parse_action()
480 filter->action.tag_a_tpid_sel = tpid; in ocelot_flower_parse_action()
481 filter->action.push_outer_tag = OCELOT_ES0_TAG; in ocelot_flower_parse_action()
482 filter->action.tag_a_vid_sel = OCELOT_ES0_VID; in ocelot_flower_parse_action()
483 filter->action.vid_a_val = a->vlan.vid; in ocelot_flower_parse_action()
484 filter->action.pcp_a_val = a->vlan.prio; in ocelot_flower_parse_action()
485 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
488 if (filter->block_id != PSFP_BLOCK_ID) { in ocelot_flower_parse_action()
491 return -EOPNOTSUPP; in ocelot_flower_parse_action()
493 filter->type = OCELOT_PSFP_FILTER_OFFLOAD; in ocelot_flower_parse_action()
497 return -EOPNOTSUPP; in ocelot_flower_parse_action()
501 if (filter->goto_target == -1) { in ocelot_flower_parse_action()
502 if ((filter->block_id == VCAP_IS2 && filter->lookup == 1) || in ocelot_flower_parse_action()
503 chain == 0 || filter->block_id == PSFP_BLOCK_ID) { in ocelot_flower_parse_action()
507 return -EOPNOTSUPP; in ocelot_flower_parse_action()
511 if (!ocelot_is_goto_target_valid(filter->goto_target, chain, ingress) && in ocelot_flower_parse_action()
514 return -EOPNOTSUPP; in ocelot_flower_parse_action()
525 const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0]; in ocelot_flower_parse_indev()
526 int key_length = vcap->keys[VCAP_ES0_IGR_PORT].length; in ocelot_flower_parse_indev()
527 struct netlink_ext_ack *extack = f->common.extack; in ocelot_flower_parse_indev()
529 struct flow_match_meta match; in ocelot_flower_parse_indev() local
532 flow_rule_match_meta(rule, &match); in ocelot_flower_parse_indev()
534 if (!match.mask->ingress_ifindex) in ocelot_flower_parse_indev()
537 if (match.mask->ingress_ifindex != 0xFFFFFFFF) { in ocelot_flower_parse_indev()
538 NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask"); in ocelot_flower_parse_indev()
539 return -EOPNOTSUPP; in ocelot_flower_parse_indev()
542 dev = ocelot->ops->port_to_netdev(ocelot, port); in ocelot_flower_parse_indev()
544 return -EINVAL; in ocelot_flower_parse_indev()
546 indev = __dev_get_by_index(dev_net(dev), match.key->ingress_ifindex); in ocelot_flower_parse_indev()
549 "Can't find the ingress port to match on"); in ocelot_flower_parse_indev()
550 return -ENOENT; in ocelot_flower_parse_indev()
553 ingress_port = ocelot->ops->netdev_to_port(indev); in ocelot_flower_parse_indev()
557 return -EOPNOTSUPP; in ocelot_flower_parse_indev()
562 return -EINVAL; in ocelot_flower_parse_indev()
565 filter->ingress_port.value = ingress_port; in ocelot_flower_parse_indev()
566 filter->ingress_port.mask = GENMASK(key_length - 1, 0); in ocelot_flower_parse_indev()
577 struct flow_dissector *dissector = rule->match.dissector; in ocelot_flower_parse_key()
578 struct netlink_ext_ack *extack = f->common.extack; in ocelot_flower_parse_key()
579 u16 proto = ntohs(f->common.protocol); in ocelot_flower_parse_key()
583 if (dissector->used_keys & in ocelot_flower_parse_key()
592 return -EOPNOTSUPP; in ocelot_flower_parse_key()
596 struct flow_match_meta match; in ocelot_flower_parse_key() local
598 flow_rule_match_meta(rule, &match); in ocelot_flower_parse_key()
599 if (match.mask->l2_miss) { in ocelot_flower_parse_key()
600 NL_SET_ERR_MSG_MOD(extack, "Can't match on \"l2_miss\""); in ocelot_flower_parse_key()
601 return -EOPNOTSUPP; in ocelot_flower_parse_key()
605 /* For VCAP ES0 (egress rewriter) we can match on the ingress port */ in ocelot_flower_parse_key()
613 struct flow_match_control match; in ocelot_flower_parse_key() local
615 flow_rule_match_control(rule, &match); in ocelot_flower_parse_key()
619 struct flow_match_vlan match; in ocelot_flower_parse_key() local
621 flow_rule_match_vlan(rule, &match); in ocelot_flower_parse_key()
622 filter->key_type = OCELOT_VCAP_KEY_ANY; in ocelot_flower_parse_key()
623 filter->vlan.vid.value = match.key->vlan_id; in ocelot_flower_parse_key()
624 filter->vlan.vid.mask = match.mask->vlan_id; in ocelot_flower_parse_key()
625 filter->vlan.pcp.value[0] = match.key->vlan_priority; in ocelot_flower_parse_key()
626 filter->vlan.pcp.mask[0] = match.mask->vlan_priority; in ocelot_flower_parse_key()
631 struct flow_match_eth_addrs match; in ocelot_flower_parse_key() local
633 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
635 "VCAP ES0 cannot match on MAC address"); in ocelot_flower_parse_key()
636 return -EOPNOTSUPP; in ocelot_flower_parse_key()
643 if ((dissector->used_keys & in ocelot_flower_parse_key()
650 return -EOPNOTSUPP; in ocelot_flower_parse_key()
652 flow_rule_match_eth_addrs(rule, &match); in ocelot_flower_parse_key()
654 if (filter->block_id == VCAP_IS1 && in ocelot_flower_parse_key()
655 !is_zero_ether_addr(match.mask->dst)) { in ocelot_flower_parse_key()
657 "Key type S1_NORMAL cannot match on destination MAC"); in ocelot_flower_parse_key()
658 return -EOPNOTSUPP; in ocelot_flower_parse_key()
661 filter->key_type = OCELOT_VCAP_KEY_ETYPE; in ocelot_flower_parse_key()
662 ether_addr_copy(filter->key.etype.dmac.value, in ocelot_flower_parse_key()
663 match.key->dst); in ocelot_flower_parse_key()
664 ether_addr_copy(filter->key.etype.smac.value, in ocelot_flower_parse_key()
665 match.key->src); in ocelot_flower_parse_key()
666 ether_addr_copy(filter->key.etype.dmac.mask, in ocelot_flower_parse_key()
667 match.mask->dst); in ocelot_flower_parse_key()
668 ether_addr_copy(filter->key.etype.smac.mask, in ocelot_flower_parse_key()
669 match.mask->src); in ocelot_flower_parse_key()
674 struct flow_match_basic match; in ocelot_flower_parse_key() local
676 flow_rule_match_basic(rule, &match); in ocelot_flower_parse_key()
677 if (ntohs(match.key->n_proto) == ETH_P_IP) { in ocelot_flower_parse_key()
678 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
680 "VCAP ES0 cannot match on IP protocol"); in ocelot_flower_parse_key()
681 return -EOPNOTSUPP; in ocelot_flower_parse_key()
684 filter->key_type = OCELOT_VCAP_KEY_IPV4; in ocelot_flower_parse_key()
685 filter->key.ipv4.proto.value[0] = in ocelot_flower_parse_key()
686 match.key->ip_proto; in ocelot_flower_parse_key()
687 filter->key.ipv4.proto.mask[0] = in ocelot_flower_parse_key()
688 match.mask->ip_proto; in ocelot_flower_parse_key()
691 if (ntohs(match.key->n_proto) == ETH_P_IPV6) { in ocelot_flower_parse_key()
692 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
694 "VCAP ES0 cannot match on IP protocol"); in ocelot_flower_parse_key()
695 return -EOPNOTSUPP; in ocelot_flower_parse_key()
698 filter->key_type = OCELOT_VCAP_KEY_IPV6; in ocelot_flower_parse_key()
699 filter->key.ipv6.proto.value[0] = in ocelot_flower_parse_key()
700 match.key->ip_proto; in ocelot_flower_parse_key()
701 filter->key.ipv6.proto.mask[0] = in ocelot_flower_parse_key()
702 match.mask->ip_proto; in ocelot_flower_parse_key()
709 struct flow_match_ipv4_addrs match; in ocelot_flower_parse_key() local
712 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
714 "VCAP ES0 cannot match on IP address"); in ocelot_flower_parse_key()
715 return -EOPNOTSUPP; in ocelot_flower_parse_key()
718 flow_rule_match_ipv4_addrs(rule, &match); in ocelot_flower_parse_key()
720 if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) { in ocelot_flower_parse_key()
722 "Key type S1_NORMAL cannot match on destination IP"); in ocelot_flower_parse_key()
723 return -EOPNOTSUPP; in ocelot_flower_parse_key()
726 tmp = &filter->key.ipv4.sip.value.addr[0]; in ocelot_flower_parse_key()
727 memcpy(tmp, &match.key->src, 4); in ocelot_flower_parse_key()
729 tmp = &filter->key.ipv4.sip.mask.addr[0]; in ocelot_flower_parse_key()
730 memcpy(tmp, &match.mask->src, 4); in ocelot_flower_parse_key()
732 tmp = &filter->key.ipv4.dip.value.addr[0]; in ocelot_flower_parse_key()
733 memcpy(tmp, &match.key->dst, 4); in ocelot_flower_parse_key()
735 tmp = &filter->key.ipv4.dip.mask.addr[0]; in ocelot_flower_parse_key()
736 memcpy(tmp, &match.mask->dst, 4); in ocelot_flower_parse_key()
742 return -EOPNOTSUPP; in ocelot_flower_parse_key()
746 struct flow_match_ports match; in ocelot_flower_parse_key() local
748 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
750 "VCAP ES0 cannot match on L4 ports"); in ocelot_flower_parse_key()
751 return -EOPNOTSUPP; in ocelot_flower_parse_key()
754 flow_rule_match_ports(rule, &match); in ocelot_flower_parse_key()
755 filter->key.ipv4.sport.value = ntohs(match.key->src); in ocelot_flower_parse_key()
756 filter->key.ipv4.sport.mask = ntohs(match.mask->src); in ocelot_flower_parse_key()
757 filter->key.ipv4.dport.value = ntohs(match.key->dst); in ocelot_flower_parse_key()
758 filter->key.ipv4.dport.mask = ntohs(match.mask->dst); in ocelot_flower_parse_key()
764 if (filter->block_id == VCAP_ES0) { in ocelot_flower_parse_key()
766 "VCAP ES0 cannot match on L2 proto"); in ocelot_flower_parse_key()
767 return -EOPNOTSUPP; in ocelot_flower_parse_key()
772 return -EOPNOTSUPP; in ocelot_flower_parse_key()
773 filter->key_type = OCELOT_VCAP_KEY_ETYPE; in ocelot_flower_parse_key()
774 *(__be16 *)filter->key.etype.etype.value = htons(proto); in ocelot_flower_parse_key()
775 *(__be16 *)filter->key.etype.etype.mask = htons(0xffff); in ocelot_flower_parse_key()
788 filter->prio = f->common.prio; in ocelot_flower_parse()
789 filter->id.cookie = f->cookie; in ocelot_flower_parse()
790 filter->id.tc_offload = true; in ocelot_flower_parse()
796 /* PSFP filter need to parse key by stream identification function. */ in ocelot_flower_parse()
797 if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD) in ocelot_flower_parse()
814 filter->ingress_port_mask = BIT(port); in ocelot_vcap_filter_create()
816 const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0]; in ocelot_vcap_filter_create()
817 int key_length = vcap->keys[VCAP_ES0_EGR_PORT].length; in ocelot_vcap_filter_create()
819 filter->egress_port.value = port; in ocelot_vcap_filter_create()
820 filter->egress_port.mask = GENMASK(key_length - 1, 0); in ocelot_vcap_filter_create()
829 list_add(&filter->list, &ocelot->dummy_rules); in ocelot_vcap_dummy_filter_add()
837 list_del(&filter->list); in ocelot_vcap_dummy_filter_del()
852 if (filter->block_id != VCAP_ES0 || in ocelot_flower_patch_es0_vlan_modify()
853 filter->action.tag_a_vid_sel != OCELOT_ES0_VID_PLUS_CLASSIFIED_VID) in ocelot_flower_patch_es0_vlan_modify()
856 if (filter->vlan.vid.mask != VLAN_VID_MASK) { in ocelot_flower_patch_es0_vlan_modify()
859 return -EOPNOTSUPP; in ocelot_flower_patch_es0_vlan_modify()
862 filter->action.vid_a_val -= filter->vlan.vid.value; in ocelot_flower_patch_es0_vlan_modify()
863 filter->action.vid_a_val &= VLAN_VID_MASK; in ocelot_flower_patch_es0_vlan_modify()
871 struct netlink_ext_ack *extack = f->common.extack; in ocelot_cls_flower_replace()
873 int chain = f->common.chain_index; in ocelot_cls_flower_replace()
878 return -EOPNOTSUPP; in ocelot_cls_flower_replace()
884 return -EOPNOTSUPP; in ocelot_cls_flower_replace()
887 filter = ocelot_vcap_block_find_filter_by_id(&ocelot->block[block_id], in ocelot_cls_flower_replace()
888 f->cookie, true); in ocelot_cls_flower_replace()
893 return -EOPNOTSUPP; in ocelot_cls_flower_replace()
896 filter->ingress_port_mask |= BIT(port); in ocelot_cls_flower_replace()
904 return -ENOMEM; in ocelot_cls_flower_replace()
918 /* The non-optional GOTOs for the TCAM skeleton don't need in ocelot_cls_flower_replace()
921 if (filter->type == OCELOT_VCAP_FILTER_DUMMY) in ocelot_cls_flower_replace()
924 if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD) { in ocelot_cls_flower_replace()
926 if (ocelot->ops->psfp_filter_add) in ocelot_cls_flower_replace()
927 return ocelot->ops->psfp_filter_add(ocelot, port, f); in ocelot_cls_flower_replace()
930 return -EOPNOTSUPP; in ocelot_cls_flower_replace()
933 return ocelot_vcap_filter_add(ocelot, filter, f->common.extack); in ocelot_cls_flower_replace()
944 block_id = ocelot_chain_to_block(f->common.chain_index, ingress); in ocelot_cls_flower_destroy()
949 if (ocelot->ops->psfp_filter_del) in ocelot_cls_flower_destroy()
950 return ocelot->ops->psfp_filter_del(ocelot, f); in ocelot_cls_flower_destroy()
952 return -EOPNOTSUPP; in ocelot_cls_flower_destroy()
955 block = &ocelot->block[block_id]; in ocelot_cls_flower_destroy()
957 filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true); in ocelot_cls_flower_destroy()
961 if (filter->type == OCELOT_VCAP_FILTER_DUMMY) in ocelot_cls_flower_destroy()
965 filter->ingress_port_mask &= ~BIT(port); in ocelot_cls_flower_destroy()
966 if (filter->ingress_port_mask) in ocelot_cls_flower_destroy()
982 block_id = ocelot_chain_to_block(f->common.chain_index, ingress); in ocelot_cls_flower_stats()
987 if (ocelot->ops->psfp_stats_get) { in ocelot_cls_flower_stats()
988 ret = ocelot->ops->psfp_stats_get(ocelot, f, &stats); in ocelot_cls_flower_stats()
995 return -EOPNOTSUPP; in ocelot_cls_flower_stats()
998 block = &ocelot->block[block_id]; in ocelot_cls_flower_stats()
1000 filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true); in ocelot_cls_flower_stats()
1001 if (!filter || filter->type == OCELOT_VCAP_FILTER_DUMMY) in ocelot_cls_flower_stats()
1008 stats.pkts = filter->stats.pkts; in ocelot_cls_flower_stats()
1011 flow_stats_update(&f->stats, 0x0, stats.pkts, stats.drops, 0x0, in ocelot_cls_flower_stats()