|
@@ -565,19 +565,21 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
|
|
|
* first half because the HW search is by incrementing addresses.
|
|
|
*/
|
|
|
if (fs->location == RX_CLS_LOC_ANY)
|
|
|
- rule_index[0] = find_first_zero_bit(priv->cfp.used,
|
|
|
- bcm_sf2_cfp_rule_size(priv));
|
|
|
+ rule_index[1] = find_first_zero_bit(priv->cfp.used,
|
|
|
+ priv->num_cfp_rules);
|
|
|
else
|
|
|
- rule_index[0] = fs->location;
|
|
|
+ rule_index[1] = fs->location;
|
|
|
+ if (rule_index[1] > bcm_sf2_cfp_rule_size(priv))
|
|
|
+ return -ENOSPC;
|
|
|
|
|
|
/* Flag it as used (cleared on error path) such that we can immediately
|
|
|
* obtain a second one to chain from.
|
|
|
*/
|
|
|
- set_bit(rule_index[0], priv->cfp.used);
|
|
|
+ set_bit(rule_index[1], priv->cfp.used);
|
|
|
|
|
|
- rule_index[1] = find_first_zero_bit(priv->cfp.used,
|
|
|
- bcm_sf2_cfp_rule_size(priv));
|
|
|
- if (rule_index[1] > bcm_sf2_cfp_rule_size(priv)) {
|
|
|
+ rule_index[0] = find_first_zero_bit(priv->cfp.used,
|
|
|
+ priv->num_cfp_rules);
|
|
|
+ if (rule_index[0] > bcm_sf2_cfp_rule_size(priv)) {
|
|
|
ret = -ENOSPC;
|
|
|
goto out_err;
|
|
|
}
|
|
@@ -715,14 +717,14 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
|
|
|
/* 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[1], priv->cfp.used);
|
|
|
+ set_bit(rule_index[0], priv->cfp.used);
|
|
|
set_bit(rule_index[1], priv->cfp.unique);
|
|
|
fs->location = rule_index[1];
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
out_err:
|
|
|
- clear_bit(rule_index[0], priv->cfp.used);
|
|
|
+ clear_bit(rule_index[1], priv->cfp.used);
|
|
|
return ret;
|
|
|
}
|
|
|
|