Commit 59bfde01 authored by Roi Dayan's avatar Roi Dayan Committed by David S. Miller

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: default avatarRoi Dayan <roid@mellanox.com>
Reviewed-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 20a1ea67
...@@ -92,6 +92,8 @@ struct devlink_ops { ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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; 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]); mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
err = ops->eswitch_mode_set(devlink, mode);
if (err)
return err;
}
if (ops && ops->eswitch_mode_set) if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
return ops->eswitch_mode_set(devlink, mode); if (!ops->eswitch_inline_mode_set)
return -EOPNOTSUPP; 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] = { ...@@ -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[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment