| @@ -1394,6 +1394,78 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, · 1393 unmodified lines |
| 1394 | 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 | 1469 | static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { |
| 1398 | 1470 | [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, |
| 1399 | 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] = { · 7 unmodified lines |
| 1407 | 1479 | [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, |
| 1408 | 1480 | [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, |
| 1409 | 1481 | [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, |
| 1482 | + [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 }, |
| 1410 | 1483 | }; |
| 1411 | 1484 | |
| 1412 | 1485 | static const struct genl_ops devlink_nl_ops[] = { |
| @@ -1525,6 +1598,20 @@ static const struct genl_ops devlink_nl_ops[] = { · 112 unmodified lines |
| 1525 | 1598 | DEVLINK_NL_FLAG_NEED_SB | |
| 1526 | 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 | /** |