aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2016-07-01 07:51:01 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-02 14:40:40 -0400
commit08f4b5918b2d6b491f0403cc1886f5cdccef89bb (patch)
tree35da396f43f718b63095c9e552ec4cfe26a27a6e
parentfed9ce22bf8ae8f417b8f047d2d630542d152ccf (diff)
net/devlink: Add E-Switch mode control
Add the commands to set and show the mode of SRIOV E-Switch, two modes are supported: * legacy: operating in the "old" L2 based mode (DMAC --> VF vport) * switchdev: the E-Switch is referred to as whitebox switch configured using standard tools such as tc, bridge, openvswitch etc. To allow working with the tools, for each VF, a VF representor netdevice is created by the E-Switch manager vendor device driver instance (e.g PF). Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/devlink.h3
-rw-r--r--include/uapi/linux/devlink.h8
-rw-r--r--net/core/devlink.c87
3 files changed, 98 insertions, 0 deletions
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 1d45b61cb320..c99ffe8cef3c 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -90,6 +90,9 @@ struct devlink_ops {
90 u16 tc_index, 90 u16 tc_index,
91 enum devlink_sb_pool_type pool_type, 91 enum devlink_sb_pool_type pool_type,
92 u32 *p_cur, u32 *p_max); 92 u32 *p_cur, u32 *p_max);
93
94 int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
95 int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
93}; 96};
94 97
95static inline void *devlink_priv(struct devlink *devlink) 98static inline void *devlink_priv(struct devlink *devlink)
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index ba0073b26fa6..915bfa74458c 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -57,6 +57,8 @@ enum devlink_command {
57 DEVLINK_CMD_SB_OCC_SNAPSHOT, 57 DEVLINK_CMD_SB_OCC_SNAPSHOT,
58 DEVLINK_CMD_SB_OCC_MAX_CLEAR, 58 DEVLINK_CMD_SB_OCC_MAX_CLEAR,
59 59
60 DEVLINK_CMD_ESWITCH_MODE_GET,
61 DEVLINK_CMD_ESWITCH_MODE_SET,
60 /* add new commands above here */ 62 /* add new commands above here */
61 63
62 __DEVLINK_CMD_MAX, 64 __DEVLINK_CMD_MAX,
@@ -95,6 +97,11 @@ enum devlink_sb_threshold_type {
95 97
96#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20 98#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20
97 99
100enum devlink_eswitch_mode {
101 DEVLINK_ESWITCH_MODE_LEGACY,
102 DEVLINK_ESWITCH_MODE_SWITCHDEV,
103};
104
98enum devlink_attr { 105enum devlink_attr {
99 /* don't change the order or add anything between, this is ABI! */ 106 /* don't change the order or add anything between, this is ABI! */
100 DEVLINK_ATTR_UNSPEC, 107 DEVLINK_ATTR_UNSPEC,
@@ -125,6 +132,7 @@ enum devlink_attr {
125 DEVLINK_ATTR_SB_TC_INDEX, /* u16 */ 132 DEVLINK_ATTR_SB_TC_INDEX, /* u16 */
126 DEVLINK_ATTR_SB_OCC_CUR, /* u32 */ 133 DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
127 DEVLINK_ATTR_SB_OCC_MAX, /* u32 */ 134 DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
135 DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
128 136
129 /* add new attributes above here, update the policy in devlink.c */ 137 /* add new attributes above here, update the policy in devlink.c */
130 138
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 933e8d4d3968..b2e592a198c0 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -1394,6 +1394,78 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1394 return -EOPNOTSUPP; 1394 return -EOPNOTSUPP;
1395} 1395}
1396 1396
1397static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1398 enum devlink_command cmd, u32 portid,
1399 u32 seq, int flags, u16 mode)
1400{
1401 void *hdr;
1402
1403 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1404 if (!hdr)
1405 return -EMSGSIZE;
1406
1407 if (devlink_nl_put_handle(msg, devlink))
1408 goto nla_put_failure;
1409
1410 if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
1411 goto nla_put_failure;
1412
1413 genlmsg_end(msg, hdr);
1414 return 0;
1415
1416nla_put_failure:
1417 genlmsg_cancel(msg, hdr);
1418 return -EMSGSIZE;
1419}
1420
1421static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
1422 struct genl_info *info)
1423{
1424 struct devlink *devlink = info->user_ptr[0];
1425 const struct devlink_ops *ops = devlink->ops;
1426 struct sk_buff *msg;
1427 u16 mode;
1428 int err;
1429
1430 if (!ops || !ops->eswitch_mode_get)
1431 return -EOPNOTSUPP;
1432
1433 err = ops->eswitch_mode_get(devlink, &mode);
1434 if (err)
1435 return err;
1436
1437 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1438 if (!msg)
1439 return -ENOMEM;
1440
1441 err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
1442 info->snd_portid, info->snd_seq, 0, mode);
1443
1444 if (err) {
1445 nlmsg_free(msg);
1446 return err;
1447 }
1448
1449 return genlmsg_reply(msg, info);
1450}
1451
1452static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
1453 struct genl_info *info)
1454{
1455 struct devlink *devlink = info->user_ptr[0];
1456 const struct devlink_ops *ops = devlink->ops;
1457 u16 mode;
1458
1459 if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
1460 return -EINVAL;
1461
1462 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1463
1464 if (ops && ops->eswitch_mode_set)
1465 return ops->eswitch_mode_set(devlink, mode);
1466 return -EOPNOTSUPP;
1467}
1468
1397static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 1469static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1398 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 1470 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
1399 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 1471 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
@@ -1407,6 +1479,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1407 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 1479 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
1408 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 1480 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
1409 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 1481 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1482 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
1410}; 1483};
1411 1484
1412static const struct genl_ops devlink_nl_ops[] = { 1485static const struct genl_ops devlink_nl_ops[] = {
@@ -1525,6 +1598,20 @@ static const struct genl_ops devlink_nl_ops[] = {
1525 DEVLINK_NL_FLAG_NEED_SB | 1598 DEVLINK_NL_FLAG_NEED_SB |
1526 DEVLINK_NL_FLAG_LOCK_PORTS, 1599 DEVLINK_NL_FLAG_LOCK_PORTS,
1527 }, 1600 },
1601 {
1602 .cmd = DEVLINK_CMD_ESWITCH_MODE_GET,
1603 .doit = devlink_nl_cmd_eswitch_mode_get_doit,
1604 .policy = devlink_nl_policy,
1605 .flags = GENL_ADMIN_PERM,
1606 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1607 },
1608 {
1609 .cmd = DEVLINK_CMD_ESWITCH_MODE_SET,
1610 .doit = devlink_nl_cmd_eswitch_mode_set_doit,
1611 .policy = devlink_nl_policy,
1612 .flags = GENL_ADMIN_PERM,
1613 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1614 },
1528}; 1615};
1529 1616
1530/** 1617/**