diff options
Diffstat (limited to 'net/core/devlink.c')
| -rw-r--r-- | net/core/devlink.c | 87 |
1 files changed, 87 insertions, 0 deletions
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 | ||
| 1397 | static 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 | |||
| 1416 | nla_put_failure: | ||
| 1417 | genlmsg_cancel(msg, hdr); | ||
| 1418 | return -EMSGSIZE; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | static 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 | |||
| 1452 | static 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 | |||
| 1397 | static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { | 1469 | static 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 | ||
| 1412 | static const struct genl_ops devlink_nl_ops[] = { | 1485 | static 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 | /** |
