#define VSC9959_PSFP_SFID_MAX 175
#define VSC9959_PSFP_GATE_ID_MAX 183
+#define VSC9959_PSFP_POLICER_BASE 63
#define VSC9959_PSFP_POLICER_MAX 383
#define VSC9959_PSFP_GATE_LIST_NUM 4
#define VSC9959_PSFP_GATE_CYCLETIME_MIN 5000
struct felix_stream stream = {0};
struct felix_stream_gate *sgi;
struct ocelot_psfp_list *psfp;
+ struct ocelot_policer pol;
int ret, i, size;
+ u64 rate, burst;
+ u32 index;
psfp = &ocelot->psfp;
ret = vsc9959_psfp_sgi_table_add(ocelot, sgi);
if (ret) {
kfree(sgi);
- return ret;
+ goto err;
}
sfi.sg_valid = 1;
sfi.sgid = sgi->index;
kfree(sgi);
break;
case FLOW_ACTION_POLICE:
+ index = a->police.index + VSC9959_PSFP_POLICER_BASE;
+ if (index > VSC9959_PSFP_POLICER_MAX) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ rate = a->police.rate_bytes_ps;
+ burst = rate * PSCHED_NS2TICKS(a->police.burst);
+ pol = (struct ocelot_policer) {
+ .burst = div_u64(burst, PSCHED_TICKS_PER_SEC),
+ .rate = div_u64(rate, 1000) * 8,
+ };
+ ret = ocelot_vcap_policer_add(ocelot, index, &pol);
+ if (ret)
+ goto err;
+
+ sfi.fm_valid = 1;
+ sfi.fmid = index;
+ sfi.maxsdu = a->police.mtu;
+ break;
default:
return -EOPNOTSUPP;
}
if (sfi.sg_valid)
vsc9959_psfp_sgi_table_del(ocelot, sfi.sgid);
+ if (sfi.fm_valid)
+ ocelot_vcap_policer_del(ocelot, sfi.fmid);
+
return ret;
}
if (sfi->sg_valid)
vsc9959_psfp_sgi_table_del(ocelot, sfi->sgid);
+ if (sfi->fm_valid)
+ ocelot_vcap_policer_del(ocelot, sfi->fmid);
+
vsc9959_psfp_sfi_table_del(ocelot, stream->sfid);
stream->sfid_valid = 0;