forked from Minki/linux
net: dsa: add ops for devlink-sb
Switches that care about QoS might have hardware support for reserving buffer pools for individual ports or traffic classes, and configuring their sizes and thresholds. Through devlink-sb (shared buffers), this is all configurable, as well as their occupancy being viewable. Add the plumbing in DSA for these operations. Individual drivers still need to call devlink_sb_register() with the shared buffers they want to expose. A helper was not created in DSA for this purpose (unlike, say, dsa_devlink_params_register), since in my opinion it does not bring any benefit over plainly calling devlink_sb_register() directly. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
703b762190
commit
2a6ef76303
@ -699,6 +699,40 @@ struct dsa_switch_ops {
|
|||||||
int (*devlink_info_get)(struct dsa_switch *ds,
|
int (*devlink_info_get)(struct dsa_switch *ds,
|
||||||
struct devlink_info_req *req,
|
struct devlink_info_req *req,
|
||||||
struct netlink_ext_ack *extack);
|
struct netlink_ext_ack *extack);
|
||||||
|
int (*devlink_sb_pool_get)(struct dsa_switch *ds,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
struct devlink_sb_pool_info *pool_info);
|
||||||
|
int (*devlink_sb_pool_set)(struct dsa_switch *ds, unsigned int sb_index,
|
||||||
|
u16 pool_index, u32 size,
|
||||||
|
enum devlink_sb_threshold_type threshold_type,
|
||||||
|
struct netlink_ext_ack *extack);
|
||||||
|
int (*devlink_sb_port_pool_get)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
u32 *p_threshold);
|
||||||
|
int (*devlink_sb_port_pool_set)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
u32 threshold,
|
||||||
|
struct netlink_ext_ack *extack);
|
||||||
|
int (*devlink_sb_tc_pool_bind_get)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u16 *p_pool_index, u32 *p_threshold);
|
||||||
|
int (*devlink_sb_tc_pool_bind_set)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u16 pool_index, u32 threshold,
|
||||||
|
struct netlink_ext_ack *extack);
|
||||||
|
int (*devlink_sb_occ_snapshot)(struct dsa_switch *ds,
|
||||||
|
unsigned int sb_index);
|
||||||
|
int (*devlink_sb_occ_max_clear)(struct dsa_switch *ds,
|
||||||
|
unsigned int sb_index);
|
||||||
|
int (*devlink_sb_occ_port_pool_get)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
u32 *p_cur, u32 *p_max);
|
||||||
|
int (*devlink_sb_occ_tc_port_bind_get)(struct dsa_switch *ds, int port,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u32 *p_cur, u32 *p_max);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MTU change functionality. Switches can also adjust their MRU through
|
* MTU change functionality. Switches can also adjust their MRU through
|
||||||
|
159
net/dsa/dsa2.c
159
net/dsa/dsa2.c
@ -463,8 +463,165 @@ static int dsa_devlink_info_get(struct devlink *dl,
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_pool_get(struct devlink *dl,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
struct devlink_sb_pool_info *pool_info)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_to_ds(dl);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_pool_get)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_pool_get(ds, sb_index, pool_index,
|
||||||
|
pool_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_pool_set(struct devlink *dl, unsigned int sb_index,
|
||||||
|
u16 pool_index, u32 size,
|
||||||
|
enum devlink_sb_threshold_type threshold_type,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_to_ds(dl);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_pool_set)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_pool_set(ds, sb_index, pool_index, size,
|
||||||
|
threshold_type, extack);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_port_pool_get(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
u32 *p_threshold)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_port_pool_get)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_port_pool_get(ds, port, sb_index,
|
||||||
|
pool_index, p_threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_port_pool_set(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index, u16 pool_index,
|
||||||
|
u32 threshold,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_port_pool_set)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_port_pool_set(ds, port, sb_index,
|
||||||
|
pool_index, threshold, extack);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dsa_devlink_sb_tc_pool_bind_get(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u16 *p_pool_index, u32 *p_threshold)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_tc_pool_bind_get)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_tc_pool_bind_get(ds, port, sb_index,
|
||||||
|
tc_index, pool_type,
|
||||||
|
p_pool_index, p_threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dsa_devlink_sb_tc_pool_bind_set(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u16 pool_index, u32 threshold,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_tc_pool_bind_set)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_tc_pool_bind_set(ds, port, sb_index,
|
||||||
|
tc_index, pool_type,
|
||||||
|
pool_index, threshold,
|
||||||
|
extack);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_occ_snapshot(struct devlink *dl,
|
||||||
|
unsigned int sb_index)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_to_ds(dl);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_occ_snapshot)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_occ_snapshot(ds, sb_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_occ_max_clear(struct devlink *dl,
|
||||||
|
unsigned int sb_index)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_to_ds(dl);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_occ_max_clear)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_occ_max_clear(ds, sb_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_devlink_sb_occ_port_pool_get(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index,
|
||||||
|
u16 pool_index, u32 *p_cur,
|
||||||
|
u32 *p_max)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_occ_port_pool_get)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_occ_port_pool_get(ds, port, sb_index,
|
||||||
|
pool_index, p_cur, p_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dsa_devlink_sb_occ_tc_port_bind_get(struct devlink_port *dlp,
|
||||||
|
unsigned int sb_index, u16 tc_index,
|
||||||
|
enum devlink_sb_pool_type pool_type,
|
||||||
|
u32 *p_cur, u32 *p_max)
|
||||||
|
{
|
||||||
|
struct dsa_switch *ds = dsa_devlink_port_to_ds(dlp);
|
||||||
|
int port = dsa_devlink_port_to_port(dlp);
|
||||||
|
|
||||||
|
if (!ds->ops->devlink_sb_occ_tc_port_bind_get)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
return ds->ops->devlink_sb_occ_tc_port_bind_get(ds, port,
|
||||||
|
sb_index, tc_index,
|
||||||
|
pool_type, p_cur,
|
||||||
|
p_max);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct devlink_ops dsa_devlink_ops = {
|
static const struct devlink_ops dsa_devlink_ops = {
|
||||||
.info_get = dsa_devlink_info_get,
|
.info_get = dsa_devlink_info_get,
|
||||||
|
.sb_pool_get = dsa_devlink_sb_pool_get,
|
||||||
|
.sb_pool_set = dsa_devlink_sb_pool_set,
|
||||||
|
.sb_port_pool_get = dsa_devlink_sb_port_pool_get,
|
||||||
|
.sb_port_pool_set = dsa_devlink_sb_port_pool_set,
|
||||||
|
.sb_tc_pool_bind_get = dsa_devlink_sb_tc_pool_bind_get,
|
||||||
|
.sb_tc_pool_bind_set = dsa_devlink_sb_tc_pool_bind_set,
|
||||||
|
.sb_occ_snapshot = dsa_devlink_sb_occ_snapshot,
|
||||||
|
.sb_occ_max_clear = dsa_devlink_sb_occ_max_clear,
|
||||||
|
.sb_occ_port_pool_get = dsa_devlink_sb_occ_port_pool_get,
|
||||||
|
.sb_occ_tc_port_bind_get = dsa_devlink_sb_occ_tc_port_bind_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dsa_switch_setup(struct dsa_switch *ds)
|
static int dsa_switch_setup(struct dsa_switch *ds)
|
||||||
|
Loading…
Reference in New Issue
Block a user