mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
devlink: Add E-Switch inline mode control
Some HWs need the VF driver to put part of the packet headers on the TX descriptor so the e-switch can do proper matching and steering. The supported modes: none, link, network, transport. Signed-off-by: Roi Dayan <roid@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
20a1ea6747
commit
59bfde01fa
3 changed files with 61 additions and 19 deletions
|
@ -92,6 +92,8 @@ struct devlink_ops {
|
||||||
|
|
||||||
int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
|
int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
|
||||||
int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
|
int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
|
||||||
|
int (*eswitch_inline_mode_get)(struct devlink *devlink, u8 *p_inline_mode);
|
||||||
|
int (*eswitch_inline_mode_set)(struct devlink *devlink, u8 inline_mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void *devlink_priv(struct devlink *devlink)
|
static inline void *devlink_priv(struct devlink *devlink)
|
||||||
|
|
|
@ -102,6 +102,13 @@ enum devlink_eswitch_mode {
|
||||||
DEVLINK_ESWITCH_MODE_SWITCHDEV,
|
DEVLINK_ESWITCH_MODE_SWITCHDEV,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum devlink_eswitch_inline_mode {
|
||||||
|
DEVLINK_ESWITCH_INLINE_MODE_NONE,
|
||||||
|
DEVLINK_ESWITCH_INLINE_MODE_LINK,
|
||||||
|
DEVLINK_ESWITCH_INLINE_MODE_NETWORK,
|
||||||
|
DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT,
|
||||||
|
};
|
||||||
|
|
||||||
enum devlink_attr {
|
enum devlink_attr {
|
||||||
/* don't change the order or add anything between, this is ABI! */
|
/* don't change the order or add anything between, this is ABI! */
|
||||||
DEVLINK_ATTR_UNSPEC,
|
DEVLINK_ATTR_UNSPEC,
|
||||||
|
@ -133,6 +140,7 @@ enum devlink_attr {
|
||||||
DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
|
DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
|
||||||
DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
|
DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
|
||||||
DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
|
DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
|
||||||
|
DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */
|
||||||
|
|
||||||
/* add new attributes above here, update the policy in devlink.c */
|
/* add new attributes above here, update the policy in devlink.c */
|
||||||
|
|
||||||
|
|
|
@ -1394,26 +1394,45 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
|
||||||
|
|
||||||
static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
|
static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||||
enum devlink_command cmd, u32 portid,
|
enum devlink_command cmd, u32 portid,
|
||||||
u32 seq, int flags, u16 mode)
|
u32 seq, int flags)
|
||||||
{
|
{
|
||||||
|
const struct devlink_ops *ops = devlink->ops;
|
||||||
void *hdr;
|
void *hdr;
|
||||||
|
int err = 0;
|
||||||
|
u16 mode;
|
||||||
|
u8 inline_mode;
|
||||||
|
|
||||||
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
if (devlink_nl_put_handle(msg, devlink))
|
err = devlink_nl_put_handle(msg, devlink);
|
||||||
goto nla_put_failure;
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
|
err = ops->eswitch_mode_get(devlink, &mode);
|
||||||
goto nla_put_failure;
|
if (err)
|
||||||
|
goto out;
|
||||||
|
err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (ops->eswitch_inline_mode_get) {
|
||||||
|
err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
|
||||||
|
inline_mode);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
genlmsg_end(msg, hdr);
|
genlmsg_end(msg, hdr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nla_put_failure:
|
out:
|
||||||
genlmsg_cancel(msg, hdr);
|
genlmsg_cancel(msg, hdr);
|
||||||
return -EMSGSIZE;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
|
static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
|
||||||
|
@ -1422,22 +1441,17 @@ static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
|
||||||
struct devlink *devlink = info->user_ptr[0];
|
struct devlink *devlink = info->user_ptr[0];
|
||||||
const struct devlink_ops *ops = devlink->ops;
|
const struct devlink_ops *ops = devlink->ops;
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg;
|
||||||
u16 mode;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!ops || !ops->eswitch_mode_get)
|
if (!ops || !ops->eswitch_mode_get)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
err = ops->eswitch_mode_get(devlink, &mode);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
|
err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
|
||||||
info->snd_portid, info->snd_seq, 0, mode);
|
info->snd_portid, info->snd_seq, 0);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
|
@ -1453,15 +1467,32 @@ static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
|
||||||
struct devlink *devlink = info->user_ptr[0];
|
struct devlink *devlink = info->user_ptr[0];
|
||||||
const struct devlink_ops *ops = devlink->ops;
|
const struct devlink_ops *ops = devlink->ops;
|
||||||
u16 mode;
|
u16 mode;
|
||||||
|
u8 inline_mode;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
|
if (!ops)
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
|
|
||||||
|
|
||||||
if (ops && ops->eswitch_mode_set)
|
|
||||||
return ops->eswitch_mode_set(devlink, mode);
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
|
||||||
|
if (!ops->eswitch_mode_set)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
|
||||||
|
err = ops->eswitch_mode_set(devlink, mode);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
|
||||||
|
if (!ops->eswitch_inline_mode_set)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
inline_mode = nla_get_u8(
|
||||||
|
info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
|
||||||
|
err = ops->eswitch_inline_mode_set(devlink, inline_mode);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
|
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
|
||||||
|
@ -1478,6 +1509,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
|
||||||
[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
|
[DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
|
||||||
[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
|
[DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
|
||||||
[DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
|
[DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
|
||||||
|
[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct genl_ops devlink_nl_ops[] = {
|
static const struct genl_ops devlink_nl_ops[] = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue