mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-20 13:36:08 +04:00
qualcommax: qca_ppe: add devlink info and clear port meter credit
devlink dev info reports no chip id, and the ingress port meter keeps its credit when a police action is removed. Report the device and revision fields of the switch id register as the generic asic id and revision; device 0x15 with revision 0 is IPQ807x and 1 is IPQ6018, and probe does not depend on it. Clear both words of the port's meter credit entry when the rate goes to zero, as the port shaper already does. On IPQ8074 the credit entry reads zero after the police action is deleted, and a re-armed police holds its rate. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de> Link: https://github.com/openwrt/openwrt/pull/25700 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
1 parent
478da5ef34
commit
aaa4378dce
3 files changed
+53
No files matched your search
@@ -19,6 +19,10 @@
|
||||
#define QCA_PPE_MAX_BRIDGES 8
|
||||
|
||||
/* --- Global --- */
|
||||
#define PPE_SWITCH_ID 0x0
|
||||
#define PPE_SWITCH_ID_REV GENMASK(7, 0)
|
||||
#define PPE_SWITCH_ID_DEV GENMASK(15, 8)
|
||||
|
||||
#define PPE_CLK_GATING_CTRL 0x8
|
||||
#define PPE_QM_CLK_GATE_EN BIT(4)
|
||||
|
||||
@@ -586,6 +590,11 @@
|
||||
#define PPE_PORT_METER_W2(p) (PPE_POLICER_BASE + 0xc000 + (p) * 0x10 + 0x8)
|
||||
#define PPE_PORT_METER_W3(p) (PPE_POLICER_BASE + 0xc000 + (p) * 0x10 + 0xc)
|
||||
|
||||
/* The meter's token buckets, committed and excess, one entry per port and two
|
||||
* words wide, the second of which commits it.
|
||||
*/
|
||||
#define PPE_PORT_METER_CRDT(p) (PPE_POLICER_BASE + 0xd000 + (p) * 0x10)
|
||||
|
||||
#define PPE_PORT_TX_DROP_CNT(p) (PPE_POLICER_BASE + 0x7d000 + (p) * 0x10)
|
||||
#define PPE_VP_TX_DROP_CNT(v) (PPE_POLICER_BASE + 0x7e000 + (v) * 0x10)
|
||||
|
||||
|
||||
@@ -659,6 +659,41 @@ static int ppe_devlink_setup(struct dsa_switch *ds)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The part names itself in the first register of the global block. qca-ssdk's
|
||||
* named accessor for it is compiled out; what proves the field split is its init
|
||||
* path reading the same word raw (ssdk_init.c chip_ver_get): device 0x15 is this
|
||||
* switch generation, revision 0 IPQ807x and 1 IPQ6018.
|
||||
*/
|
||||
static int qca_ppe_devlink_info_get(struct dsa_switch *ds,
|
||||
struct devlink_info_req *req,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct qca_ppe_priv *priv = ds_to_priv(ds);
|
||||
u32 id, dev, rev;
|
||||
char buf[8];
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(priv->regmap, PPE_SWITCH_ID, &id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev = FIELD_GET(PPE_SWITCH_ID_DEV, id);
|
||||
rev = FIELD_GET(PPE_SWITCH_ID_REV, id);
|
||||
|
||||
snprintf(buf, sizeof(buf), "0x%02x", dev);
|
||||
ret = devlink_info_version_fixed_put(req,
|
||||
DEVLINK_INFO_VERSION_GENERIC_ASIC_ID,
|
||||
buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snprintf(buf, sizeof(buf), "0x%02x", rev);
|
||||
|
||||
return devlink_info_version_fixed_put(req,
|
||||
DEVLINK_INFO_VERSION_GENERIC_ASIC_REV,
|
||||
buf);
|
||||
}
|
||||
|
||||
static int qca_ppe_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct qca_ppe_priv *priv = ds_to_priv(ds);
|
||||
@@ -2449,6 +2484,7 @@ static const struct dsa_switch_ops qca_ppe_ops = {
|
||||
.get_stats64 = qca_ppe_get_stats64,
|
||||
.get_regs_len = qca_ppe_get_regs_len,
|
||||
.get_regs = qca_ppe_get_regs,
|
||||
.devlink_info_get = qca_ppe_devlink_info_get,
|
||||
.devlink_sb_pool_get = qca_ppe_devlink_sb_pool_get,
|
||||
.devlink_sb_pool_set = qca_ppe_devlink_sb_pool_set,
|
||||
};
|
||||
|
||||
@@ -1488,6 +1488,14 @@ static int ppe_port_policer_set(struct qca_ppe_priv *priv, int port,
|
||||
regmap_write(priv->regmap, PPE_PORT_METER_W2(port), 0);
|
||||
regmap_write(priv->regmap, PPE_PORT_METER_W3(port), 0);
|
||||
|
||||
/* Credit outlives the rate that filled it: what a re-armed meter would
|
||||
* spend on its first frames was bought at a rate the port has lost.
|
||||
*/
|
||||
if (!rate_bps) {
|
||||
regmap_write(priv->regmap, PPE_PORT_METER_CRDT(port), 0);
|
||||
regmap_write(priv->regmap, PPE_PORT_METER_CRDT(port) + 0x4, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user