History

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.

Roi Dayan committed 9 years ago

Commit 59bfde01 parent 20a1ea63 files · +61 −19Browse files

Unified · Split

3 files
  1. include/net/devlink.h +2 −0
  2. include/uapi/linux/devlink.h +8 −0
  3. net/core/devlink.c +51 −19
include/net/devlink.h+2−0
@@ -92,6 +92,8 @@ struct devlink_ops { · 91 unmodified lines
9292
9393 int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
9494 int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
95+ int (*eswitch_inline_mode_get)(struct devlink *devlink, u8 *p_inline_mode);
96+ int (*eswitch_inline_mode_set)(struct devlink *devlink, u8 inline_mode);
9597 };
9698
9799 static inline void *devlink_priv(struct devlink *devlink)
include/uapi/linux/devlink.h+8−0
@@ -102,6 +102,13 @@ enum devlink_eswitch_mode { · 101 unmodified lines
102102 DEVLINK_ESWITCH_MODE_SWITCHDEV,
103103 };
104104
105+enum devlink_eswitch_inline_mode {
106+ DEVLINK_ESWITCH_INLINE_MODE_NONE,
107+ DEVLINK_ESWITCH_INLINE_MODE_LINK,
108+ DEVLINK_ESWITCH_INLINE_MODE_NETWORK,
109+ DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT,
110+};
111+
105112 enum devlink_attr {
106113 /* don't change the order or add anything between, this is ABI! */
107114 DEVLINK_ATTR_UNSPEC,
@@ -133,6 +140,7 @@ enum devlink_attr { · 25 unmodified lines
133140 DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
134141 DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
135142 DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
143+ DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */
136144
137145 /* add new attributes above here, update the policy in devlink.c */
138146
net/core/devlink.c+51−19
@@ -1394,26 +1394,45 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, · 1393 unmodified lines
13941394
13951395 static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
13961396 enum devlink_command cmd, u32 portid,
1397− u32 seq, int flags, u16 mode)
1397+ u32 seq, int flags)
13981398 {
1399+ const struct devlink_ops *ops = devlink->ops;
13991400 void *hdr;
1401+ int err = 0;
1402+ u16 mode;
1403+ u8 inline_mode;
14001404
14011405 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
14021406 if (!hdr)
14031407 return -EMSGSIZE;
14041408
1405− if (devlink_nl_put_handle(msg, devlink))
1406− goto nla_put_failure;
1409+ err = devlink_nl_put_handle(msg, devlink);
1410+ if (err)
1411+ goto out;
14071412
1408− if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
1409− goto nla_put_failure;
1413+ err = ops->eswitch_mode_get(devlink, &mode);
1414+ if (err)
1415+ goto out;
1416+ err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1417+ if (err)
1418+ goto out;
1419+
1420+ if (ops->eswitch_inline_mode_get) {
1421+ err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1422+ if (err)
1423+ goto out;
1424+ err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1425+ inline_mode);
1426+ if (err)
1427+ goto out;
1428+ }
14101429
14111430 genlmsg_end(msg, hdr);
14121431 return 0;
14131432
1414−nla_put_failure:
1433+out:
14151434 genlmsg_cancel(msg, hdr);
1416− return -EMSGSIZE;
1435+ return err;
14171436 }
14181437
14191438 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, · 2 unmodified lines
14221441 struct devlink *devlink = info->user_ptr[0];
14231442 const struct devlink_ops *ops = devlink->ops;
14241443 struct sk_buff *msg;
1425− u16 mode;
14261444 int err;
14271445
14281446 if (!ops || !ops->eswitch_mode_get)
14291447 return -EOPNOTSUPP;
14301448
1431− err = ops->eswitch_mode_get(devlink, &mode);
1432− if (err)
1433− return err;
1434−
14351449 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14361450 if (!msg)
14371451 return -ENOMEM;
14381452
14391453 err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
1440− info->snd_portid, info->snd_seq, 0, mode);
1454+ info->snd_portid, info->snd_seq, 0);
14411455
14421456 if (err) {
14431457 nlmsg_free(msg);
@@ -1453,15 +1467,32 @@ static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb, · 9 unmodified lines
14531467 struct devlink *devlink = info->user_ptr[0];
14541468 const struct devlink_ops *ops = devlink->ops;
14551469 u16 mode;
1470+ u8 inline_mode;
1471+ int err = 0;
14561472
1457− if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
1458− return -EINVAL;
1473+ if (!ops)
1474+ return -EOPNOTSUPP;
14591475
1460− mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1476+ if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1477+ if (!ops->eswitch_mode_set)
1478+ return -EOPNOTSUPP;
1479+ mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1480+ err = ops->eswitch_mode_set(devlink, mode);
1481+ if (err)
1482+ return err;
1483+ }
14611484
1462− if (ops && ops->eswitch_mode_set)
1463− return ops->eswitch_mode_set(devlink, mode);
1464− return -EOPNOTSUPP;
1485+ if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1486+ if (!ops->eswitch_inline_mode_set)
1487+ return -EOPNOTSUPP;
1488+ inline_mode = nla_get_u8(
1489+ info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1490+ err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1491+ if (err)
1492+ return err;
1493+ }
1494+
1495+ return 0;
14651496 }
14661497
14671498 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] = { · 10 unmodified lines
14781509 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
14791510 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
14801511 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
1512+ [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
14811513 };
14821514
14831515 static const struct genl_ops devlink_nl_ops[] = {