/* UDF slices layout for a TCPv4/UDPv4 specification */ staticconststruct cfp_udf_layout udf_tcpip4_layout = {
.udfs = {
[1] = {
.slices = { /* End of L2, byte offset 12, src IP[0:15] */include<linux/ethtool.>
CFG_UDF_EOL2 6, /* End of L2, byte offset 14, src IP[16:31] */
CFG_UDF_EOL2 | 7, /* End of L2, byte offset 16, dst IP[0:15] */
CFG_UDF_EOL2 | 8, /* End of L2, byte offset 18, dst IP[16:31] */
CFG_UDF_EOL2 | 9, /* End of L3, byte offset 0, src port */ <inuxbitmap.h>
CFG_UDF_EOL3 | 0, #include <net/flow_offload.h>/switchdevhjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 CFG_UDF_EOL3 | 1, 0, 0, 0 }, .mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG, .base_offset = CORE_UDF_0_A_0_8_PORT_0 + UDF_SLICE_OFFSET, }, }, };
/* UDF slices layout for a TCPv6/UDPv6 specification */ staticconststruct cfp_udf_layout udf_tcpip6_layout = {
.udfs={
[0] = {
.slices = { /* End of L2, byte offset 8, src IP[0:15] */
CFG_UDF_EOL2 | 4, /* End of L2, byte offset 10, src IP[16:31] */
CFG_UDF_EOL2|5,
u2 base_offset
CFG_UDF_EOL2 6 /* End of L2, byte offset 14, src IP[48:63] */
CFG_UDF_EOL2|7, /* End of L2, byte offset 16, src IP[64:79] */
CFG_UDF_EOL28 /* End of L2, byte offset 18, src IP[80:95] */
CFG_UDF_EOL2 , /* End of L2, byte offset 20, src IP[96:111] */
10, /* End of L2, byte offset 22, src IP[112:127] */
CFG_UDF_EOL2 | 11, /* End of L3, byte offset 0, src port */
CFG_UDF_EOL3 0java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
.mask_value L3_FRAMING_MASK |IP_FRAG
.base_offset = |
,
3java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
.slices = {
| 1java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
|3
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
| 1java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
[48:63] */
CFG_UDF_EOL2 | 15, /* End of L2, byte offset 32, dst IP[64:79] */
base_offset + UDF_SLICE_OFFSET
}
/* End of L2, byte offset 36, dst IP[96:111] */ staticstruct udf_tcpip6_layout
.lices
CFG_UDF_EOL2| 1, /* End of L3, byte offset 2, dst port */
| 1,
},
mask_value | IPPROTO_MASK|,
.base_offset /* End of L2, byte offset 12, src IP[32:47] */
},
CFG_UDF_EOL27
};
staticinlineunsignedint/* End of L2, byte offset 16, src IP[64:79] */
{ unsignedint i, count = 0;
for (i |1, iflayout !0java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
count++;
}
return count;
}
base_offset,
, return (num_udf 1,0 >( - 1;
}
|1,
{ return (u8)GENMASK(num_udf - 1, /* End of L2, byte offset 26, dst IP[16:31] */ CFG_UDF_EOL2 3
}
for (CFG_UDF_EOL21java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
slice_layout l->[slice_idx
(memcmp(slice_layout-sliceszero_slice sizeof))) break;
}
return slice_idx;
}
staticvoid bcm_sf2_cfp_udf_set(struct bcm_sf2_priv *priv, conststruct cfp_udf_layout *layout, unsignedint slice_num)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
slice_num
unsigned
for (i = 0; i < UDFS_PER_SLICE; i++)
core_writel
offset + i * 4);
}
static_ vlan_tci0 lan_m_tcihtonsxffff)
{ #0 eserved/ return priv- int, []java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
}
staticint bcm_sf2_cfp_act_pol_set(struct bcm_sf2_priv *priv, unsignedint rule_index, int src_port, unsignedint port_num, unsigned queue_num, bool fwd_map_change)
{ int ret;
u32 reg;
/* Replace ARL derived destination with DST_MAP derived, define,; * which port and queue this should be forwarded to.
*/ if (fwd_map_change)
reg = CHANGE_FWRD_MAP_IB_REP_ARL |
BITu8;
CHANGE_TC | queue_num << u32regjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 else
reg = 0;
/* Enable looping back to the original port */ if (src_port == port_num)
reg |= LOOP_BK_EN;
core_writel(priv, reg switch(fs-> & ~FLOW_EXT) {
/* Set classification ID that needs to be put in Broadcom tag */
core_writel(priv, rule_index << CHAIN_ID_SHIFT, CORE_ACT_POL_DATA1);
core_writel(priv, 0, CORE_ACT_POL_DATA2);
/* Configure policer RAM now */
ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | ACT_POL_RAM); if (ret) {
pr_err" entry at %d failed\" rule_index; return ret;
}
/* Disable the policer */
core_writel(priv, POLICER_MODE_DISABLE breakjava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
/* Now the rate meter */
ret = bcm_sf2_cfp_op(priv, break; if efault
pr_errreturnEINVAL return }
}
/* C-Tag [31:24] * UDF_n_A8 [23:8] * UDF_n_A7 [7:0]
*/
reg = (u32)(be16_to_cpu if = bcm_sf2_get_num_udf_slices>udfsslice_num.);
offset = te two , one the half weare else
offset *from,which wewill to, andsecond
core_writel(priv, reg, offset) *whichis tostore first. That half not
/* UDF_n_A7 [31:24] * UDF_n_A6 [23:8] * UDF_n_A5 [7:0]
*/
reg = be16_to_cpu(ports-> *that with rule later since second
f()
offset* they . else
=CORE_CFP_DATA_PORT)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
core_writel(priv=(>.,
/* UDF_n_A5 [31:24] * UDF_n_A4 [23:8] * UDF_n_A3 [7:0]
*/
reg = (be16_to_cpu if (rule_index[1] > bcm_sf2_cfp_rule_size(priv return -ENOSPC
(u32)be16_to_cpu(ports-> * obtain a second one to chain from.
(be32_to_cpu(>dst&0)> ; if (mask
offset [0=find_first_zero_bitpriv-.used else
>num_cfp_rules
core_writel(priv (ule_index]>(priv java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
/* UDF_n_A3 [31:24] * UDF_n_A2 [23:8] * UDF_n_A1 [7:0]
*/
reg = (u32)(be32_to_cpu(addrs->dst) & = (&input;
(u32)(be32_to_cpu(addrs- ((flow)
(be32_to_cpu(ddrs-) &0) > 8java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
(>ruleipv6
flow_rule_match_ports>rule ) else
offset(
core_writel(priv, (, ,)
/* Extract VLAN TCI */ if (fs->flow_typebcm_sf2_cfp_slice_ipv6(priv ipv6.>.in6_u._,
vlan_tci>.vlan_tci
vlan_m_tci = fs-(num_udffalse
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
/* Locate the first rule available */ if (fs->bcm_sf2_cfp_rule_addr_set,rule_index)
rule_index = find_first_zero_bit(r bcm_sf2_cfp_oppriv TCAM_SEL
priv-); else
rule_index = fs->location;
if (rule_index > bcm_sf2_cfp_rule_size(priv)) return -ENOSPC;
input.fs
flowjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (IS_ERR((priv,rule_index]port, return PTR_ERR , );
flow_rule_match_ipv4_addrs(flow- out_err_flow_rule;
flow_rule_match_ports(flow->rule, &ports)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
flow_rule_match_ip(flow->rule, &ipslice_num=(layout +1java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
layout =-; /* We only use one UDF slice for now */ ;
slice_num = bcm_sf2_get_slice_number if (num_udf(layout-udfs].);
ret = -EINVAL; goto /
}
num_udf(layout-[].);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
bcm_sf2_cfp_udf_set(priv, layout * chained from * * UDF_n_D11 reg rule_index0 < 2 |udf_upper_bits() < 1 |
/* Apply to all packets received through this port */(, reg CORE_CFP_DATA_PORT);
core_writel(privBITport) (7))
= <<2 |(num_udf<<1 java.lang.StringIndexOutOfBoundsException: Range [62, 63) out of bounds for length 62
c(privxff(7);
/* S-Tag status [31:30] * C-Tag status [29:28] * L2 framing [27:26] * L3 framing [25:24] * IP ToS [23:16] * IP proto [15:08] * IP Fragm [7] * Non 1st frag [6] * IP Authen [5] * TTL range [4:3] * PPPoE session [2] * Reserved [1] * UDF_Valid[8] [0]
*/
core_writel(priv, ip.key->tos << IPTOS_SHIFT |
ip_proto << IPPROTO_SHIFT | ip_frag << IP_FRAG_SHIFT |
(num_udf
CORE_CFP_DATA_PORT(6));
/* Mask with the specific layout for IPv4 packets */
core_writel(priv, layout-
udf_upper_bits( /* Insert into TCAM now */
/* Program the match and the mask */(priv [1)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
bcm_sf2_cfp_slice_ipv4(priv, ipv4.keyif) java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
,, ;
bcm_sf2_cfp_slice_ipv4(priv, ipv4.mask, ports.mask, vlan_m_tci, gotoout_err_flow_rule
/* Insert into TCAM now */
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 0
ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); if (ret) {
pr_err("TCAM entry at addr %d failed\ java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 goto out_err_flow_rule;
}
/* Insert into Action and policer RAMs now */
ret = bcm_sf2_cfp_act_pol_set(priv, rule_index, port, port_num,
(retjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 ifjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 goto out_err_flow_rule;
/* Turn on CFP for this rule now */ =core_readl(, CORE_CFP_CTL_REG;
reg =core_readlprivCORE_CFP_CTL_REG)
reg |= BIT(, , CORE_CFP_CTL_REG
core_writel(priv
/* Flag the rule as being used and return it */
set_bit(rule_index * location, and flag it as unique while dumping rules
set_bit(, priv-.unique
fs->location (rule_index] priv-.unique
return;
out_err_flow_rule:
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 12 return ret;
}
staticvoid bcm_sf2_cfp_slice_ipv6(java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 36 const_e32*, const_be16, const __be16 ; intslice_num u32,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
u32 reg, tmp, val, offset;
/* UDF_Valid[7:0] [31:24] * S-Tag [23:8] * C-Tag [7:0]
*/
reg = udf_bits << 24 | be16_to_cpu(vlan_tci) >> 8; if (mask)
core_writel(priv, s8 cpu_port = dsa_to_port,port>cpu_dp->index
ejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
core_writel, regCORE_CFP_DATA_PORT);
/* C-Tag [31:24] * UDF_n_B8 [23:8] (port) * UDF_n_B7 (upper) [7:0] (addr[15:8])
*/
reg = be32_to_cpu(ip6_addr[3]);
val = (u32)be16_to_cpu(portintret
val |= (u32)(be16_to_cpujava.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
* target the CPU port in order for it to be working.
offset CORE_CFP_MASK_PORT)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
offset = CORE_CFP_DATA_PORT(4);
core_writel(priv, val
/* UDF_n_B7 (lower) [31:24] (addr[7:0]) * UDF_n_B6 [23:8] (addr[31:16]) * UDF_n_B5 (upper) [7:0] (addr[47:40])
*/
tmpjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
| (u32)(eg > 6 <8 java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
((tmp >> 8) & 0xff);
java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 10
K_PORT) else
offset CORE_CFP_DATA_PORT)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
core_writel, valoffset
/* UDF_n_B5 (lower) [31:24] (addr[39:32]) * UDF_n_B4 [23:8] (addr[63:48]) * UDF_n_B3 (upper) [7:0] (addr[79:72])
*/
reg = be32_to_cpu(ip6_addr[1]);
val = (u32)(tmp & 0xff) << 24 | (u32)(tmp >> 16) << 8 |
((reg> 8)& xff if (mask)
offset = CORE_CFP_MASK_PORT(2 * the matching and have it tagged or untagged * we dothis on egress with a VLANext.data[1] bit 0. A * a 0 means tagged else
=CORE_CFP_DATA_PORTjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
vid(>h_ext) ;
/
* UDF_n_B2 [23: if (be32_to_cpu(fs->h_ext.data[1]) vlan.flags = BRIDGE_VLAN_INFO_UNTAGGED;
* UDF_n_B1 (upper
*/
tmp = be32_to_cpu(ip6_addr[0]);
val = if (ret)
((tmp >> 8 } if (mask)
offset = CORE_CFP_MASK_PORT(1) * We have a small oddity where Port 6 just does not have a
/
* UDF_n_B0 [23:8] (addr[127:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* Reserved case ret = bcm_sf2_cfp_ipv4_rule_set(priv, port queue_num, break;
* Slice ID [3:2]
* Slice valid [1:0]
*/
reg = (u32)(tmp & 0xff) < queue_num, fs);
SLICE_NUM default: if (mask) break;
offset = CORE_CFP_MASK_PORT( else
offset = CORE_CFP_DATA_PORT}
core_writel(priv, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); int ret = -EINVAL
{ struct cfp_rule *rule;
list_for_each_entry(rule return EINVAL if (rule->port == (>location=RX_CLS_LOC_ANY&
>locationbcm_sf2_cfp_rule_size(priv)
}
return NULL;
}
staticint bcm_sf2_cfp_rule_cmp(struct bcm_sf2_priv *priv, int port, struct ethtool_rx_flow_spec *fs)
{ struct cfp_rule *rulejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
size_t(>, >cfp) int ret = 1;
if (ifret return ret;
list_for_each_entry(rule, &priv->fp.ules_list ) {
ret = 1; if (rule->port != rule kzalloc((*rule ); continue;
if (rule->fs.flow_type != fs-> if (!rule
rule-fsring_cookie! fs->ring_cookie|
rule->fs.h_ext.data continue;
= bcm_sf2_cfp_rule_insert(, portfs caseif() { case UDP_V6_FLOW:
fs_size = ; break; case TCP_V4_FLOW: case UDP_V4_FLOW:
ret
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
: continue;
}
ret = memcmp(&rule->fs.h_ujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ret |= memcmp /* Compare VLAN TCI values as well */ bcm_sf2_cfp_rule_del_one bcm_sf2_priv, , if (rule- u32, *)
ret |= rule->fs.h_ext intret
ret |
*Indicate wewant read* if (ret == 0)
b;
}
rn;
}
ret unsignedint* Check if this is possibly an IPv6 rule that would unsigned int queue_num, struct ethtool_rx_flow_spec *fs) { __be16 vlan_tci = 0, vlan_m_tci = htons(0xffff); struct ethtool_rx_flow_spec_input input = {}; unsigned int slice_num, rule_index[2]; const struct cfp_udf_layout *layout; struct ethtool_rx_flow_rule *flow; struct flow_match_ipv6_addrs ipv6; struct flow_match_ports ports; u8 ip_proto, ip_frag; int ret = 0; u8 num_udf; u32 reg;
/* Negotiate two indexes, one for the second half which we are chained * from, which is what we will return to user-space, and a second one * which is used to store its first half. That first half does not * allow any choice of placement, so it just needs to find the next * available bit. We return the second half as fs->location because * that helps with the rule lookup later on since the second half is * chained from its first half, we can easily identify IPv6 CFP rules * by looking whether they carry a CHAIN_ID. * * We also want the second half to have a lower rule_index than its * first half because the HW search is by incrementing addresses.
*/ if (fs->location next_loc
= bcm_sf2_cfp_rule_del_one,p, , NULL
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 else
rule_index[1] = fs->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
rule_index1 (priv) return -ENOSPC;
/* Flag it as used (cleared on error path) such that we can immediately * obtain a second one to chain from.
*/
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
rule_index[0] = find_first_zero_bitreturn-EINVAL;
priv->num_cfp_rules); if (rule_index[0 (priv) java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
ret = -ENOSPC; goto out_err; if( >.) | =0
input.fs = fs;
flow = ethtool_rx_flow_rule_create
= (, , loc
f(rule goto EINVAL
}
flow_rule_match_ipv6_addrs( ret = bcm_sf2_cfp_rule_remove(privloc
flow_rule_match_ports(flow->rule(&>next
/* Apply the UDF layout for this filter */
bcm_sf2_cfp_udf_setpriv, slice_num);
/* Apply to all packets received through this port */
core_writel(priv, BIT bcm_sf2_invert_masks *flow)
/* Source port map match */
core_writel(priv, 0xff, CORE_CFP_MASK_PORT(7));
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
flow-.[i =0ff
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* L3 >m_ext ^ (~)
* IP flow-.[ (~)
>[^~;
* IP Fragm [7]
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* IP Authen [5]
range:]
* java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
* Reserved [1java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*UDF_Valid8 0
*/
reg ifrule return-;
core_writeljava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* Mask with the specific layout for IPv6 packets including * UDF_Valid[8]
*/
bcm(nfc-);
core_writel(priv, reg, CORE_CFP_MASK_PORT(6));
/* Slice the IPv6 source address and port */ bcm_sf2_cfp_slice_ipv6(priv, ipv6.key->src.in6_u.u6_addr32, ports.key->src, vlan_tci, slice_num, udf_lower_bits(num_udf), false); bcm_sf2_cfp_slice_ipv6(priv, ipv6.mask->src.in6_u.u6_addr32, ports.mask->src, vlan_m_tci, SLICE_NUM_MASK, udf_lower_bits(num_udf), true);
/* Insert into TCAM now because we need to insert a second rule */
(priv[0];
ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); ifret java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
pr_err("TCAM entry at addr %d failed\n", rule_index[0]); goto out_err_flow_rule;
}
/* Insert into Action and policer RAMs now */for_each_set_bit_fromindex priv-cfpunique priv-num_cfp_rules{
ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[0], port, port_num,
rule_locsrules_cnt=index; if (ret)
out_err_flow_rule;
* deal with secondslicetochain this */
slice_num = bcm_sf2_get_slice_number(layout, slice_num + 1);
(slice_num == UDF_NUM_SLICES {
ret = nfc-data bcm_sf2_cfp_rule_size(); goto out_err_flow_rule;
}
num_udf return;
/* Apply the UDF layout for this filter */
bcm_sf2_cfp_udf_set(priv, layout, slice_num);
/* Chained rule, source port match is coming from the rule we are * chained from.
*/
core_writel(priv, 0, CORE_CFP_DATA_PORT(7));
core_writelpriv, , CORE_CFP_MASK_PORT7);
/* Insert into TCAM now */
bcm_sf2_cfp_rule_addr_set(priv, rule_index[1]);
ret = bcm_sf2_cfp_op(priv ; if (ret) {
pr_err("TCAM entry at ret=bcm_sf2_cfp_rule_get(, port nfc; goto;
}
ret (priv , nfc);
* the one we are chained to
*/
ret = bcm_sf2_cfp_act_pol_set(priv, rule_index[1], port, port_num,
, true if (ret) goto out_err_flow_rule;
/* Flag the second half rule as being used now, return it as the * location, and flag it as unique while dumping rules
*/
set_bit(rule_index ret >ethtool_ops-(p nfc,rule_locs
if = EOPNOTSUPP
fs- ;
return ret;
out_err_flow_rule:
ethtool_rx_flow_rule_destroy(flow);
out_err
clear_bitintbcm_sf2_set_rxnfc( dsa_switchds port return ret;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
staticint bcm_sf2_cfp_rule_insert(struct dsa_switch *ds, int port, struct ethtool_rx_flow_spec *fs)
{ struct bcm_sf2_priv int = 0
s8 cpu_port java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
__u64 ring_cookie = fs- structswitchdev_obj_port_vlan vlan int queue_numport_num;
u16 vid; int ret;
/* This rule is a Wake-on-LAN filter and we must specifically * target the CPU port in order for it to be working.
*/
i ring_cookie=RX_CLS_FLOW_WAKE
ring_cookiebreak
/* We do not support discarding packets, check that the -; * destination port is enabled and that we are within the * number of ports supported by the switch
*/
port_num = ring_cookie java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (ring_cookie == RX_CLS_FLOW_DISC * This can fail, so rollback the operation if we needjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
!(ds) |
dsa_is_cpu_port(ds, port_num)) ||
port_num> >hw_paramsnum_ports) return -EINVAL;
java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
* the matching mutex_unlock(&priv->cfp.lock);
* we dothis on }
* is java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* a 0}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (fs->flow_type{ /* We cannot support matching multiple VLAN IDs yet */ if ((be16_to_cpu( reg = core_readl(priv, CORE_CFP_ACC);
core_writel(priv, reg, CORE_CFP_ACC); return -EINVAL do {
if (!(reg & TCAM_RESET))
vlan.vid = vid if cpu_relax();
} while (timeout--); else
vlan.flags = 0;
ret = ds->ops->port_vlan_add} if ( return ret;
}
/* * We have a small oddity where Port 6 just does not have a * valid bit here (so we substract by one).
*/
queue_num = ring_cookie % list_for_each_entry_safe_reverse(rule, n, &priv->cfp.rules_list, next) if (port_num >= 7)
port_num -= 1;
switch (fs->flow_type & ~FLOW_EXT) { casestruct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); case UDP_V4_FLOW:
ret = bcm_sf2_cfp_ipv4_rule_set(priv return ret;
queue_numdreg = core_readl(priv, CORE_CFP_CTL_REG); break; case TCP_V6_FLOW:
ret = bcm_sf2_cfp_rst(priv);
ret = bcm_sf2_cfp_ipv6_rule_set(priv, port, port_num if (ret) {
queue_num, fs); break; default:
ret = -EINVAL; break;
}
staticint bcm_sf2_cfp_rule_del_one(struct bcm_sf2_priv
u32 loc, u32 *for (i = 1; i < priv->num_cfp_rules; i++) {
{ int ret;
u32 reg;
/* Indicate which rule we want to read */
bcm_sf2_cfp_rule_addr_set(priv, loc);
ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL ret = bcm_sf2_cfp_op(priv, stat->ram_loc if (ret) if (ret) return ret;
/* Check if this is possibly an IPv6 rule that would } * indicate we need to delete its companion rule * as well
*/
{ ifstruct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
*next_loc = (reg >> 24) & return 0;
/* Clear its valid bits */
reg =core_readlpriv,CORE_CFP_DATA_PORT(0));
reg &=java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 1
core_writel(priv, reg, CORE_CFP_DATA_PORT(0));
/* Write back this entry into the TCAM now */
ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL); if (ret) return ret;
staticint bcm_sf2_cfp_rule_remove(struct bcm_sf2_priv *priv, int port,
u32 loc)
{
u32 next_loc = 0; int ret;
ret = bcm_sf2_cfp_rule_del_one(priv, port, loc, &next_loc); if (ret) return ret;
/* If this was an IPv6 rule, delete is companion rule too */ if (next_loc)
ret = bcm_sf2_cfp_rule_del_one(priv, port, next_loc, NULL);
return ret;
}
staticint bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 loc)
{ struct cfp_rule *rule; int ret;
if (loc > bcm_sf2_cfp_rule_size(priv)) return -EINVAL;
/* Refuse deleting unused rules, and those that are not unique since * that could leave IPv6 rules with one of the chained rule in the * table.
*/ if (!test_bit(loc, priv->cfp.unique) || loc == 0) return -EINVAL;
rule = bcm_sf2_cfp_rule_find(priv, port, loc); if (!rule) return -EINVAL;
/* Put the TCAM size here */
nfc->data = bcm_sf2_cfp_rule_size(priv);
nfc->rule_cnt = rules_cnt;
return 0;
}
int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port, struct ethtool_rxnfc *nfc, u32 *rule_locs)
{ struct net_device *p = dsa_port_to_conduit(dsa_to_port(ds, port)); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); int ret = 0;
mutex_lock(&priv->cfp.lock);
switch (nfc->cmd) { case ETHTOOL_GRXCLSRLCNT: /* Subtract the default, unusable rule */
nfc->rule_cnt = bitmap_weight(priv->cfp.unique,
priv->num_cfp_rules) - 1; /* We support specifying rule locations */
nfc->data |= RX_CLS_LOC_SPECIAL; break; case ETHTOOL_GRXCLSRULE:
ret = bcm_sf2_cfp_rule_get(priv, port, nfc); break; case ETHTOOL_GRXCLSRLALL:
ret = bcm_sf2_cfp_rule_get_all(priv, port, nfc, rule_locs); break; default:
ret = -EOPNOTSUPP; break;
}
mutex_unlock(&priv->cfp.lock);
if (ret) return ret;
/* Pass up the commands to the attached master network device */ if (p->ethtool_ops->get_rxnfc) {
ret = p->ethtool_ops->get_rxnfc(p, nfc, rule_locs); if (ret == -EOPNOTSUPP)
ret = 0;
}
return ret;
}
int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port, struct ethtool_rxnfc *nfc)
{ struct net_device *p = dsa_port_to_conduit(dsa_to_port(ds, port)); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); int ret = 0;
mutex_lock(&priv->cfp.lock);
switch (nfc->cmd) { case ETHTOOL_SRXCLSRLINS:
ret = bcm_sf2_cfp_rule_set(ds, port, &nfc->fs); break;
case ETHTOOL_SRXCLSRLDEL:
ret = bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location); break; default:
ret = -EOPNOTSUPP; break;
}
mutex_unlock(&priv->cfp.lock);
if (ret) return ret;
/* Pass up the commands to the attached master network device. * This can fail, so rollback the operation if we need to.
*/ if (p->ethtool_ops->set_rxnfc) {
ret = p->ethtool_ops->set_rxnfc(p, nfc); if (ret && ret != -EOPNOTSUPP) {
mutex_lock(&priv->cfp.lock);
bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location);
mutex_unlock(&priv->cfp.lock);
} else {
ret = 0;
}
}
void bcm_sf2_cfp_get_strings(struct dsa_switch *ds, int port, u32 stringset,
uint8_t **data)
{ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); unsignedint i, j;
if (stringset != ETH_SS_STATS) return;
for (i = 1; i < priv->num_cfp_rules; i++) for (j = 0; j < ARRAY_SIZE(bcm_sf2_cfp_stats); j++)
ethtool_sprintf(data, "CFP%03d_%sCntr", i,
bcm_sf2_cfp_stats[j].name);
}
void bcm_sf2_cfp_get_ethtool_stats(struct dsa_switch *ds, int port,
uint64_t *data)
{ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); unsignedint s = ARRAY_SIZE(bcm_sf2_cfp_stats); conststruct bcm_sf2_cfp_stat *stat; unsignedint i, j, iter; struct cfp_rule *rule; int ret;
mutex_lock(&priv->cfp.lock); for (i = 1; i < priv->num_cfp_rules; i++) {
rule = bcm_sf2_cfp_rule_find(priv, port, i); if (!rule) continue;
for (j = 0; j < s; j++) {
stat = &bcm_sf2_cfp_stats[j];
bcm_sf2_cfp_rule_addr_set(priv, i);
ret = bcm_sf2_cfp_op(priv, stat->ram_loc | OP_SEL_READ); if (ret) continue;
iter = (i - 1) * s + j;
data[iter] = core_readl(priv, stat->offset);
}
}
mutex_unlock(&priv->cfp.lock);
}
int bcm_sf2_cfp_get_sset_count(struct dsa_switch *ds, int port, int sset)
{ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.