Message ID | 20240130110944.26771-2-r-gunasekaran@ti.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | RPMsg based shared memory ethernet driver | expand |
On Tue, Jan 30, 2024 at 04:39:43PM +0530, Ravi Gunasekaran wrote: > TI's K3 SoCs comprises heterogeneous processors (Cortex A, Cortex R). > When the ethernet controller is completely managed by a core (Cortex R) > running a flavor of RTOS, in a non virtualized environment, network traffic > tunnelling between heterogeneous processors can be realized by means of > RPMsg based shared memory ethernet driver. With the shared memory used > for the data plane and the RPMsg end point channel used for control plane. > > inter-core-virt-eth driver is modelled as a RPMsg based shared > memory ethernet driver for such an use case. > > As a first step, register the inter-core-virt-eth as a RPMsg driver. > And introduce basic control messages for querying and responding. > > Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com> > Signed-off-by: Ravi Gunasekaran <r-gunasekaran@ti.com> > --- > drivers/net/ethernet/ti/inter-core-virt-eth.c | 139 ++++++++++++++++++ > drivers/net/ethernet/ti/inter-core-virt-eth.h | 89 +++++++++++ > 2 files changed, 228 insertions(+) > create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.c > create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.h > > diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.c b/drivers/net/ethernet/ti/inter-core-virt-eth.c > new file mode 100644 > index 000000000000..d3b689eab1c0 > --- /dev/null > +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.c > @@ -0,0 +1,139 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ Hi Ravi and Siddharth, The correct style for SPDX headers in .c files is a '//' comment: // SPDX-License-Identifier: GPL-2.0 > +/* Texas Instruments K3 Inter Core Virtual Ethernet Driver > + * > + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ > + */ ... > diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.h b/drivers/net/ethernet/ti/inter-core-virt-eth.h ... > +struct icve_common { > + struct rpmsg_device *rpdev; > + spinlock_t send_msg_lock; > + spinlock_t recv_msg_lock; Spinlocks ought to come with an comment regarding what they lock. > + struct message send_msg; > + struct message recv_msg; > + struct icve_port *port; > + struct device *dev; > +} __packed; > + > +#endif /* __INTER_CORE_VIRT_ETH_H__ */ > -- > 2.17.1 > >
Simon, On 2/1/2024 7:00 PM, Simon Horman wrote: > On Tue, Jan 30, 2024 at 04:39:43PM +0530, Ravi Gunasekaran wrote: >> TI's K3 SoCs comprises heterogeneous processors (Cortex A, Cortex R). >> When the ethernet controller is completely managed by a core (Cortex R) >> running a flavor of RTOS, in a non virtualized environment, network traffic >> tunnelling between heterogeneous processors can be realized by means of >> RPMsg based shared memory ethernet driver. With the shared memory used >> for the data plane and the RPMsg end point channel used for control plane. >> >> inter-core-virt-eth driver is modelled as a RPMsg based shared >> memory ethernet driver for such an use case. >> >> As a first step, register the inter-core-virt-eth as a RPMsg driver. >> And introduce basic control messages for querying and responding. >> >> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com> >> Signed-off-by: Ravi Gunasekaran <r-gunasekaran@ti.com> >> --- >> drivers/net/ethernet/ti/inter-core-virt-eth.c | 139 ++++++++++++++++++ >> drivers/net/ethernet/ti/inter-core-virt-eth.h | 89 +++++++++++ >> 2 files changed, 228 insertions(+) >> create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.c >> create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.h >> >> diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.c b/drivers/net/ethernet/ti/inter-core-virt-eth.c >> new file mode 100644 >> index 000000000000..d3b689eab1c0 >> --- /dev/null >> +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.c >> @@ -0,0 +1,139 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ > Hi Ravi and Siddharth, > > The correct style for SPDX headers in .c files is a '//' comment: > > // SPDX-License-Identifier: GPL-2.0 I will fix this. >> +/* Texas Instruments K3 Inter Core Virtual Ethernet Driver >> + * >> + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ >> + */ > ... > >> diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.h b/drivers/net/ethernet/ti/inter-core-virt-eth.h > ... > >> +struct icve_common { >> + struct rpmsg_device *rpdev; >> + spinlock_t send_msg_lock; >> + spinlock_t recv_msg_lock; > Spinlocks ought to come with an comment regarding what they lock. I will add the comments as reported by checkpatch. > >> + struct message send_msg; >> + struct message recv_msg; >> + struct icve_port *port; >> + struct device *dev; >> +} __packed; >> + >> +#endif /* __INTER_CORE_VIRT_ETH_H__ */ >> -- >> 2.17.1 >> >> Ravi
Simon, On 2/1/2024 7:00 PM, Simon Horman wrote: > On Tue, Jan 30, 2024 at 04:39:43PM +0530, Ravi Gunasekaran wrote: >> TI's K3 SoCs comprises heterogeneous processors (Cortex A, Cortex R). >> When the ethernet controller is completely managed by a core (Cortex R) >> running a flavor of RTOS, in a non virtualized environment, network traffic >> tunnelling between heterogeneous processors can be realized by means of >> RPMsg based shared memory ethernet driver. With the shared memory used >> for the data plane and the RPMsg end point channel used for control plane. >> >> inter-core-virt-eth driver is modelled as a RPMsg based shared >> memory ethernet driver for such an use case. >> >> As a first step, register the inter-core-virt-eth as a RPMsg driver. >> And introduce basic control messages for querying and responding. >> >> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com> >> Signed-off-by: Ravi Gunasekaran <r-gunasekaran@ti.com> >> --- >> drivers/net/ethernet/ti/inter-core-virt-eth.c | 139 ++++++++++++++++++ >> drivers/net/ethernet/ti/inter-core-virt-eth.h | 89 +++++++++++ >> 2 files changed, 228 insertions(+) >> create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.c >> create mode 100644 drivers/net/ethernet/ti/inter-core-virt-eth.h >> >> diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.c b/drivers/net/ethernet/ti/inter-core-virt-eth.c >> new file mode 100644 >> index 000000000000..d3b689eab1c0 >> --- /dev/null >> +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.c >> @@ -0,0 +1,139 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ > Hi Ravi and Siddharth, > > The correct style for SPDX headers in .c files is a '//' comment: > > // SPDX-License-Identifier: GPL-2.0 I will fix this. >> +/* Texas Instruments K3 Inter Core Virtual Ethernet Driver >> + * >> + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ >> + */ > ... > >> diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.h b/drivers/net/ethernet/ti/inter-core-virt-eth.h > ... > >> +struct icve_common { >> + struct rpmsg_device *rpdev; >> + spinlock_t send_msg_lock; >> + spinlock_t recv_msg_lock; > Spinlocks ought to come with an comment regarding what they lock. I will add the comments as reported by checkpatch. > >> + struct message send_msg; >> + struct message recv_msg; >> + struct icve_port *port; >> + struct device *dev; >> +} __packed; >> + >> +#endif /* __INTER_CORE_VIRT_ETH_H__ */ >> -- >> 2.17.1 >> >> Ravi
diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.c b/drivers/net/ethernet/ti/inter-core-virt-eth.c new file mode 100644 index 000000000000..d3b689eab1c0 --- /dev/null +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.c @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Texas Instruments K3 Inter Core Virtual Ethernet Driver + * + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#include "inter-core-virt-eth.h" + +static int icve_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) +{ + struct icve_common *common = dev_get_drvdata(&rpdev->dev); + struct message *msg = (struct message *)data; + struct icve_port *port = common->port; + u32 msg_type = msg->msg_hdr.msg_type; + u32 rpmsg_type; + + switch (msg_type) { + case ICVE_RESPONSE_MSG: + rpmsg_type = msg->resp_msg.type; + switch (rpmsg_type) { + case ICVE_RESP_SHM_INFO: + + /* Retrieve Tx and Rx shared memory info from msg */ + port->tx_buffer = msg->resp_msg.shm_info.tx_buffer; + + if (!port->tx_buffer) { + dev_err(common->dev, "Tx Buffer invalid\n"); + return -ENOMEM; + } + + port->tx_buffer->base_addr = + msg->resp_msg.shm_info.tx_buffer_base_addr; + + if (!port->tx_buffer->base_addr) { + dev_err(common->dev, "Tx Buffer address invalid\n"); + return -ENOMEM; + } + + port->rx_buffer = msg->resp_msg.shm_info.rx_buffer; + + if (!port->rx_buffer) { + dev_err(common->dev, "Rx Buffer invalid\n"); + return -ENOMEM; + } + + port->rx_buffer->base_addr = + msg->resp_msg.shm_info.rx_buffer_base_addr; + + if (!port->rx_buffer->base_addr) { + dev_err(common->dev, "Rx Buffer address invalid\n"); + return -ENOMEM; + } + + port->icve_max_buffers = + msg->resp_msg.shm_info.max_buffers; + + break; + } + break; + default: + dev_err(common->dev, "Invalid msg type\n"); + break; + } + + return 0; +} + +static int create_request(struct icve_common *common, enum icve_rpmsg_type rpmsg_type) +{ + struct message *msg = &common->send_msg; + int ret = 0; + + msg->msg_hdr.src_id = common->port->port_id; + msg->req_msg.type = rpmsg_type; + + switch (rpmsg_type) { + case ICVE_REQ_SHM_INFO: + msg->msg_hdr.msg_type = ICVE_REQUEST_MSG; + break; + default: + ret = -EINVAL; + dev_err(common->dev, "Invalid RPMSG request\n"); + }; + + return ret; +} + +static int icve_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct device *dev = &rpdev->dev; + struct icve_common *common; + unsigned long flags; + + common = devm_kzalloc(&rpdev->dev, sizeof(*common), GFP_KERNEL); + if (!common) + return -ENOMEM; + + dev_set_drvdata(dev, common); + + common->port = devm_kzalloc(dev, sizeof(*common->port), GFP_KERNEL); + common->dev = dev; + common->rpdev = rpdev; + + spin_lock_init(&common->send_msg_lock); + spin_lock_init(&common->recv_msg_lock); + + /* Send request to fetch shared memory details from remote core */ + spin_lock_irqsave(&common->send_msg_lock, flags); + create_request(common, ICVE_REQ_SHM_INFO); + rpmsg_send(common->rpdev->ept, (void *)(&common->send_msg), sizeof(common->send_msg)); + spin_unlock_irqrestore(&common->send_msg_lock, flags); + + return 0; +} + +static void icve_rpmsg_remove(struct rpmsg_device *rpdev) +{ + dev_info(&rpdev->dev, "icve rpmsg client driver is removed\n"); +} + +static struct rpmsg_device_id icve_rpmsg_id_table[] = { + { .name = "icve-rpsmg-client" }, + { }, +}; +MODULE_DEVICE_TABLE(rpmsg, icve_rpmsg_id_table); + +static struct rpmsg_driver icve_rpmsg_client = { + .drv.name = KBUILD_MODNAME, + .id_table = icve_rpmsg_id_table, + .probe = icve_rpmsg_probe, + .callback = icve_rpmsg_cb, + .remove = icve_rpmsg_remove, +}; +module_rpmsg_driver(icve_rpmsg_client); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Siddharth Vadapalli <s-vadapalli@ti.com>"); +MODULE_AUTHOR("Ravi Gunasekaran <r-gunasekaran@ti.com"); +MODULE_DESCRIPTION("TI Inter Core Virtual Ethernet driver"); diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.h b/drivers/net/ethernet/ti/inter-core-virt-eth.h new file mode 100644 index 000000000000..063cc371eeb3 --- /dev/null +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Texas Instruments K3 Inter Core Virtual Ethernet Driver + * + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#ifndef __INTER_CORE_VIRT_ETH_H__ +#define __INTER_CORE_VIRT_ETH_H__ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/rpmsg.h> + +enum icve_msg_type { + ICVE_REQUEST_MSG = 0, + ICVE_RESPONSE_MSG, +}; + +enum icve_rpmsg_type { + /* Request types */ + ICVE_REQ_SHM_INFO = 0, + + /* Response types */ + ICVE_RESP_SHM_INFO, +}; + +struct icve_shm_info { + void *tx_buffer; + void *tx_buffer_base_addr; + void *rx_buffer; + void *rx_buffer_base_addr; + u32 max_buffers; +} __packed; + +struct request_message { + u32 type; /* Request Type */ +} __packed; + +struct response_message { + u32 type; + union { + struct icve_shm_info shm_info; + }; +} __packed; + +struct notify_message { + u32 type; +} __packed; + +struct message_header { + u32 src_id; + u32 msg_type; /* Do not use enum type, as enum size is compiler dependent */ +} __packed; + +struct message { + struct message_header msg_hdr; + union { + struct request_message req_msg; + struct response_message resp_msg; + struct notify_message notify_msg; + }; +} __packed; + +struct shared_mem { + u32 head; + u32 tail; + void *base_addr; +} __packed; + +struct icve_port { + struct shared_mem *tx_buffer; /* Write buffer for data to be consumed remote side */ + struct shared_mem *rx_buffer; /* Read buffer for data to be consumed by this driver */ + struct icve_common *common; + u32 icve_max_buffers; + u32 port_id; /* Unique ID for the port : TODO: Define range for use by Linux and non linux */ + +} __packed; + +struct icve_common { + struct rpmsg_device *rpdev; + spinlock_t send_msg_lock; + spinlock_t recv_msg_lock; + struct message send_msg; + struct message recv_msg; + struct icve_port *port; + struct device *dev; +} __packed; + +#endif /* __INTER_CORE_VIRT_ETH_H__ */