Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mctp: Expose transport binding identifier via IFLA attribute

MCTP control protocol implementations are transport binding dependent.
Endpoint discovery is mandatory based on transport binding.
Message timing requirements are specified in each respective transport
binding specification.

However, we currently have no means to get this information from MCTP
links.

Add a IFLA_MCTP_PHYS_BINDING netlink link attribute, which represents
the transport type using the DMTF DSP0239-defined type numbers, returned
as part of RTM_GETLINK data.

We get an IFLA_MCTP_PHYS_BINDING attribute for each MCTP link, for
example:

- 0x00 (unspec) for loopback interface;
- 0x01 (SMBus/I2C) for mctpi2c%d interfaces; and
- 0x05 (serial) for mctpserial%d interfaces.

Signed-off-by: Khang Nguyen <khangng@os.amperecomputing.com>
Reviewed-by: Matt Johnston <matt@codeconstruct.com.au>
Link: https://patch.msgid.link/20241105071915.821871-1-khangng@os.amperecomputing.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Khang Nguyen and committed by
Jakub Kicinski
580db513 4861333b

+37 -8
+2 -1
drivers/net/mctp/mctp-i2c.c
··· 880 880 goto err; 881 881 } 882 882 883 - rc = mctp_register_netdev(ndev, &mctp_i2c_mctp_ops); 883 + rc = mctp_register_netdev(ndev, &mctp_i2c_mctp_ops, 884 + MCTP_PHYS_BINDING_SMBUS); 884 885 if (rc < 0) { 885 886 dev_err(&mcli->client->dev, 886 887 "register netdev \"%s\" failed %d\n",
+1 -1
drivers/net/mctp/mctp-i3c.c
··· 607 607 goto err_free_uninit; 608 608 } 609 609 610 - rc = mctp_register_netdev(ndev, NULL); 610 + rc = mctp_register_netdev(ndev, NULL, MCTP_PHYS_BINDING_I3C); 611 611 if (rc < 0) { 612 612 dev_warn(&ndev->dev, "netdev register failed: %d\n", rc); 613 613 goto err_free_netdev;
+3 -2
drivers/net/mctp/mctp-serial.c
··· 23 23 24 24 #include <linux/mctp.h> 25 25 #include <net/mctp.h> 26 + #include <net/mctpdevice.h> 26 27 #include <net/pkt_sched.h> 27 28 28 29 #define MCTP_SERIAL_MTU 68 /* base mtu (64) + mctp header */ ··· 471 470 spin_lock_init(&dev->lock); 472 471 INIT_WORK(&dev->tx_work, mctp_serial_tx_work); 473 472 474 - rc = register_netdev(ndev); 473 + rc = mctp_register_netdev(ndev, NULL, MCTP_PHYS_BINDING_SERIAL); 475 474 if (rc) 476 475 goto free_netdev; 477 476 ··· 493 492 struct mctp_serial *dev = tty->disc_data; 494 493 int idx = dev->idx; 495 494 496 - unregister_netdev(dev->netdev); 495 + mctp_unregister_netdev(dev->netdev); 497 496 ida_free(&mctp_serial_ida, idx); 498 497 } 499 498
+18
include/net/mctp.h
··· 298 298 int mctp_device_init(void); 299 299 void mctp_device_exit(void); 300 300 301 + /* MCTP IDs and Codes from DMTF specification 302 + * "DSP0239 Management Component Transport Protocol (MCTP) IDs and Codes" 303 + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0239_1.11.1.pdf 304 + */ 305 + enum mctp_phys_binding { 306 + MCTP_PHYS_BINDING_UNSPEC = 0x00, 307 + MCTP_PHYS_BINDING_SMBUS = 0x01, 308 + MCTP_PHYS_BINDING_PCIE_VDM = 0x02, 309 + MCTP_PHYS_BINDING_USB = 0x03, 310 + MCTP_PHYS_BINDING_KCS = 0x04, 311 + MCTP_PHYS_BINDING_SERIAL = 0x05, 312 + MCTP_PHYS_BINDING_I3C = 0x06, 313 + MCTP_PHYS_BINDING_MMBI = 0x07, 314 + MCTP_PHYS_BINDING_PCC = 0x08, 315 + MCTP_PHYS_BINDING_UCIE = 0x09, 316 + MCTP_PHYS_BINDING_VENDOR = 0xFF, 317 + }; 318 + 301 319 #endif /* __NET_MCTP_H */
+3 -1
include/net/mctpdevice.h
··· 22 22 refcount_t refs; 23 23 24 24 unsigned int net; 25 + enum mctp_phys_binding binding; 25 26 26 27 const struct mctp_netdev_ops *ops; 27 28 ··· 45 44 struct mctp_dev *__mctp_dev_get(const struct net_device *dev); 46 45 47 46 int mctp_register_netdev(struct net_device *dev, 48 - const struct mctp_netdev_ops *ops); 47 + const struct mctp_netdev_ops *ops, 48 + enum mctp_phys_binding binding); 49 49 void mctp_unregister_netdev(struct net_device *dev); 50 50 51 51 void mctp_dev_hold(struct mctp_dev *mdev);
+1
include/uapi/linux/if_link.h
··· 1958 1958 enum { 1959 1959 IFLA_MCTP_UNSPEC, 1960 1960 IFLA_MCTP_NET, 1961 + IFLA_MCTP_PHYS_BINDING, 1961 1962 __IFLA_MCTP_MAX, 1962 1963 }; 1963 1964
+9 -3
net/mctp/device.c
··· 371 371 return -ENODATA; 372 372 if (nla_put_u32(skb, IFLA_MCTP_NET, mdev->net)) 373 373 return -EMSGSIZE; 374 + if (nla_put_u8(skb, IFLA_MCTP_PHYS_BINDING, mdev->binding)) 375 + return -EMSGSIZE; 374 376 return 0; 375 377 } 376 378 ··· 387 385 if (!mdev) 388 386 return 0; 389 387 ret = nla_total_size(4); /* IFLA_MCTP_NET */ 388 + ret += nla_total_size(1); /* IFLA_MCTP_PHYS_BINDING */ 390 389 mctp_dev_put(mdev); 391 390 return ret; 392 391 } ··· 483 480 } 484 481 485 482 static int mctp_register_netdevice(struct net_device *dev, 486 - const struct mctp_netdev_ops *ops) 483 + const struct mctp_netdev_ops *ops, 484 + enum mctp_phys_binding binding) 487 485 { 488 486 struct mctp_dev *mdev; 489 487 ··· 493 489 return PTR_ERR(mdev); 494 490 495 491 mdev->ops = ops; 492 + mdev->binding = binding; 496 493 497 494 return register_netdevice(dev); 498 495 } 499 496 500 497 int mctp_register_netdev(struct net_device *dev, 501 - const struct mctp_netdev_ops *ops) 498 + const struct mctp_netdev_ops *ops, 499 + enum mctp_phys_binding binding) 502 500 { 503 501 int rc; 504 502 505 503 rtnl_lock(); 506 - rc = mctp_register_netdevice(dev, ops); 504 + rc = mctp_register_netdevice(dev, ops, binding); 507 505 rtnl_unlock(); 508 506 509 507 return rc;