Lines Matching +full:8 +full:- +full:port
1 // SPDX-License-Identifier: GPL-2.0-or-later
23 int port; member
50 CFG_UDF_EOL2 | 8,
53 /* End of L3, byte offset 0, src port */
55 /* End of L3, byte offset 2, dst port */
70 /* End of L2, byte offset 8, src IP[0:15] */
79 CFG_UDF_EOL2 | 8,
86 /* End of L3, byte offset 0, src port */
110 /* End of L3, byte offset 2, dst port */
133 return GENMASK(num_udf - 1, 0) >> (UDFS_PER_SLICE - 1); in udf_upper_bits()
138 return (u8)GENMASK(num_udf - 1, 0); in udf_lower_bits()
148 slice_layout = &l->udfs[slice_idx]; in bcm_sf2_get_slice_number()
149 if (memcmp(slice_layout->slices, zero_slice, in bcm_sf2_get_slice_number()
161 u32 offset = layout->udfs[slice_num].base_offset; in bcm_sf2_cfp_udf_set()
165 core_writel(priv, layout->udfs[slice_num].slices[i], in bcm_sf2_cfp_udf_set()
185 } while (timeout--); in bcm_sf2_cfp_op()
188 return -ETIMEDOUT; in bcm_sf2_cfp_op()
198 WARN_ON(addr >= priv->num_cfp_rules); in bcm_sf2_cfp_rule_addr_set()
209 return priv->num_cfp_rules - 1; in bcm_sf2_cfp_rule_size()
223 * which port and queue this should be forwarded to. in bcm_sf2_cfp_act_pol_set()
232 /* Enable looping back to the original port */ in bcm_sf2_cfp_act_pol_set()
273 * S-Tag [23:8] in bcm_sf2_cfp_slice_ipv4()
274 * C-Tag [7:0] in bcm_sf2_cfp_slice_ipv4()
276 reg = udf_lower_bits(num_udf) << 24 | be16_to_cpu(vlan_tci) >> 8; in bcm_sf2_cfp_slice_ipv4()
282 /* C-Tag [31:24] in bcm_sf2_cfp_slice_ipv4()
283 * UDF_n_A8 [23:8] in bcm_sf2_cfp_slice_ipv4()
294 * UDF_n_A6 [23:8] in bcm_sf2_cfp_slice_ipv4()
297 reg = be16_to_cpu(ports->dst) >> 8; in bcm_sf2_cfp_slice_ipv4()
305 * UDF_n_A4 [23:8] in bcm_sf2_cfp_slice_ipv4()
308 reg = (be16_to_cpu(ports->dst) & 0xff) << 24 | in bcm_sf2_cfp_slice_ipv4()
309 (u32)be16_to_cpu(ports->src) << 8 | in bcm_sf2_cfp_slice_ipv4()
310 (be32_to_cpu(addrs->dst) & 0x0000ff00) >> 8; in bcm_sf2_cfp_slice_ipv4()
318 * UDF_n_A2 [23:8] in bcm_sf2_cfp_slice_ipv4()
321 reg = (u32)(be32_to_cpu(addrs->dst) & 0xff) << 24 | in bcm_sf2_cfp_slice_ipv4()
322 (u32)(be32_to_cpu(addrs->dst) >> 16) << 8 | in bcm_sf2_cfp_slice_ipv4()
323 (be32_to_cpu(addrs->src) & 0x0000ff00) >> 8; in bcm_sf2_cfp_slice_ipv4()
331 * UDF_n_A0 [23:8] in bcm_sf2_cfp_slice_ipv4()
336 reg = (u32)(be32_to_cpu(addrs->src) & 0xff) << 24 | in bcm_sf2_cfp_slice_ipv4()
337 (u32)(be32_to_cpu(addrs->src) >> 16) << 8 | in bcm_sf2_cfp_slice_ipv4()
346 static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_ipv4_rule_set() argument
364 switch (fs->flow_type & ~FLOW_EXT) { in bcm_sf2_cfp_ipv4_rule_set()
372 return -EINVAL; in bcm_sf2_cfp_ipv4_rule_set()
375 ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); in bcm_sf2_cfp_ipv4_rule_set()
378 if (fs->flow_type & FLOW_EXT) { in bcm_sf2_cfp_ipv4_rule_set()
379 vlan_tci = fs->h_ext.vlan_tci; in bcm_sf2_cfp_ipv4_rule_set()
380 vlan_m_tci = fs->m_ext.vlan_tci; in bcm_sf2_cfp_ipv4_rule_set()
384 if (fs->location == RX_CLS_LOC_ANY) in bcm_sf2_cfp_ipv4_rule_set()
385 rule_index = find_first_zero_bit(priv->cfp.used, in bcm_sf2_cfp_ipv4_rule_set()
386 priv->num_cfp_rules); in bcm_sf2_cfp_ipv4_rule_set()
388 rule_index = fs->location; in bcm_sf2_cfp_ipv4_rule_set()
391 return -ENOSPC; in bcm_sf2_cfp_ipv4_rule_set()
398 flow_rule_match_ipv4_addrs(flow->rule, &ipv4); in bcm_sf2_cfp_ipv4_rule_set()
399 flow_rule_match_ports(flow->rule, &ports); in bcm_sf2_cfp_ipv4_rule_set()
400 flow_rule_match_ip(flow->rule, &ip); in bcm_sf2_cfp_ipv4_rule_set()
406 ret = -EINVAL; in bcm_sf2_cfp_ipv4_rule_set()
410 num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); in bcm_sf2_cfp_ipv4_rule_set()
415 /* Apply to all packets received through this port */ in bcm_sf2_cfp_ipv4_rule_set()
416 core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7)); in bcm_sf2_cfp_ipv4_rule_set()
418 /* Source port map match */ in bcm_sf2_cfp_ipv4_rule_set()
421 /* S-Tag status [31:30] in bcm_sf2_cfp_ipv4_rule_set()
422 * C-Tag status [29:28] in bcm_sf2_cfp_ipv4_rule_set()
433 * UDF_Valid[8] [0] in bcm_sf2_cfp_ipv4_rule_set()
435 core_writel(priv, ip.key->tos << IPTOS_SHIFT | in bcm_sf2_cfp_ipv4_rule_set()
441 core_writel(priv, layout->udfs[slice_num].mask_value | in bcm_sf2_cfp_ipv4_rule_set()
460 ret = bcm_sf2_cfp_act_pol_set(priv, rule_index, port, port_num, in bcm_sf2_cfp_ipv4_rule_set()
467 reg |= BIT(port); in bcm_sf2_cfp_ipv4_rule_set()
471 set_bit(rule_index, priv->cfp.used); in bcm_sf2_cfp_ipv4_rule_set()
472 set_bit(rule_index, priv->cfp.unique); in bcm_sf2_cfp_ipv4_rule_set()
473 fs->location = rule_index; in bcm_sf2_cfp_ipv4_rule_set()
483 const __be32 *ip6_addr, const __be16 port, in bcm_sf2_cfp_slice_ipv6() argument
491 * S-Tag [23:8] in bcm_sf2_cfp_slice_ipv6()
492 * C-Tag [7:0] in bcm_sf2_cfp_slice_ipv6()
494 reg = udf_bits << 24 | be16_to_cpu(vlan_tci) >> 8; in bcm_sf2_cfp_slice_ipv6()
500 /* C-Tag [31:24] in bcm_sf2_cfp_slice_ipv6()
501 * UDF_n_B8 [23:8] (port) in bcm_sf2_cfp_slice_ipv6()
502 * UDF_n_B7 (upper) [7:0] (addr[15:8]) in bcm_sf2_cfp_slice_ipv6()
505 val = (u32)be16_to_cpu(port) << 8 | ((reg >> 8) & 0xff); in bcm_sf2_cfp_slice_ipv6()
514 * UDF_n_B6 [23:8] (addr[31:16]) in bcm_sf2_cfp_slice_ipv6()
518 val = (u32)(reg & 0xff) << 24 | (u32)(reg >> 16) << 8 | in bcm_sf2_cfp_slice_ipv6()
519 ((tmp >> 8) & 0xff); in bcm_sf2_cfp_slice_ipv6()
527 * UDF_n_B4 [23:8] (addr[63:48]) in bcm_sf2_cfp_slice_ipv6()
531 val = (u32)(tmp & 0xff) << 24 | (u32)(tmp >> 16) << 8 | in bcm_sf2_cfp_slice_ipv6()
532 ((reg >> 8) & 0xff); in bcm_sf2_cfp_slice_ipv6()
540 * UDF_n_B2 [23:8] (addr[95:80]) in bcm_sf2_cfp_slice_ipv6()
544 val = (u32)(reg & 0xff) << 24 | (u32)(reg >> 16) << 8 | in bcm_sf2_cfp_slice_ipv6()
545 ((tmp >> 8) & 0xff); in bcm_sf2_cfp_slice_ipv6()
553 * UDF_n_B0 [23:8] (addr[127:112]) in bcm_sf2_cfp_slice_ipv6()
558 reg = (u32)(tmp & 0xff) << 24 | (u32)(tmp >> 16) << 8 | in bcm_sf2_cfp_slice_ipv6()
568 int port, u32 location) in bcm_sf2_cfp_rule_find() argument
572 list_for_each_entry(rule, &priv->cfp.rules_list, next) { in bcm_sf2_cfp_rule_find()
573 if (rule->port == port && rule->fs.location == location) in bcm_sf2_cfp_rule_find()
580 static int bcm_sf2_cfp_rule_cmp(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_rule_cmp() argument
587 if (list_empty(&priv->cfp.rules_list)) in bcm_sf2_cfp_rule_cmp()
590 list_for_each_entry(rule, &priv->cfp.rules_list, next) { in bcm_sf2_cfp_rule_cmp()
592 if (rule->port != port) in bcm_sf2_cfp_rule_cmp()
595 if (rule->fs.flow_type != fs->flow_type || in bcm_sf2_cfp_rule_cmp()
596 rule->fs.ring_cookie != fs->ring_cookie || in bcm_sf2_cfp_rule_cmp()
597 rule->fs.h_ext.data[0] != fs->h_ext.data[0]) in bcm_sf2_cfp_rule_cmp()
600 switch (fs->flow_type & ~FLOW_EXT) { in bcm_sf2_cfp_rule_cmp()
613 ret = memcmp(&rule->fs.h_u, &fs->h_u, fs_size); in bcm_sf2_cfp_rule_cmp()
614 ret |= memcmp(&rule->fs.m_u, &fs->m_u, fs_size); in bcm_sf2_cfp_rule_cmp()
616 if (rule->fs.flow_type & FLOW_EXT) { in bcm_sf2_cfp_rule_cmp()
617 ret |= rule->fs.h_ext.vlan_tci != fs->h_ext.vlan_tci; in bcm_sf2_cfp_rule_cmp()
618 ret |= rule->fs.m_ext.vlan_tci != fs->m_ext.vlan_tci; in bcm_sf2_cfp_rule_cmp()
627 static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_ipv6_rule_set() argument
644 switch (fs->flow_type & ~FLOW_EXT) { in bcm_sf2_cfp_ipv6_rule_set()
652 return -EINVAL; in bcm_sf2_cfp_ipv6_rule_set()
655 ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); in bcm_sf2_cfp_ipv6_rule_set()
658 if (fs->flow_type & FLOW_EXT) { in bcm_sf2_cfp_ipv6_rule_set()
659 vlan_tci = fs->h_ext.vlan_tci; in bcm_sf2_cfp_ipv6_rule_set()
660 vlan_m_tci = fs->m_ext.vlan_tci; in bcm_sf2_cfp_ipv6_rule_set()
666 return -EINVAL; in bcm_sf2_cfp_ipv6_rule_set()
668 num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); in bcm_sf2_cfp_ipv6_rule_set()
671 * from, which is what we will return to user-space, and a second one in bcm_sf2_cfp_ipv6_rule_set()
674 * available bit. We return the second half as fs->location because in bcm_sf2_cfp_ipv6_rule_set()
682 if (fs->location == RX_CLS_LOC_ANY) in bcm_sf2_cfp_ipv6_rule_set()
683 rule_index[1] = find_first_zero_bit(priv->cfp.used, in bcm_sf2_cfp_ipv6_rule_set()
684 priv->num_cfp_rules); in bcm_sf2_cfp_ipv6_rule_set()
686 rule_index[1] = fs->location; in bcm_sf2_cfp_ipv6_rule_set()
688 return -ENOSPC; in bcm_sf2_cfp_ipv6_rule_set()
693 set_bit(rule_index[1], priv->cfp.used); in bcm_sf2_cfp_ipv6_rule_set()
695 rule_index[0] = find_first_zero_bit(priv->cfp.used, in bcm_sf2_cfp_ipv6_rule_set()
696 priv->num_cfp_rules); in bcm_sf2_cfp_ipv6_rule_set()
698 ret = -ENOSPC; in bcm_sf2_cfp_ipv6_rule_set()
708 flow_rule_match_ipv6_addrs(flow->rule, &ipv6); in bcm_sf2_cfp_ipv6_rule_set()
709 flow_rule_match_ports(flow->rule, &ports); in bcm_sf2_cfp_ipv6_rule_set()
714 /* Apply to all packets received through this port */ in bcm_sf2_cfp_ipv6_rule_set()
715 core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7)); in bcm_sf2_cfp_ipv6_rule_set()
717 /* Source port map match */ in bcm_sf2_cfp_ipv6_rule_set()
720 /* S-Tag status [31:30] in bcm_sf2_cfp_ipv6_rule_set()
721 * C-Tag status [29:28] in bcm_sf2_cfp_ipv6_rule_set()
732 * UDF_Valid[8] [0] in bcm_sf2_cfp_ipv6_rule_set()
739 * UDF_Valid[8] in bcm_sf2_cfp_ipv6_rule_set()
741 reg = layout->udfs[slice_num].mask_value | udf_upper_bits(num_udf); in bcm_sf2_cfp_ipv6_rule_set()
744 /* Slice the IPv6 source address and port */ in bcm_sf2_cfp_ipv6_rule_set()
745 bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32, in bcm_sf2_cfp_ipv6_rule_set()
746 ports.key->src, vlan_tci, slice_num, in bcm_sf2_cfp_ipv6_rule_set()
748 bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32, in bcm_sf2_cfp_ipv6_rule_set()
749 ports.mask->src, vlan_m_tci, SLICE_NUM_MASK, in bcm_sf2_cfp_ipv6_rule_set()
762 ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port, port_num, in bcm_sf2_cfp_ipv6_rule_set()
770 ret = -EINVAL; in bcm_sf2_cfp_ipv6_rule_set()
774 num_udf = bcm_sf2_get_num_udf_slices(layout->udfs[slice_num].slices); in bcm_sf2_cfp_ipv6_rule_set()
779 /* Chained rule, source port match is coming from the rule we are in bcm_sf2_cfp_ipv6_rule_set()
788 * UDF_Valid[11:8] [19:16] in bcm_sf2_cfp_ipv6_rule_set()
789 * UDF_Valid[7:0] [15:8] in bcm_sf2_cfp_ipv6_rule_set()
793 udf_lower_bits(num_udf) << 8; in bcm_sf2_cfp_ipv6_rule_set()
796 /* Mask all except chain ID, UDF Valid[8] and UDF Valid[7:0] */ in bcm_sf2_cfp_ipv6_rule_set()
798 udf_lower_bits(num_udf) << 8; in bcm_sf2_cfp_ipv6_rule_set()
801 bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->dst.in6_u.u6_addr32, in bcm_sf2_cfp_ipv6_rule_set()
802 ports.key->dst, 0, slice_num, in bcm_sf2_cfp_ipv6_rule_set()
804 bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->dst.in6_u.u6_addr32, in bcm_sf2_cfp_ipv6_rule_set()
805 ports.key->dst, 0, SLICE_NUM_MASK, in bcm_sf2_cfp_ipv6_rule_set()
820 ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[1], port, port_num, in bcm_sf2_cfp_ipv6_rule_set()
827 reg |= BIT(port); in bcm_sf2_cfp_ipv6_rule_set()
833 set_bit(rule_index[0], priv->cfp.used); in bcm_sf2_cfp_ipv6_rule_set()
834 set_bit(rule_index[1], priv->cfp.unique); in bcm_sf2_cfp_ipv6_rule_set()
835 fs->location = rule_index[1]; in bcm_sf2_cfp_ipv6_rule_set()
842 clear_bit(rule_index[1], priv->cfp.used); in bcm_sf2_cfp_ipv6_rule_set()
846 static int bcm_sf2_cfp_rule_insert(struct dsa_switch *ds, int port, in bcm_sf2_cfp_rule_insert() argument
850 s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; in bcm_sf2_cfp_rule_insert()
851 __u64 ring_cookie = fs->ring_cookie; in bcm_sf2_cfp_rule_insert()
857 /* This rule is a Wake-on-LAN filter and we must specifically in bcm_sf2_cfp_rule_insert()
858 * target the CPU port in order for it to be working. in bcm_sf2_cfp_rule_insert()
864 * destination port is enabled and that we are within the in bcm_sf2_cfp_rule_insert()
872 port_num >= priv->hw_params.num_ports) in bcm_sf2_cfp_rule_insert()
873 return -EINVAL; in bcm_sf2_cfp_rule_insert()
876 * the matching and have it tagged or untagged on the destination port, in bcm_sf2_cfp_rule_insert()
881 if (fs->flow_type & FLOW_EXT) { in bcm_sf2_cfp_rule_insert()
883 if ((be16_to_cpu(fs->m_ext.vlan_tci) & VLAN_VID_MASK) != in bcm_sf2_cfp_rule_insert()
885 return -EINVAL; in bcm_sf2_cfp_rule_insert()
887 vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK; in bcm_sf2_cfp_rule_insert()
889 if (be32_to_cpu(fs->h_ext.data[1]) & 1) in bcm_sf2_cfp_rule_insert()
894 ret = ds->ops->port_vlan_add(ds, port_num, &vlan, NULL); in bcm_sf2_cfp_rule_insert()
900 * We have a small oddity where Port 6 just does not have a in bcm_sf2_cfp_rule_insert()
905 port_num -= 1; in bcm_sf2_cfp_rule_insert()
907 switch (fs->flow_type & ~FLOW_EXT) { in bcm_sf2_cfp_rule_insert()
910 ret = bcm_sf2_cfp_ipv4_rule_set(priv, port, port_num, in bcm_sf2_cfp_rule_insert()
915 ret = bcm_sf2_cfp_ipv6_rule_set(priv, port, port_num, in bcm_sf2_cfp_rule_insert()
919 ret = -EINVAL; in bcm_sf2_cfp_rule_insert()
926 static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, in bcm_sf2_cfp_rule_set() argument
931 int ret = -EINVAL; in bcm_sf2_cfp_rule_set()
934 if (fs->flow_type & FLOW_MAC_EXT) in bcm_sf2_cfp_rule_set()
935 return -EINVAL; in bcm_sf2_cfp_rule_set()
937 if (fs->location != RX_CLS_LOC_ANY && in bcm_sf2_cfp_rule_set()
938 fs->location > bcm_sf2_cfp_rule_size(priv)) in bcm_sf2_cfp_rule_set()
939 return -EINVAL; in bcm_sf2_cfp_rule_set()
941 if ((fs->flow_type & FLOW_EXT) && in bcm_sf2_cfp_rule_set()
942 !(ds->ops->port_vlan_add || ds->ops->port_vlan_del)) in bcm_sf2_cfp_rule_set()
943 return -EOPNOTSUPP; in bcm_sf2_cfp_rule_set()
945 if (fs->location != RX_CLS_LOC_ANY && in bcm_sf2_cfp_rule_set()
946 test_bit(fs->location, priv->cfp.used)) in bcm_sf2_cfp_rule_set()
947 return -EBUSY; in bcm_sf2_cfp_rule_set()
949 ret = bcm_sf2_cfp_rule_cmp(priv, port, fs); in bcm_sf2_cfp_rule_set()
951 return -EEXIST; in bcm_sf2_cfp_rule_set()
955 return -ENOMEM; in bcm_sf2_cfp_rule_set()
957 ret = bcm_sf2_cfp_rule_insert(ds, port, fs); in bcm_sf2_cfp_rule_set()
963 rule->port = port; in bcm_sf2_cfp_rule_set()
964 memcpy(&rule->fs, fs, sizeof(*fs)); in bcm_sf2_cfp_rule_set()
965 list_add_tail(&rule->next, &priv->cfp.rules_list); in bcm_sf2_cfp_rule_set()
970 static int bcm_sf2_cfp_rule_del_one(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_rule_del_one() argument
1001 clear_bit(loc, priv->cfp.used); in bcm_sf2_cfp_rule_del_one()
1002 clear_bit(loc, priv->cfp.unique); in bcm_sf2_cfp_rule_del_one()
1007 static int bcm_sf2_cfp_rule_remove(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_rule_remove() argument
1013 ret = bcm_sf2_cfp_rule_del_one(priv, port, loc, &next_loc); in bcm_sf2_cfp_rule_remove()
1019 ret = bcm_sf2_cfp_rule_del_one(priv, port, next_loc, NULL); in bcm_sf2_cfp_rule_remove()
1024 static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 loc) in bcm_sf2_cfp_rule_del() argument
1030 return -EINVAL; in bcm_sf2_cfp_rule_del()
1036 if (!test_bit(loc, priv->cfp.unique) || loc == 0) in bcm_sf2_cfp_rule_del()
1037 return -EINVAL; in bcm_sf2_cfp_rule_del()
1039 rule = bcm_sf2_cfp_rule_find(priv, port, loc); in bcm_sf2_cfp_rule_del()
1041 return -EINVAL; in bcm_sf2_cfp_rule_del()
1043 ret = bcm_sf2_cfp_rule_remove(priv, port, loc); in bcm_sf2_cfp_rule_del()
1045 list_del(&rule->next); in bcm_sf2_cfp_rule_del()
1055 for (i = 0; i < sizeof(flow->m_u); i++) in bcm_sf2_invert_masks()
1056 flow->m_u.hdata[i] ^= 0xff; in bcm_sf2_invert_masks()
1058 flow->m_ext.vlan_etype ^= cpu_to_be16(~0); in bcm_sf2_invert_masks()
1059 flow->m_ext.vlan_tci ^= cpu_to_be16(~0); in bcm_sf2_invert_masks()
1060 flow->m_ext.data[0] ^= cpu_to_be32(~0); in bcm_sf2_invert_masks()
1061 flow->m_ext.data[1] ^= cpu_to_be32(~0); in bcm_sf2_invert_masks()
1064 static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port, in bcm_sf2_cfp_rule_get() argument
1069 rule = bcm_sf2_cfp_rule_find(priv, port, nfc->fs.location); in bcm_sf2_cfp_rule_get()
1071 return -EINVAL; in bcm_sf2_cfp_rule_get()
1073 memcpy(&nfc->fs, &rule->fs, sizeof(rule->fs)); in bcm_sf2_cfp_rule_get()
1075 bcm_sf2_invert_masks(&nfc->fs); in bcm_sf2_cfp_rule_get()
1078 nfc->data = bcm_sf2_cfp_rule_size(priv); in bcm_sf2_cfp_rule_get()
1085 int port, struct ethtool_rxnfc *nfc, in bcm_sf2_cfp_rule_get_all() argument
1090 for_each_set_bit_from(index, priv->cfp.unique, priv->num_cfp_rules) { in bcm_sf2_cfp_rule_get_all()
1096 nfc->data = bcm_sf2_cfp_rule_size(priv); in bcm_sf2_cfp_rule_get_all()
1097 nfc->rule_cnt = rules_cnt; in bcm_sf2_cfp_rule_get_all()
1102 int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port, in bcm_sf2_get_rxnfc() argument
1105 struct net_device *p = dsa_port_to_conduit(dsa_to_port(ds, port)); in bcm_sf2_get_rxnfc()
1109 mutex_lock(&priv->cfp.lock); in bcm_sf2_get_rxnfc()
1111 switch (nfc->cmd) { in bcm_sf2_get_rxnfc()
1114 nfc->rule_cnt = bitmap_weight(priv->cfp.unique, in bcm_sf2_get_rxnfc()
1115 priv->num_cfp_rules) - 1; in bcm_sf2_get_rxnfc()
1117 nfc->data |= RX_CLS_LOC_SPECIAL; in bcm_sf2_get_rxnfc()
1120 ret = bcm_sf2_cfp_rule_get(priv, port, nfc); in bcm_sf2_get_rxnfc()
1123 ret = bcm_sf2_cfp_rule_get_all(priv, port, nfc, rule_locs); in bcm_sf2_get_rxnfc()
1126 ret = -EOPNOTSUPP; in bcm_sf2_get_rxnfc()
1130 mutex_unlock(&priv->cfp.lock); in bcm_sf2_get_rxnfc()
1136 if (p->ethtool_ops->get_rxnfc) { in bcm_sf2_get_rxnfc()
1137 ret = p->ethtool_ops->get_rxnfc(p, nfc, rule_locs); in bcm_sf2_get_rxnfc()
1138 if (ret == -EOPNOTSUPP) in bcm_sf2_get_rxnfc()
1145 int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port, in bcm_sf2_set_rxnfc() argument
1148 struct net_device *p = dsa_port_to_conduit(dsa_to_port(ds, port)); in bcm_sf2_set_rxnfc()
1152 mutex_lock(&priv->cfp.lock); in bcm_sf2_set_rxnfc()
1154 switch (nfc->cmd) { in bcm_sf2_set_rxnfc()
1156 ret = bcm_sf2_cfp_rule_set(ds, port, &nfc->fs); in bcm_sf2_set_rxnfc()
1160 ret = bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location); in bcm_sf2_set_rxnfc()
1163 ret = -EOPNOTSUPP; in bcm_sf2_set_rxnfc()
1167 mutex_unlock(&priv->cfp.lock); in bcm_sf2_set_rxnfc()
1175 if (p->ethtool_ops->set_rxnfc) { in bcm_sf2_set_rxnfc()
1176 ret = p->ethtool_ops->set_rxnfc(p, nfc); in bcm_sf2_set_rxnfc()
1177 if (ret && ret != -EOPNOTSUPP) { in bcm_sf2_set_rxnfc()
1178 mutex_lock(&priv->cfp.lock); in bcm_sf2_set_rxnfc()
1179 bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location); in bcm_sf2_set_rxnfc()
1180 mutex_unlock(&priv->cfp.lock); in bcm_sf2_set_rxnfc()
1204 } while (timeout--); in bcm_sf2_cfp_rst()
1207 return -ETIMEDOUT; in bcm_sf2_cfp_rst()
1217 if (list_empty(&priv->cfp.rules_list)) in bcm_sf2_cfp_exit()
1220 list_for_each_entry_safe_reverse(rule, n, &priv->cfp.rules_list, next) in bcm_sf2_cfp_exit()
1221 bcm_sf2_cfp_rule_del(priv, rule->port, rule->fs.location); in bcm_sf2_cfp_exit()
1231 if (list_empty(&priv->cfp.rules_list)) in bcm_sf2_cfp_resume()
1242 list_for_each_entry(rule, &priv->cfp.rules_list, next) { in bcm_sf2_cfp_resume()
1243 ret = bcm_sf2_cfp_rule_remove(priv, rule->port, in bcm_sf2_cfp_resume()
1244 rule->fs.location); in bcm_sf2_cfp_resume()
1246 dev_err(ds->dev, "failed to remove rule\n"); in bcm_sf2_cfp_resume()
1250 ret = bcm_sf2_cfp_rule_insert(ds, rule->port, &rule->fs); in bcm_sf2_cfp_resume()
1252 dev_err(ds->dev, "failed to restore rule\n"); in bcm_sf2_cfp_resume()
1282 void bcm_sf2_cfp_get_strings(struct dsa_switch *ds, int port, u32 stringset, in bcm_sf2_cfp_get_strings() argument
1291 for (i = 1; i < priv->num_cfp_rules; i++) in bcm_sf2_cfp_get_strings()
1297 void bcm_sf2_cfp_get_ethtool_stats(struct dsa_switch *ds, int port, in bcm_sf2_cfp_get_ethtool_stats() argument
1307 mutex_lock(&priv->cfp.lock); in bcm_sf2_cfp_get_ethtool_stats()
1308 for (i = 1; i < priv->num_cfp_rules; i++) { in bcm_sf2_cfp_get_ethtool_stats()
1309 rule = bcm_sf2_cfp_rule_find(priv, port, i); in bcm_sf2_cfp_get_ethtool_stats()
1317 ret = bcm_sf2_cfp_op(priv, stat->ram_loc | OP_SEL_READ); in bcm_sf2_cfp_get_ethtool_stats()
1321 iter = (i - 1) * s + j; in bcm_sf2_cfp_get_ethtool_stats()
1322 data[iter] = core_readl(priv, stat->offset); in bcm_sf2_cfp_get_ethtool_stats()
1326 mutex_unlock(&priv->cfp.lock); in bcm_sf2_cfp_get_ethtool_stats()
1329 int bcm_sf2_cfp_get_sset_count(struct dsa_switch *ds, int port, int sset) in bcm_sf2_cfp_get_sset_count() argument
1337 return (priv->num_cfp_rules - 1) * ARRAY_SIZE(bcm_sf2_cfp_stats); in bcm_sf2_cfp_get_sset_count()