Commit 53c6b86c authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'i3c-mctp-net-driver'

Matt Johnston says:

====================
I3C MCTP net driver

This series adds an I3C transport for the kernel's MCTP network
protocol. MCTP is a communication protocol between system components
(BMCs, drives, NICs etc), with higher level protocols such as NVMe-MI or
PLDM built on top of it (in userspace). It runs over various transports
such as I2C, PCIe, or I3C.

The mctp-i3c driver follows a similar approach to the kernel's existing
mctp-i2c driver, creating a "mctpi3cX" network interface for each
numbered I3C bus. Busses opt in to support by adding a "mctp-controller"
property to the devicetree:

&i3c0 {
        mctp-controller;
}

The driver will bind to MCTP class devices (DCR 0xCC) that are on a
supported I3C bus. Each bus is represented by a `struct mctp_i3c_bus`
that keeps state for the network device. An individual I3C device
(struct mctp_i3c_device) performs operations using the "parent"
mctp_i3c_bus object. The I3C notify/enumeration patch is needed so that
the mctp-i3c driver can handle creating/removing mctp_i3c_bus objects as
required.

The mctp-i3c driver is using the Provisioned ID as an identifier for
target I3C devices (the neighbour address), as that will be more stable
than the I3C dynamic address. The driver internally translates that to a
dynamic address for bus operations.

The driver has been tested using an AST2600 platform. A remote endpoint
has been tested against QEMU, as well as using the target mode support
in Aspeed's vendor tree.

I3C maintainers have acked merging this through net-next tree.
====================

Link: https://lore.kernel.org/r/20231013040628.354323-1-matt@codeconstruct.com.auSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 1b2d3b45 c8755b29
...@@ -55,6 +55,12 @@ properties: ...@@ -55,6 +55,12 @@ properties:
May not be supported by all controllers. May not be supported by all controllers.
mctp-controller:
type: boolean
description: |
Indicates that the system is accessible via this bus as an endpoint for
MCTP over I3C transport.
required: required:
- "#address-cells" - "#address-cells"
- "#size-cells" - "#size-cells"
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
static DEFINE_IDR(i3c_bus_idr); static DEFINE_IDR(i3c_bus_idr);
static DEFINE_MUTEX(i3c_core_lock); static DEFINE_MUTEX(i3c_core_lock);
static int __i3c_first_dynamic_bus_num; static int __i3c_first_dynamic_bus_num;
static BLOCKING_NOTIFIER_HEAD(i3c_bus_notifier);
/** /**
* i3c_bus_maintenance_lock - Lock the bus for a maintenance operation * i3c_bus_maintenance_lock - Lock the bus for a maintenance operation
...@@ -453,6 +454,36 @@ static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np) ...@@ -453,6 +454,36 @@ static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np)
return 0; return 0;
} }
void i3c_for_each_bus_locked(int (*fn)(struct i3c_bus *bus, void *data),
void *data)
{
struct i3c_bus *bus;
int id;
mutex_lock(&i3c_core_lock);
idr_for_each_entry(&i3c_bus_idr, bus, id)
fn(bus, data);
mutex_unlock(&i3c_core_lock);
}
EXPORT_SYMBOL_GPL(i3c_for_each_bus_locked);
int i3c_register_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&i3c_bus_notifier, nb);
}
EXPORT_SYMBOL_GPL(i3c_register_notifier);
int i3c_unregister_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&i3c_bus_notifier, nb);
}
EXPORT_SYMBOL_GPL(i3c_unregister_notifier);
static void i3c_bus_notify(struct i3c_bus *bus, unsigned int action)
{
blocking_notifier_call_chain(&i3c_bus_notifier, action, bus);
}
static const char * const i3c_bus_mode_strings[] = { static const char * const i3c_bus_mode_strings[] = {
[I3C_BUS_MODE_PURE] = "pure", [I3C_BUS_MODE_PURE] = "pure",
[I3C_BUS_MODE_MIXED_FAST] = "mixed-fast", [I3C_BUS_MODE_MIXED_FAST] = "mixed-fast",
...@@ -2682,6 +2713,8 @@ int i3c_master_register(struct i3c_master_controller *master, ...@@ -2682,6 +2713,8 @@ int i3c_master_register(struct i3c_master_controller *master,
if (ret) if (ret)
goto err_del_dev; goto err_del_dev;
i3c_bus_notify(i3cbus, I3C_NOTIFY_BUS_ADD);
/* /*
* We're done initializing the bus and the controller, we can now * We're done initializing the bus and the controller, we can now
* register I3C devices discovered during the initial DAA. * register I3C devices discovered during the initial DAA.
...@@ -2714,6 +2747,8 @@ EXPORT_SYMBOL_GPL(i3c_master_register); ...@@ -2714,6 +2747,8 @@ EXPORT_SYMBOL_GPL(i3c_master_register);
*/ */
void i3c_master_unregister(struct i3c_master_controller *master) void i3c_master_unregister(struct i3c_master_controller *master)
{ {
i3c_bus_notify(&master->bus, I3C_NOTIFY_BUS_REMOVE);
i3c_master_i2c_adapter_cleanup(master); i3c_master_i2c_adapter_cleanup(master);
i3c_master_unregister_i3c_devs(master); i3c_master_unregister_i3c_devs(master);
i3c_master_bus_cleanup(master); i3c_master_bus_cleanup(master);
......
...@@ -33,6 +33,15 @@ config MCTP_TRANSPORT_I2C ...@@ -33,6 +33,15 @@ config MCTP_TRANSPORT_I2C
from DMTF specification DSP0237. A MCTP protocol network device is from DMTF specification DSP0237. A MCTP protocol network device is
created for each I2C bus that has been assigned a mctp-i2c device. created for each I2C bus that has been assigned a mctp-i2c device.
config MCTP_TRANSPORT_I3C
tristate "MCTP I3C transport"
depends on I3C
help
Provides a driver to access MCTP devices over I3C transport,
from DMTF specification DSP0233.
A MCTP protocol network device is created for each I3C bus
having a "mctp-controller" devicetree property.
endmenu endmenu
endif endif
obj-$(CONFIG_MCTP_SERIAL) += mctp-serial.o obj-$(CONFIG_MCTP_SERIAL) += mctp-serial.o
obj-$(CONFIG_MCTP_TRANSPORT_I2C) += mctp-i2c.o obj-$(CONFIG_MCTP_TRANSPORT_I2C) += mctp-i2c.o
obj-$(CONFIG_MCTP_TRANSPORT_I3C) += mctp-i3c.o
This diff is collapsed.
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
struct i2c_client; struct i2c_client;
/* notifier actions. notifier call data is the struct i3c_bus */
enum {
I3C_NOTIFY_BUS_ADD,
I3C_NOTIFY_BUS_REMOVE,
};
struct i3c_master_controller; struct i3c_master_controller;
struct i3c_bus; struct i3c_bus;
struct i3c_device; struct i3c_device;
...@@ -652,4 +658,9 @@ void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot); ...@@ -652,4 +658,9 @@ void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot);
struct i3c_ibi_slot *i3c_master_get_free_ibi_slot(struct i3c_dev_desc *dev); struct i3c_ibi_slot *i3c_master_get_free_ibi_slot(struct i3c_dev_desc *dev);
void i3c_for_each_bus_locked(int (*fn)(struct i3c_bus *bus, void *data),
void *data);
int i3c_register_notifier(struct notifier_block *nb);
int i3c_unregister_notifier(struct notifier_block *nb);
#endif /* I3C_MASTER_H */ #endif /* I3C_MASTER_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment