From patchwork Tue Jan 30 11:09:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Gunasekaran X-Patchwork-Id: 193996 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1139714dyb; Tue, 30 Jan 2024 03:10:53 -0800 (PST) X-Google-Smtp-Source: AGHT+IEWAuKMAWRBcLXl7vyMu4tY8qVM6ugrWnFsMAq2DNul+tlsBbR7x6EzuYxfmB2tl3T3zAIY X-Received: by 2002:a05:6214:1253:b0:681:5bb8:e27c with SMTP id r19-20020a056214125300b006815bb8e27cmr12009939qvv.50.1706613053520; Tue, 30 Jan 2024 03:10:53 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706613053; cv=pass; d=google.com; s=arc-20160816; b=IL8QqcG0LDNn2Be93SN8d7NhdCH6xmMKwgoHx3F663ENvPZlTM+EKDYY/+5CRBWLlQ wPmhlF+UUHFD+pN5W1aZ2oyW4+XOblcmb1v4rtMhFuFBPEjxNwbyK6wlSqTHO8JwrZGA 4JvkWnX/BECOc8jVdx+6777dTo6ruozXY/pTtciZlenKkAGrhYinGkN/Zx3jcI3QFW9W eohr/MCydwdnHezQr7rMw8SF+kp3VMxDhcrebnLJDc50vCyqyxlD9y88rsuwbt4adKja p4jkmBl5jQnGh/BjDyBhVA7zHP4ikCm+TQrhHEcVdhTTSubwPnvDNssqVXxkK48GgrlG PTrw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=IKw60T4XT/07rIA6OzLOY16F0C5tx6w/Op4PK8bg8L0=; fh=7oI3cA6Qh3tfegtSQ0I+PABGDIobnfSo070kQZjlRfA=; b=Yzj99h9DFN2PwnMsTv8gLimCopRGTDRceRi1/415IGvkc0IuAJKt//H/F6sZkfIG3b lWMCsUNwRRnraFLBQaiwpatJSjbnKa7E+lMXjPEn3TOnxnyzFkch2wvZ59KIadMzLHgF aHhlAJ0GKWnSHjppK8xlhUIxasdeg0fU50pFpPhgApjDVv3gFD8n1gzQ5GGk1hGyrU2i ifUBWFjeDpSOUdT+pK0K0OXvrYEjXBb1dRbzQUFx2DOCjS4Wdd5qg0wOjubxlA1KCVaD Z4XDyVjn69jpWcDTdyxic1QqIL84pXPIpCDY42mHAuhmFpFvYmTfWIzC+3g3M7cy2Nxm icjw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=FPNiddXf; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-44461-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44461-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id iw8-20020a0562140f2800b006818f0b3569si9852610qvb.182.2024.01.30.03.10.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 03:10:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-44461-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=FPNiddXf; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-44461-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44461-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 42F211C2048A for ; Tue, 30 Jan 2024 11:10:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 43BFD679F0; Tue, 30 Jan 2024 11:10:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="FPNiddXf" Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE16266B44; Tue, 30 Jan 2024 11:10:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.249 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706613008; cv=none; b=mP985hp14SultbzNTCt/VjugToXFsKzSIYNmc8/0RFLiFxqntBtDBIqUlWiN9tZWw8Xg6ztziTt+0N2wDtZNWUBAFjaad7IRIDFMwiMJFFCCloELkwXe38k/6WQpG+JfIaJlqnYm4dGuGklNkhzgdZqMunn+7PWlC6wI/6dWb9U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706613008; c=relaxed/simple; bh=zVwO8g0LB/InIsnZFUFRTolbpeB9KuIQB5fFaiaHaOQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SUT0H7/OW+exu6DQRd7/I8hu3VctSxKSO63PCZdhWVOOEqKSI6/RFazmEY8Ft7sg7OofuYuOBQmmjdIBgxsIxmV9BRaPB9GFGqZR2ri8dzcCGuOUYu5HzEFbCK6hGLHJzeeiHkCkyKO6g7VI5OuoCIBV7u8zMt7m/g3sBW5nRk0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=FPNiddXf; arc=none smtp.client-ip=198.47.23.249 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 40UB9psG048437; Tue, 30 Jan 2024 05:09:51 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1706612991; bh=IKw60T4XT/07rIA6OzLOY16F0C5tx6w/Op4PK8bg8L0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=FPNiddXfUiyWV44c48J5T9P9R8Lt49ZhUYtTb+bamaGtPtMf0vBZDWtNs73j/2csg 0VnKBlcYXzIYqZYRrXrHDQ8/BqGzhFe0DYKh8hnRL26ugPIcvDs4fMqB/c8IA5eZGA SJdovcdQ76BVQJavgGXHsB2/h0fHdeEo/3Wf3WXA= Received: from DFLE106.ent.ti.com (dfle106.ent.ti.com [10.64.6.27]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 40UB9p25006264 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 30 Jan 2024 05:09:51 -0600 Received: from DFLE109.ent.ti.com (10.64.6.30) by DFLE106.ent.ti.com (10.64.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Tue, 30 Jan 2024 05:09:51 -0600 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Tue, 30 Jan 2024 05:09:51 -0600 Received: from uda0500640.dal.design.ti.com (uda0500640.dhcp.ti.com [172.24.227.88]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 40UB9ilM088313; Tue, 30 Jan 2024 05:09:48 -0600 From: Ravi Gunasekaran To: , , , , , CC: , , , , Subject: [RFC PATCH net-next 1/2] net: ethernet: ti: Introduce inter-core-virt-eth as RPMsg driver Date: Tue, 30 Jan 2024 16:39:43 +0530 Message-ID: <20240130110944.26771-2-r-gunasekaran@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240130110944.26771-1-r-gunasekaran@ti.com> References: <20240130110944.26771-1-r-gunasekaran@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789513489481181527 X-GMAIL-MSGID: 1789513489481181527 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 Signed-off-by: Ravi Gunasekaran --- 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 */ +/* 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 "); +MODULE_AUTHOR("Ravi Gunasekaran +#include +#include + +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__ */ From patchwork Tue Jan 30 11:09:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Gunasekaran X-Patchwork-Id: 193997 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1139768dyb; Tue, 30 Jan 2024 03:11:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IEy49Ddfaqk1fcZm5fUaQNbgaGZJQBUriEze9GnN3Ze+kUUxGboYDqSMtT8ysbGjURqmw+E X-Received: by 2002:a17:906:250e:b0:a35:d943:b183 with SMTP id i14-20020a170906250e00b00a35d943b183mr3172946ejb.35.1706613061097; Tue, 30 Jan 2024 03:11:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706613061; cv=pass; d=google.com; s=arc-20160816; b=cJNlNI/NnLiJG+8LZZhVhsH4ph6V21cRGQfH5mcC47vhW12LIX1d7VC5k50C3N5oEM 7vN6XYC0GBOmpJQL2etQ8BUHTTAsaFeAZegHvi5JCd+poONMqju8rBQgn4vm3IZ1b2Xq 8vhJKomQCuv5d+gtp1baLEpjiPC/A+PoXixY+/q05lXoMIQpMyFuQkvbfRKUcNo7LAJp 0UsHLQxUUSzrFM/kdXvhwZjaWXhOyQhsmq2uX5uNGEmDZFkZcoPWMYVX1ciOpHgYwhXn Ajyrbq4mhjb4T11ZY7NkhH0n2pzHRa1J2/vLK3rHfZ2aBA3BMmm3xCrPuH1N/zjh2Wh9 iGEw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/V7a58F1h3DLOzTckEeq6hpC2iW8uzFzmbeUl9ahhvg=; fh=7oI3cA6Qh3tfegtSQ0I+PABGDIobnfSo070kQZjlRfA=; b=SXXX92ztKo6fabuqUAPKZ0rsRMQY1U5SN52N8h3eJ7Kmn7cchyWZVszXORx6bmu1Km D7JB4KzUQ0HC1dA08rox8qUnP9GSIFMGCj/hhhPJytuh08YBUmp2e+YWHO9SABSLegOO M0Ijpnn0S9Ze7uTn1pNv3kF2c9Kn45XUVGjOBHquNn38bsp331Y5a3mtMoa2H4XWH6SJ X/TezluSgeLf5HzjoGb8JIkHnLyHbcyH5yH0EmtWMHA0bzSOVc64xrYAYmCx1/mcasPt O77XpkZvVtXU5kNnOVx5Uo6lBxgRZhKlFhIPZPJPz8M1ARbtgw66WUyZ7E2Q1EJ8qdrl +IRw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=kwN0S6WB; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-44462-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44462-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id o25-20020a17090611d900b00a2ebff8ea29si4533608eja.996.2024.01.30.03.11.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 03:11:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-44462-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=kwN0S6WB; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-44462-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44462-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 88C191F221B9 for ; Tue, 30 Jan 2024 11:11:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EB2C667A05; Tue, 30 Jan 2024 11:10:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="kwN0S6WB" Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6A6F65BD1; Tue, 30 Jan 2024 11:10:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.141 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706613009; cv=none; b=UmEnHfSctMsX3b+ks0FDESN9dsN2ug3FZvUGpamkSPgJ4kGbrp8cgTQVaWwzRCuBOWnUlgFm0ZNuwdw7Czx8zVwyyEDm7dpB64Rq0sPRU1tS1Gj0jyoZa4IIKCaNA1GktUu9kbCuImRVx1fQ16K/XFohVIpn4U/UzoX9zruVTlg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706613009; c=relaxed/simple; bh=oGKQ4VIBZ3R0H8ztybGkZoTw1V+p+t5P91wTT/xkoVU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WnHVN4RlB/86uJ9wp313qHXeSyvot8B6n1G6Hu8skz/+NlQp8HxsLgdLyMXW6Z+sk5TmyVFlUMUeveOfYri79L18xi7+FMouVyVpshnbSpXa4nZ+dmYWvYY2kwY5IM1S59dy+y3MQpvaqoFYjMAWoCR1lkRvrVsMcZXGNFR5eiQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=kwN0S6WB; arc=none smtp.client-ip=198.47.19.141 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 40UB9sV4088089; Tue, 30 Jan 2024 05:09:54 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1706612994; bh=/V7a58F1h3DLOzTckEeq6hpC2iW8uzFzmbeUl9ahhvg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=kwN0S6WBVIpdlzAzObfC4BhZ1HXcU58V5/b8xj305w3SME3oVyrbuQeojVvIE5G2o i652VRBifpow3EbQzP43KPfp5DAbpLxBQJ2DMjOaWYF2XR2Wp80HRlfXB5yIWAguXt yBGrNdhxl1SQB9xgZL1h2ZsB6vcAmz/XkFkE2M+Y= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 40UB9sAa006299 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 30 Jan 2024 05:09:54 -0600 Received: from DFLE105.ent.ti.com (10.64.6.26) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Tue, 30 Jan 2024 05:09:54 -0600 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Tue, 30 Jan 2024 05:09:54 -0600 Received: from uda0500640.dal.design.ti.com (uda0500640.dhcp.ti.com [172.24.227.88]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 40UB9ilN088313; Tue, 30 Jan 2024 05:09:51 -0600 From: Ravi Gunasekaran To: , , , , , CC: , , , , Subject: [RFC PATCH net-next 2/2] net: ethernet: ti: inter-core-virt-eth: Register as network device Date: Tue, 30 Jan 2024 16:39:44 +0530 Message-ID: <20240130110944.26771-3-r-gunasekaran@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240130110944.26771-1-r-gunasekaran@ti.com> References: <20240130110944.26771-1-r-gunasekaran@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789513497006731327 X-GMAIL-MSGID: 1789513497006731327 Register the RPMsg driver as network device and add support for basic ethernet functionality by using the shared memory for data plane. The shared memory layout is as below, with the region between PKT_1_LEN to PKT_N modelled as circular buffer. ------------------------- | HEAD | ------------------------- | TAIL | ------------------------- | PKT_1_LEN | | PKT_1 | ------------------------- | PKT_2_LEN | | PKT_2 | ------------------------- | . | | . | ------------------------- | PKT_N_LEN | | PKT_N | ------------------------- The offset between the HEAD and TAIL is polled to process the Rx packets. Signed-off-by: Siddharth Vadapalli Signed-off-by: Ravi Gunasekaran --- drivers/net/ethernet/ti/inter-core-virt-eth.c | 316 ++++++++++++++++++ drivers/net/ethernet/ti/inter-core-virt-eth.h | 16 + 2 files changed, 332 insertions(+) diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.c b/drivers/net/ethernet/ti/inter-core-virt-eth.c index d3b689eab1c0..735482001f4d 100644 --- a/drivers/net/ethernet/ti/inter-core-virt-eth.c +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.c @@ -6,6 +6,50 @@ #include "inter-core-virt-eth.h" +#define ICVE_MIN_PACKET_SIZE ETH_ZLEN +#define ICVE_MAX_PACKET_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN) +#define ICVE_MAX_TX_QUEUES 1 +#define ICVE_MAX_RX_QUEUES 1 + +#define TEST_DEBUG 1 + +#ifdef TEST_DEBUG +#define ICVE_MAX_BUFFERS 100 //TODO : Set to power of 2 to leverage shift operations +#endif + +#define PKT_LEN_SIZE_TYPE sizeof(u32) + +/* 4 bytes to hold packet length and ICVE_MAX_PACKET_SIZE to hold packet */ +#define ICVE_BUFFER_SIZE (ICVE_MAX_PACKET_SIZE + PKT_LEN_SIZE_TYPE) + +#define RX_POLL_TIMEOUT 250 + +#define icve_ndev_to_priv(ndev) \ + ((struct icve_ndev_priv *)netdev_priv(ndev)) +#define icve_ndev_to_port(ndev) (icve_ndev_to_priv(ndev)->port) +#define icve_ndev_to_common(ndev) (icve_ndev_to_port(ndev)->common) + +static void icve_rx_timer(struct timer_list *timer) +{ + struct icve_port *port = from_timer(port, timer, rx_timer); + struct napi_struct *napi; + int num_pkts = 0; + u32 head, tail; + + head = port->rx_buffer->head; + tail = port->rx_buffer->tail; + + num_pkts = tail - head; + num_pkts = num_pkts >= 0 ? num_pkts : (num_pkts + port->icve_max_buffers); + + napi = &port->rx_napi; + if (num_pkts && likely(napi_schedule_prep(napi))) { + __napi_schedule(napi); + } else { + mod_timer(&port->rx_timer, RX_POLL_TIMEOUT); + } +} + 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); @@ -57,6 +101,18 @@ static int icve_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, void * break; } break; + case ICVE_NOTIFY_MSG: + rpmsg_type = msg->notify_msg.type; + switch (rpmsg_type) { + case ICVE_NOTIFY_REMOTE_READY: + /* Turn on carrier once remote core signals ready */ + netif_carrier_on(port->ndev); + break; + case ICVE_NOTIFY_PORT_UP: + case ICVE_NOTIFY_PORT_DOWN: + break; + } + break; default: dev_err(common->dev, "Invalid msg type\n"); break; @@ -77,6 +133,10 @@ static int create_request(struct icve_common *common, enum icve_rpmsg_type rpmsg case ICVE_REQ_SHM_INFO: msg->msg_hdr.msg_type = ICVE_REQUEST_MSG; break; + case ICVE_NOTIFY_PORT_UP: + case ICVE_NOTIFY_PORT_DOWN: + msg->msg_hdr.msg_type = ICVE_NOTIFY_MSG; + break; default: ret = -EINVAL; dev_err(common->dev, "Invalid RPMSG request\n"); @@ -85,11 +145,262 @@ static int create_request(struct icve_common *common, enum icve_rpmsg_type rpmsg return ret; } +static int icve_rx_packets(struct napi_struct *napi, int budget) +{ + struct icve_port *port = container_of(napi, struct icve_port, rx_napi); + u32 count, process_pkts; + struct sk_buff *skb; + u32 head, tail; + u32 pkt_len; + int num_pkts; + + head = port->rx_buffer->head; + tail = port->rx_buffer->tail; + + num_pkts = tail - head; + num_pkts = num_pkts >= 0 ? num_pkts : (num_pkts + port->icve_max_buffers); + process_pkts = min(num_pkts, budget); + count = 0; + while (count < process_pkts) { + memcpy((void *)&pkt_len, + (void *)port->rx_buffer->base_addr + ((head + count) * ICVE_BUFFER_SIZE), + PKT_LEN_SIZE_TYPE); + + /* Start building the skb */ + skb = napi_alloc_skb(napi, pkt_len); + skb->dev = port->ndev; + skb_put(skb, pkt_len); + + memcpy((void *)skb->data, + (void *)(port->rx_buffer->base_addr + PKT_LEN_SIZE_TYPE) + ((head + count) * ICVE_BUFFER_SIZE), + pkt_len); + + skb->protocol = eth_type_trans(skb, port->ndev); + + /* Push skb into network stack */ + napi_gro_receive(napi, skb); + + count++; + } + + if (num_pkts) { + port->rx_buffer->head = (port->rx_buffer->head + count) % port->icve_max_buffers; + + if (num_pkts < budget && napi_complete_done(napi, count)) + mod_timer(&port->rx_timer, RX_POLL_TIMEOUT); + } + return count; +} + +#ifdef TEST_DEBUG +static int test_tx_rx_path(struct sk_buff *skb, struct net_device *ndev) +{ + struct icve_port *port = icve_ndev_to_port(ndev); + u32 *data; + u32 len; + + len = skb_headlen(skb); + + /* Copy length */ + memcpy((void *)port->rx_buffer->base_addr + (port->rx_buffer->tail * ICVE_BUFFER_SIZE), + (void *)&len, PKT_LEN_SIZE_TYPE); + + /* Copy data to shared mem */ + memcpy((void *)(port->rx_buffer->base_addr + PKT_LEN_SIZE_TYPE) + (port->rx_buffer->tail * ICVE_BUFFER_SIZE), + (void *)skb->data, len); + + data = (u32 *)(port->rx_buffer->base_addr + (port->rx_buffer->tail * ICVE_BUFFER_SIZE)); + + port->rx_buffer->tail = (port->rx_buffer->tail + 1) % ICVE_MAX_BUFFERS; + + return 0; +} +#endif + +static int icve_ndo_open(struct net_device *ndev) +{ + struct icve_common *common = icve_ndev_to_common(ndev); + struct icve_port *port = icve_ndev_to_port(ndev); + unsigned long flags; + + /* Send a msg to remote core signalling that we are ready */ + spin_lock_irqsave(&common->send_msg_lock, flags); +#ifndef TEST_DEBUG + create_request(common, ICVE_NOTIFY_PORT_UP); + rpmsg_send(common->rpdev->ept, (void *)(&common->send_msg), sizeof(common->send_msg)); +#endif + spin_unlock_irqrestore(&common->send_msg_lock, flags); + + if (!(port->tx_buffer && port->rx_buffer)) { + netdev_err(ndev, "Shared memory not setup\n"); + return -EPERM; + } + + netif_napi_add(ndev, &port->rx_napi, icve_rx_packets); + napi_enable(&port->rx_napi); + + timer_setup(&port->rx_timer, icve_rx_timer, 0); + mod_timer(&port->rx_timer, RX_POLL_TIMEOUT); + + return 0; +} + +static int icve_ndo_stop(struct net_device *ndev) +{ + struct icve_common *common = icve_ndev_to_common(ndev); + unsigned long flags; + + spin_lock_irqsave(&common->send_msg_lock, flags); +#ifndef TEST_DEBUG + create_request(common, ICVE_NOTIFY_PORT_DOWN); + rpmsg_send(common->rpdev->ept, (void *)(&common->send_msg), sizeof(common->send_msg)); +#endif + spin_unlock_irqrestore(&common->send_msg_lock, flags); + return 0; +} + +static netdev_tx_t icve_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct icve_port *port = icve_ndev_to_port(ndev); + struct ethhdr *ether; + u32 head, tail; + u32 num_pkts; + u32 len; + + ether = eth_hdr(skb); + len = skb_headlen(skb); + + head = port->tx_buffer->head; + tail = port->tx_buffer->tail; + + /* If the buffer queue is full, then drop packet */ + num_pkts = tail - head; + num_pkts = num_pkts >= 0 ? num_pkts : (num_pkts + port->icve_max_buffers); + if ((num_pkts + 1) == port->icve_max_buffers) { + netdev_warn(ndev, "Tx buffer full\n"); + goto ring_full; + } + + /* Copy length */ + memcpy((void *)port->tx_buffer->base_addr + (port->tx_buffer->tail * ICVE_BUFFER_SIZE), + (void *)&len, PKT_LEN_SIZE_TYPE); + + /* Copy data to shared mem */ + memcpy((void *)(port->tx_buffer->base_addr + PKT_LEN_SIZE_TYPE) + + (port->tx_buffer->tail * ICVE_BUFFER_SIZE), + (void *)skb->data, len); + +#ifdef TEST_DEBUG + /* For quick Rx path testing, inject Tx pkt back into network */ + test_tx_rx_path(skb, ndev); +#endif + port->tx_buffer->tail = (port->tx_buffer->tail + 1) % port->icve_max_buffers; + + dev_consume_skb_any(skb); + + return NETDEV_TX_OK; + +ring_full: + return NETDEV_TX_BUSY; +} + +static int icve_set_mac_address(struct net_device *ndev, void *addr) +{ + eth_mac_addr(ndev, addr); + + /* TODO : Inform remote core about MAC address change */ + return 0; +} + +static const struct net_device_ops icve_netdev_ops = { + .ndo_open = icve_ndo_open, + .ndo_stop = icve_ndo_stop, + .ndo_start_xmit = icve_start_xmit, + .ndo_set_mac_address = icve_set_mac_address, +}; + +static int icve_init_ndev(struct icve_common *common) +{ + struct device *dev = &common->rpdev->dev; + struct icve_ndev_priv *ndev_priv; + struct icve_port *port; + static u32 port_id; + int err; + + port = common->port; + port->common = common; + port->port_id = port_id++; + + port->ndev = devm_alloc_etherdev_mqs(common->dev, sizeof(*ndev_priv), + ICVE_MAX_TX_QUEUES, + ICVE_MAX_RX_QUEUES); + + if (!port->ndev) { + dev_err(dev, "error allocating net_device\n"); + return -ENOMEM; + } + + ndev_priv = netdev_priv(port->ndev); + ndev_priv->port = port; + SET_NETDEV_DEV(port->ndev, dev); + + port->ndev->min_mtu = ICVE_MIN_PACKET_SIZE; + port->ndev->max_mtu = ICVE_MAX_PACKET_SIZE; + port->ndev->netdev_ops = &icve_netdev_ops; + +#ifdef TEST_DEBUG + /* Allocate memory to test without actual RPMsg handshaking */ + port->tx_buffer = devm_kzalloc(dev, sizeof(port->tx_buffer), + GFP_KERNEL); + if (!port->tx_buffer) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + } + + port->tx_buffer->base_addr = devm_kzalloc(dev, ICVE_BUFFER_SIZE * ICVE_MAX_BUFFERS, + GFP_KERNEL); + if (!port->tx_buffer->base_addr) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + } + + port->rx_buffer = devm_kzalloc(dev, sizeof(port->rx_buffer), + GFP_KERNEL); + if (!port->rx_buffer) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + }; + + port->rx_buffer->base_addr = devm_kzalloc(dev, ICVE_BUFFER_SIZE * ICVE_MAX_BUFFERS, + GFP_KERNEL); + if (!port->rx_buffer->base_addr) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + } + + port->icve_max_buffers = ICVE_MAX_BUFFERS; +#else + /* Shared memory details will be sent by the remote core. + * So turn off the carrier, until both the virtual port and + * remote core is ready + */ + netif_carrier_off(port->ndev); + +#endif + err = register_netdev(port->ndev); + + if (err) + dev_err(dev, "error registering icve net device %d\n", err); + + return 0; +} + static int icve_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *dev = &rpdev->dev; struct icve_common *common; unsigned long flags; + int ret; common = devm_kzalloc(&rpdev->dev, sizeof(*common), GFP_KERNEL); if (!common) @@ -104,6 +415,11 @@ static int icve_rpmsg_probe(struct rpmsg_device *rpdev) spin_lock_init(&common->send_msg_lock); spin_lock_init(&common->recv_msg_lock); + /* Register the network device */ + ret = icve_init_ndev(common); + if (ret) + return ret; + /* 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); diff --git a/drivers/net/ethernet/ti/inter-core-virt-eth.h b/drivers/net/ethernet/ti/inter-core-virt-eth.h index 063cc371eeb3..c3386a5ff714 100644 --- a/drivers/net/ethernet/ti/inter-core-virt-eth.h +++ b/drivers/net/ethernet/ti/inter-core-virt-eth.h @@ -7,13 +7,16 @@ #ifndef __INTER_CORE_VIRT_ETH_H__ #define __INTER_CORE_VIRT_ETH_H__ +#include #include #include +#include #include enum icve_msg_type { ICVE_REQUEST_MSG = 0, ICVE_RESPONSE_MSG, + ICVE_NOTIFY_MSG, }; enum icve_rpmsg_type { @@ -22,6 +25,11 @@ enum icve_rpmsg_type { /* Response types */ ICVE_RESP_SHM_INFO, + + /* Notification types */ + ICVE_NOTIFY_PORT_UP, + ICVE_NOTIFY_PORT_DOWN, + ICVE_NOTIFY_REMOTE_READY, }; struct icve_shm_info { @@ -70,7 +78,11 @@ struct shared_mem { 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 timer_list rx_timer; struct icve_common *common; + struct napi_struct rx_napi; + u8 local_mac_addr[ETH_ALEN]; + struct net_device *ndev; u32 icve_max_buffers; u32 port_id; /* Unique ID for the port : TODO: Define range for use by Linux and non linux */ @@ -86,4 +98,8 @@ struct icve_common { struct device *dev; } __packed; +struct icve_ndev_priv { + struct icve_port *port; +}; + #endif /* __INTER_CORE_VIRT_ETH_H__ */