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
92 92
93 int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);93 int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
94 int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);94 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);
95};97};
96 98
97static inline void *devlink_priv(struct devlink *devlink)99static 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
102 DEVLINK_ESWITCH_MODE_SWITCHDEV,102 DEVLINK_ESWITCH_MODE_SWITCHDEV,
103};103};
104 104
105enum 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
105enum devlink_attr {112enum devlink_attr {
106 /* don't change the order or add anything between, this is ABI! */113 /* don't change the order or add anything between, this is ABI! */
107 DEVLINK_ATTR_UNSPEC,114 DEVLINK_ATTR_UNSPEC,
@@ -133,6 +140,7 @@ enum devlink_attr { · 25 unmodified lines
133 DEVLINK_ATTR_SB_OCC_CUR, /* u32 */140 DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
134 DEVLINK_ATTR_SB_OCC_MAX, /* u32 */141 DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
135 DEVLINK_ATTR_ESWITCH_MODE, /* u16 */142 DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
143 DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */
136 144
137 /* add new attributes above here, update the policy in devlink.c */145 /* add new attributes above here, update the policy in devlink.c */
138 146
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
1394 1394
1395static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,1395static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1396 enum devlink_command cmd, u32 portid,1396 enum devlink_command cmd, u32 portid,
1397 u32 seq, int flags, u16 mode)1397 u32 seq, int flags)
1398{1398{
1399 const struct devlink_ops *ops = devlink->ops;
1399 void *hdr;1400 void *hdr;
1401 int err = 0;
1402 u16 mode;
1403 u8 inline_mode;
1400 1404
1401 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);1405 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1402 if (!hdr)1406 if (!hdr)
1403 return -EMSGSIZE;1407 return -EMSGSIZE;
1404 1408
1405 if (devlink_nl_put_handle(msg, devlink))1409 err = devlink_nl_put_handle(msg, devlink);
1406 goto nla_put_failure;1410 if (err)
1411 goto out;
1407 1412
1408 if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))1413 err = ops->eswitch_mode_get(devlink, &mode);
1409 goto nla_put_failure;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 }
1410 1429
1411 genlmsg_end(msg, hdr);1430 genlmsg_end(msg, hdr);
1412 return 0;1431 return 0;
1413 1432
1414nla_put_failure:1433out:
1415 genlmsg_cancel(msg, hdr);1434 genlmsg_cancel(msg, hdr);
1416 return -EMSGSIZE;1435 return err;
1417}1436}
1418 1437
1419static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,1438static 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
1422 struct devlink *devlink = info->user_ptr[0];1441 struct devlink *devlink = info->user_ptr[0];
1423 const struct devlink_ops *ops = devlink->ops;1442 const struct devlink_ops *ops = devlink->ops;
1424 struct sk_buff *msg;1443 struct sk_buff *msg;
1425 u16 mode;
1426 int err;1444 int err;
1427 1445
1428 if (!ops || !ops->eswitch_mode_get)1446 if (!ops || !ops->eswitch_mode_get)
1429 return -EOPNOTSUPP;1447 return -EOPNOTSUPP;
1430 1448
1431 err = ops->eswitch_mode_get(devlink, &mode);
1432 if (err)
1433 return err;
1434
1435 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);1449 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1436 if (!msg)1450 if (!msg)
1437 return -ENOMEM;1451 return -ENOMEM;
1438 1452
1439 err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,1453 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);
1441 1455
1442 if (err) {1456 if (err) {
1443 nlmsg_free(msg);1457 nlmsg_free(msg);
@@ -1453,15 +1467,32 @@ static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb, · 9 unmodified lines
1453 struct devlink *devlink = info->user_ptr[0];1467 struct devlink *devlink = info->user_ptr[0];
1454 const struct devlink_ops *ops = devlink->ops;1468 const struct devlink_ops *ops = devlink->ops;
1455 u16 mode;1469 u16 mode;
1470 u8 inline_mode;
1471 int err = 0;
1456 1472
1457 if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])1473 if (!ops)
1458 return -EINVAL;1474 return -EOPNOTSUPP;
1459 1475
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 }
1461 1484
1462 if (ops && ops->eswitch_mode_set)1485 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1463 return ops->eswitch_mode_set(devlink, mode);1486 if (!ops->eswitch_inline_mode_set)
1464 return -EOPNOTSUPP;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;
1465}1496}
1466 1497
1467static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {1498static 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
1478 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },1509 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
1479 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },1510 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1480 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },1511 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
1512 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
1481};1513};
1482 1514
1483static const struct genl_ops devlink_nl_ops[] = {1515static const struct genl_ops devlink_nl_ops[] = {