From nobody Fri Feb 13 06:08:01 2026 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 C71F87FBCF; Fri, 31 May 2024 06:40:35 +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=1717137637; cv=none; b=Q7z3EspruO3EKN9N2QPFnkT4i0MtUE18qqp+wKcNKdr/wkDP9262Gbe5mUMsZJzAdiJQ1wGXCNZ6pTlZH/PBNBm7bTeMjWDMeX73YNZoorK5UAN3Wl8C6wvGIzkJbBf6JyUFtPPAW56I32CuGd2GqvVYPvkXvczXdyNlyFX6NZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717137637; c=relaxed/simple; bh=DXzjNM5rd7AToLRZQUV105ZOZYuh0YhBAkgkhkvc5XE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JfX7p2xPqxNomgmdwQBoKJuClsxBkYdSLkHpjsBv/1GPgI7PXrUVf+9Me1q/E0l+OMP5UnCAChDeH5h/cGwNrZgp/7zLUCLarkT8VsC69U+/V4RYdMsz0ty35wbn+fDoTy+mFrxvZAur1Bb/A7oCq1iCOf67+7M/sSmgA2sor58= 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=nx4x3fFg; 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="nx4x3fFg" Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eBtk014178; Fri, 31 May 2024 01:40:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1717137611; bh=hGu2VXsFQDrK+BQT5GD5iaSQUyDm83ze2KDc3Oe6xCA=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=nx4x3fFgDHo01TIjbp4EK10yeXXpHe8ZKihzIOqaHCccFns99GXnnJAiUb5humDr1 f1bt4c1E22bglSew9XMjaZ8LsYYGMU32R0UdHP8fpvGWd6VtufR+pSgjgg/ABBppkU 2aOAWi/YfC8kFRzB1a6CG0nBG2RIyhAmms9/w9Dc= Received: from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 44V6eBTX007622 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 31 May 2024 01:40:11 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 31 May 2024 01:40:10 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE100.ent.ti.com (157.170.170.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; Fri, 31 May 2024 01:40:10 -0500 Received: from fllv0122.itg.ti.com (fllv0122.itg.ti.com [10.247.120.72]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eAF5086051; Fri, 31 May 2024 01:40:10 -0500 Received: from localhost (linux-team-01.dhcp.ti.com [172.24.227.57]) by fllv0122.itg.ti.com (8.14.7/8.14.7) with ESMTP id 44V6e901010385; Fri, 31 May 2024 01:40:10 -0500 From: Yojana Mallik To: , , , , , , , , , , , , CC: , , , Subject: [PATCH net-next v2 1/3] net: ethernet: ti: RPMsg based shared memory ethernet driver Date: Fri, 31 May 2024 12:10:04 +0530 Message-ID: <20240531064006.1223417-2-y-mallik@ti.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240531064006.1223417-1-y-mallik@ti.com> References: <20240531064006.1223417-1-y-mallik@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Content-Type: text/plain; charset="utf-8" From: Ravi Gunasekaran 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: Ravi Gunasekaran Signed-off-by: Yojana Mallik --- drivers/net/ethernet/ti/Kconfig | 9 +++ drivers/net/ethernet/ti/Makefile | 1 + drivers/net/ethernet/ti/icve_rpmsg_common.h | 47 +++++++++++ drivers/net/ethernet/ti/inter_core_virt_eth.c | 81 +++++++++++++++++++ drivers/net/ethernet/ti/inter_core_virt_eth.h | 27 +++++++ 5 files changed, 165 insertions(+) create mode 100644 drivers/net/ethernet/ti/icve_rpmsg_common.h 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/Kconfig b/drivers/net/ethernet/ti/Kcon= fig index 1729eb0e0b41..4f00cb8fe9f1 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -145,6 +145,15 @@ config TI_AM65_CPSW_QOS The EST scheduler runs on CPTS and the TAS/EST schedule is updated in the Fetch RAM memory of the CPSW. =20 +config TI_K3_INTERCORE_VIRT_ETH + tristate "TI K3 Intercore Virtual Ethernet driver" + help + This driver provides intercore virtual ethernet driver + capability.Intercore Virtual Ethernet driver is modelled as + a RPMsg based shared memory ethernet driver for network traffic + tunnelling between heterogeneous processors Cortex A and Cortex R + used in TI's K3 SoCs. + config TI_KEYSTONE_NETCP tristate "TI Keystone NETCP Core Support" select TI_DAVINCI_MDIO diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Mak= efile index 6e086b4c0384..24b14ca73407 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile @@ -49,3 +49,4 @@ icssg-prueth-sr1-y :=3D icssg/icssg_prueth_sr1.o \ icssg/icssg_stats.o \ icssg/icssg_ethtool.o obj-$(CONFIG_TI_ICSS_IEP) +=3D icssg/icss_iep.o +obj-$(CONFIG_TI_K3_INTERCORE_VIRT_ETH) +=3D inter_core_virt_eth.o diff --git a/drivers/net/ethernet/ti/icve_rpmsg_common.h b/drivers/net/ethe= rnet/ti/icve_rpmsg_common.h new file mode 100644 index 000000000000..7cd157479d4d --- /dev/null +++ b/drivers/net/ethernet/ti/icve_rpmsg_common.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 + * Texas Instruments K3 Inter Core Virtual Ethernet Driver common header + * + * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/ + */ + +#ifndef __ICVE_RPMSG_COMMON_H__ +#define __ICVE_RPMSG_COMMON_H__ + +#include + +enum icve_msg_type { + ICVE_REQUEST_MSG =3D 0, + ICVE_RESPONSE_MSG, + ICVE_NOTIFY_MSG, +}; + +struct request_message { + u32 type; /* Request Type */ + u32 id; /* Request ID */ +} __packed; + +struct response_message { + u32 type; /* Response Type */ + u32 id; /* Response ID */ +} __packed; + +struct notify_message { + u32 type; /* Notify Type */ + u32 id; /* Notify ID */ +} __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; + +#endif /* __ICVE_RPMSG_COMMON_H__ */ diff --git a/drivers/net/ethernet/ti/inter_core_virt_eth.c b/drivers/net/et= hernet/ti/inter_core_virt_eth.c new file mode 100644 index 000000000000..bea822d2373a --- /dev/null +++ b/drivers/net/ethernet/ti/inter_core_virt_eth.c @@ -0,0 +1,81 @@ +// 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 =3D dev_get_drvdata(&rpdev->dev); + struct message *msg =3D (struct message *)data; + u32 msg_type =3D msg->msg_hdr.msg_type; + u32 rpmsg_type; + + switch (msg_type) { + case ICVE_REQUEST_MSG: + rpmsg_type =3D msg->req_msg.type; + dev_dbg(common->dev, "Msg type =3D %d; RPMsg type =3D %d\n", + msg_type, rpmsg_type); + break; + case ICVE_RESPONSE_MSG: + rpmsg_type =3D msg->resp_msg.type; + dev_dbg(common->dev, "Msg type =3D %d; RPMsg type =3D %d\n", + msg_type, rpmsg_type); + break; + case ICVE_NOTIFY_MSG: + rpmsg_type =3D msg->notify_msg.type; + dev_dbg(common->dev, "Msg type =3D %d; RPMsg type =3D %d\n", + msg_type, rpmsg_type); + break; + default: + dev_err(common->dev, "Invalid msg type\n"); + break; + } + return 0; +} + +static int icve_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct device *dev =3D &rpdev->dev; + struct icve_common *common; + + common =3D devm_kzalloc(&rpdev->dev, sizeof(*common), GFP_KERNEL); + if (!common) + return -ENOMEM; + + dev_set_drvdata(dev, common); + + common->port =3D devm_kzalloc(dev, sizeof(*common->port), GFP_KERNEL); + common->dev =3D dev; + common->rpdev =3D rpdev; + + 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[] =3D { + { .name =3D "ti.icve" }, + {}, +}; +MODULE_DEVICE_TABLE(rpmsg, icve_rpmsg_id_table); + +static struct rpmsg_driver icve_rpmsg_client =3D { + .drv.name =3D KBUILD_MODNAME, + .id_table =3D icve_rpmsg_id_table, + .probe =3D icve_rpmsg_probe, + .callback =3D icve_rpmsg_cb, + .remove =3D icve_rpmsg_remove, +}; +module_rpmsg_driver(icve_rpmsg_client); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Siddharth Vadapalli "); +MODULE_AUTHOR("Ravi Gunasekaran +#include +#include +#include +#include +#include "icve_rpmsg_common.h" + +struct icve_port { + struct icve_common *common; +} __packed; + +struct icve_common { + struct rpmsg_device *rpdev; + struct icve_port *port; + struct device *dev; +} __packed; + +#endif /* __INTER_CORE_VIRT_ETH_H__ */ --=20 2.40.1 From nobody Fri Feb 13 06:08:01 2026 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 68E727FBDA; Fri, 31 May 2024 06:40:36 +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=1717137638; cv=none; b=AqCa8uZYmRemA+OJqrQKKKSl1E2uoifdWqB14LXdWN6VmnNkvomnTGoN/E71CcECiooX9ELmc766ejbT4rLFK3rfC956B36SaEQuWfq+nSDJrq8aHAmgsc1YOO3OCijh0sSjuVKt8JIC2UzuoZVUuAoat0C1vyN1HHrocd/0b+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717137638; c=relaxed/simple; bh=h+TmwJdb0au4o4PcmhmUMCB7xgKtC9q9x+NtgL8BqPg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Kh6sMzTqJ95ab7bfc7Fwptibp4N49dDuGu62uoANHM1c6RC3BzLhfPvK0SK+DN2QOuTHaXt30EJAJtYUevFq6nb4Kjb3aPqwhT/VrbgAqjcJm5VUB6zAekUnBUESuhTW6KKKr3FD22Ghd97Ux7LzHu5GZGUDc7KvNJCzxOkt7+4= 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=oGf30QZf; 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="oGf30QZf" Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eCFg014191; Fri, 31 May 2024 01:40:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1717137612; bh=9BTR6DzLiXvh2kynrdXzcD7GtcON45T7V8zeKgdBDUw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=oGf30QZfoE/jc+1sIBvb9OYmiD2Gp3Hz/R5XjeD5sa2p7P58ggO2zNVleVTG9bW4T yFvQpWhe0JMpWXFSirmStVIItjJiGiGiG7+lv1pX6jYUo3BexdO8xLN8nBqeev2Jj2 ROtIqa3Sd1SeopiSX02jHzYE+XiuX37gvDsBEess= Received: from DFLE106.ent.ti.com (dfle106.ent.ti.com [10.64.6.27]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 44V6eCt8065464 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 31 May 2024 01:40:12 -0500 Received: from DFLE105.ent.ti.com (10.64.6.26) 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; Fri, 31 May 2024 01:40:12 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) 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; Fri, 31 May 2024 01:40:12 -0500 Received: from fllv0122.itg.ti.com (fllv0122.itg.ti.com [10.247.120.72]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eCft086120; Fri, 31 May 2024 01:40:12 -0500 Received: from localhost (linux-team-01.dhcp.ti.com [172.24.227.57]) by fllv0122.itg.ti.com (8.14.7/8.14.7) with ESMTP id 44V6eB0U010391; Fri, 31 May 2024 01:40:12 -0500 From: Yojana Mallik To: , , , , , , , , , , , , CC: , , , Subject: [PATCH net-next v2 2/3] net: ethernet: ti: Register the RPMsg driver as network device Date: Fri, 31 May 2024 12:10:05 +0530 Message-ID: <20240531064006.1223417-3-y-mallik@ti.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240531064006.1223417-1-y-mallik@ti.com> References: <20240531064006.1223417-1-y-mallik@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Content-Type: text/plain; charset="utf-8" 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: Yojana Mallik --- drivers/net/ethernet/ti/icve_rpmsg_common.h | 86 ++++ drivers/net/ethernet/ti/inter_core_virt_eth.c | 453 +++++++++++++++++- drivers/net/ethernet/ti/inter_core_virt_eth.h | 35 +- 3 files changed, 570 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/ti/icve_rpmsg_common.h b/drivers/net/ethe= rnet/ti/icve_rpmsg_common.h index 7cd157479d4d..2e3833de14bd 100644 --- a/drivers/net/ethernet/ti/icve_rpmsg_common.h +++ b/drivers/net/ethernet/ti/icve_rpmsg_common.h @@ -15,14 +15,58 @@ enum icve_msg_type { ICVE_NOTIFY_MSG, }; =20 +enum icve_rpmsg_type { + /* Request types */ + ICVE_REQ_SHM_INFO =3D 0, + ICVE_REQ_SET_MAC_ADDR, + + /* Response types */ + ICVE_RESP_SHM_INFO, + ICVE_RESP_SET_MAC_ADDR, + + /* Notification types */ + ICVE_NOTIFY_PORT_UP, + ICVE_NOTIFY_PORT_DOWN, + ICVE_NOTIFY_PORT_READY, + ICVE_NOTIFY_REMOTE_READY, +}; + +struct icve_shm_info { + /* Total shared memory size */ + u32 total_shm_size; + /* Total number of buffers */ + u32 num_pkt_bufs; + /* Per buff slot size i.e MTU Size + 4 bytes for magic number + 4 bytes + * for Pkt len + */ + u32 buff_slot_size; + /* Base Address for Tx or Rx shared memory */ + u32 base_addr; +} __packed; + +struct icve_shm { + struct icve_shm_info shm_info_tx; + struct icve_shm_info shm_info_rx; +} __packed; + +struct icve_mac_addr { + char addr[ETH_ALEN]; +} __packed; + struct request_message { u32 type; /* Request Type */ u32 id; /* Request ID */ + union { + struct icve_mac_addr mac_addr; + }; } __packed; =20 struct response_message { u32 type; /* Response Type */ u32 id; /* Response ID */ + union { + struct icve_shm shm_info; + }; } __packed; =20 struct notify_message { @@ -44,4 +88,46 @@ struct message { }; } __packed; =20 +/* Shared Memory Layout + * + * --------------------------- ***************** + * | MAGIC_NUM | icve_shm_head + * | HEAD | + * --------------------------- ***************** + * | MAGIC_NUM | + * | PKT_1_LEN | + * | PKT_1 | + * --------------------------- + * | MAGIC_NUM | + * | PKT_2_LEN | icve_shm_buf + * | PKT_2 | + * --------------------------- + * | . | + * | . | + * --------------------------- + * | MAGIC_NUM | + * | PKT_N_LEN | + * | PKT_N | + * --------------------------- **************** + * | MAGIC_NUM | icve_shm_tail + * | TAIL | + * --------------------------- **************** + */ + +struct icve_shm_index { + u32 magic_num; + u32 index; +} __packed; + +struct icve_shm_buf { + char __iomem *base_addr; /* start addr of first buffer */ + u32 magic_num; +} __packed; + +struct icve_shared_mem { + struct icve_shm_index __iomem *head; + struct icve_shm_buf __iomem *buf; + struct icve_shm_index __iomem *tail; +} __packed; + #endif /* __ICVE_RPMSG_COMMON_H__ */ diff --git a/drivers/net/ethernet/ti/inter_core_virt_eth.c b/drivers/net/et= hernet/ti/inter_core_virt_eth.c index bea822d2373a..d96547d317fe 100644 --- a/drivers/net/ethernet/ti/inter_core_virt_eth.c +++ b/drivers/net/ethernet/ti/inter_core_virt_eth.c @@ -6,11 +6,145 @@ =20 #include "inter_core_virt_eth.h" =20 +#define ICVE_MIN_PACKET_SIZE ETH_ZLEN +#define ICVE_MAX_PACKET_SIZE 1540 //(ETH_FRAME_LEN + ETH_FCS_LEN) +#define ICVE_MAX_TX_QUEUES 1 +#define ICVE_MAX_RX_QUEUES 1 + +#define PKT_LEN_SIZE_TYPE sizeof(u32) +#define MAGIC_NUM_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 + MAGIC_NUM_SIZE_TYPE) + +#define RX_POLL_TIMEOUT 1000 /* 1000usec */ +#define RX_POLL_JIFFIES (jiffies + usecs_to_jiffies(RX_POLL_TIMEOUT)) + +#define STATE_MACHINE_TIME msecs_to_jiffies(100) +#define ICVE_REQ_TIMEOUT msecs_to_jiffies(100) + +#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 int create_request(struct icve_common *common, + enum icve_rpmsg_type rpmsg_type) +{ + struct message *msg =3D &common->send_msg; + int ret =3D 0; + + msg->msg_hdr.src_id =3D common->port->port_id; + msg->req_msg.type =3D rpmsg_type; + + switch (rpmsg_type) { + case ICVE_REQ_SHM_INFO: + msg->msg_hdr.msg_type =3D ICVE_REQUEST_MSG; + break; + case ICVE_REQ_SET_MAC_ADDR: + msg->msg_hdr.msg_type =3D ICVE_REQUEST_MSG; + ether_addr_copy(msg->req_msg.mac_addr.addr, + common->port->ndev->dev_addr); + break; + case ICVE_NOTIFY_PORT_UP: + case ICVE_NOTIFY_PORT_DOWN: + msg->msg_hdr.msg_type =3D ICVE_NOTIFY_MSG; + break; + default: + ret =3D -EINVAL; + dev_err(common->dev, "Invalid RPMSG request\n"); + }; + return ret; +} + +static int icve_create_send_request(struct icve_common *common, + enum icve_rpmsg_type rpmsg_type, + bool wait) +{ + unsigned long flags; + int ret; + + if (wait) + reinit_completion(&common->sync_msg); + + spin_lock_irqsave(&common->send_msg_lock, flags); + create_request(common, rpmsg_type); + rpmsg_send(common->rpdev->ept, (void *)(&common->send_msg), + sizeof(common->send_msg)); + spin_unlock_irqrestore(&common->send_msg_lock, flags); + + if (wait) { + ret =3D wait_for_completion_timeout(&common->sync_msg, + ICVE_REQ_TIMEOUT); + + if (!ret) { + dev_err(common->dev, "Failed to receive response within %ld jiffies\n", + ICVE_REQ_TIMEOUT); + ret =3D -ETIMEDOUT; + return ret; + } + } + return ret; +} + +static void icve_state_machine(struct work_struct *work) +{ + struct delayed_work *dwork =3D to_delayed_work(work); + struct icve_common *common; + struct icve_port *port; + + common =3D container_of(dwork, struct icve_common, state_work); + port =3D common->port; + + mutex_lock(&common->state_lock); + + switch (common->state) { + case ICVE_STATE_PROBE: + break; + case ICVE_STATE_OPEN: + icve_create_send_request(common, ICVE_REQ_SHM_INFO, false); + break; + case ICVE_STATE_CLOSE: + break; + case ICVE_STATE_READY: + icve_create_send_request(common, ICVE_REQ_SET_MAC_ADDR, false); + napi_enable(&port->rx_napi); + netif_carrier_on(port->ndev); + mod_timer(&port->rx_timer, RX_POLL_TIMEOUT); + break; + case ICVE_STATE_RUNNING: + break; + } + mutex_unlock(&common->state_lock); +} + +static void icve_rx_timer(struct timer_list *timer) +{ + struct icve_port *port =3D from_timer(port, timer, rx_timer); + struct napi_struct *napi; + int num_pkts =3D 0; + u32 head, tail; + + head =3D port->rx_buffer->head->index; + tail =3D port->rx_buffer->tail->index; + + num_pkts =3D tail - head; + num_pkts =3D num_pkts >=3D 0 ? num_pkts : + (num_pkts + port->icve_rx_max_buffers); + + napi =3D &port->rx_napi; + if (num_pkts && likely(napi_schedule_prep(napi))) + __napi_schedule(napi); + else + mod_timer(&port->rx_timer, RX_POLL_JIFFIES); +} + static int icve_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 src) { struct icve_common *common =3D dev_get_drvdata(&rpdev->dev); struct message *msg =3D (struct message *)data; + struct icve_port *port =3D common->port; u32 msg_type =3D msg->msg_hdr.msg_type; u32 rpmsg_type; =20 @@ -24,11 +158,79 @@ static int icve_rpmsg_cb(struct rpmsg_device *rpdev, v= oid *data, int len, rpmsg_type =3D msg->resp_msg.type; dev_dbg(common->dev, "Msg type =3D %d; RPMsg type =3D %d\n", msg_type, rpmsg_type); + switch (rpmsg_type) { + case ICVE_RESP_SHM_INFO: + /* Retrieve Tx and Rx shared memory info from msg */ + port->tx_buffer->head =3D + ioremap(msg->resp_msg.shm_info.shm_info_tx.base_addr, + sizeof(*port->tx_buffer->head)); + + port->tx_buffer->buf->base_addr =3D + ioremap((msg->resp_msg.shm_info.shm_info_tx.base_addr + + sizeof(*port->tx_buffer->head)), + (msg->resp_msg.shm_info.shm_info_tx.num_pkt_bufs * + msg->resp_msg.shm_info.shm_info_tx.buff_slot_size)); + + port->tx_buffer->tail =3D + ioremap(msg->resp_msg.shm_info.shm_info_tx.base_addr + + sizeof(*port->tx_buffer->head) + + (msg->resp_msg.shm_info.shm_info_tx.num_pkt_bufs * + msg->resp_msg.shm_info.shm_info_tx.buff_slot_size), + sizeof(*port->tx_buffer->tail)); + + port->icve_tx_max_buffers =3D msg->resp_msg.shm_info.shm_info_tx.num_pk= t_bufs; + + port->rx_buffer->head =3D + ioremap(msg->resp_msg.shm_info.shm_info_rx.base_addr, + sizeof(*port->rx_buffer->head)); + + port->rx_buffer->buf->base_addr =3D + ioremap(msg->resp_msg.shm_info.shm_info_rx.base_addr + + sizeof(*port->rx_buffer->head), + (msg->resp_msg.shm_info.shm_info_rx.num_pkt_bufs * + msg->resp_msg.shm_info.shm_info_rx.buff_slot_size)); + + port->rx_buffer->tail =3D + ioremap(msg->resp_msg.shm_info.shm_info_rx.base_addr + + sizeof(*port->rx_buffer->head) + + (msg->resp_msg.shm_info.shm_info_rx.num_pkt_bufs * + msg->resp_msg.shm_info.shm_info_rx.buff_slot_size), + sizeof(*port->rx_buffer->tail)); + + port->icve_rx_max_buffers =3D + msg->resp_msg.shm_info.shm_info_rx.num_pkt_bufs; + + mutex_lock(&common->state_lock); + common->state =3D ICVE_STATE_READY; + mutex_unlock(&common->state_lock); + + mod_delayed_work(system_wq, + &common->state_work, + STATE_MACHINE_TIME); + + break; + case ICVE_RESP_SET_MAC_ADDR: + break; + } + break; + case ICVE_NOTIFY_MSG: rpmsg_type =3D msg->notify_msg.type; - dev_dbg(common->dev, "Msg type =3D %d; RPMsg type =3D %d\n", - msg_type, rpmsg_type); + switch (rpmsg_type) { + case ICVE_NOTIFY_REMOTE_READY: + mutex_lock(&common->state_lock); + common->state =3D ICVE_STATE_RUNNING; + mutex_unlock(&common->state_lock); + + mod_delayed_work(system_wq, + &common->state_work, + STATE_MACHINE_TIME); + break; + case ICVE_NOTIFY_PORT_UP: + case ICVE_NOTIFY_PORT_DOWN: + break; + } break; default: dev_err(common->dev, "Invalid msg type\n"); @@ -37,10 +239,242 @@ static int icve_rpmsg_cb(struct rpmsg_device *rpdev, = void *data, int len, return 0; } =20 +static int icve_rx_packets(struct napi_struct *napi, int budget) +{ + struct icve_port *port =3D container_of(napi, struct icve_port, rx_napi); + u32 count, process_pkts; + struct sk_buff *skb; + u32 head, tail; + int num_pkts; + u32 pkt_len; + + head =3D port->rx_buffer->head->index; + tail =3D port->rx_buffer->tail->index; + + num_pkts =3D head - tail; + + num_pkts =3D num_pkts >=3D 0 ? num_pkts : + (num_pkts + port->icve_rx_max_buffers); + process_pkts =3D min(num_pkts, budget); + count =3D 0; + while (count < process_pkts) { + memcpy_fromio((void *)&pkt_len, + (void *)(port->rx_buffer->buf->base_addr + + MAGIC_NUM_SIZE_TYPE + + (((tail + count) % port->icve_rx_max_buffers) * + ICVE_BUFFER_SIZE)), + PKT_LEN_SIZE_TYPE); + /* Start building the skb */ + skb =3D napi_alloc_skb(napi, pkt_len); + if (!skb) { + port->ndev->stats.rx_dropped++; + goto rx_dropped; + } + + skb->dev =3D port->ndev; + skb_put(skb, pkt_len); + memcpy_fromio((void *)skb->data, + (void *)(port->rx_buffer->buf->base_addr + + PKT_LEN_SIZE_TYPE + MAGIC_NUM_SIZE_TYPE + + (((tail + count) % port->icve_rx_max_buffers) * + ICVE_BUFFER_SIZE)), + pkt_len); + + skb->protocol =3D eth_type_trans(skb, port->ndev); + + /* Push skb into network stack */ + napi_gro_receive(napi, skb); + + count++; + port->ndev->stats.rx_packets++; + port->ndev->stats.rx_bytes +=3D skb->len; + } + +rx_dropped: + + if (num_pkts) { + port->rx_buffer->tail->index =3D + (port->rx_buffer->tail->index + count) % + port->icve_rx_max_buffers; + + if (num_pkts < budget && napi_complete_done(napi, count)) + mod_timer(&port->rx_timer, RX_POLL_TIMEOUT); + } + + return count; +} + +static int icve_ndo_open(struct net_device *ndev) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + + mutex_lock(&common->state_lock); + common->state =3D ICVE_STATE_OPEN; + mutex_unlock(&common->state_lock); + mod_delayed_work(system_wq, &common->state_work, msecs_to_jiffies(100)); + + return 0; +} + +static int icve_ndo_stop(struct net_device *ndev) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + struct icve_port *port =3D icve_ndev_to_port(ndev); + + mutex_lock(&common->state_lock); + common->state =3D ICVE_STATE_CLOSE; + mutex_unlock(&common->state_lock); + + netif_carrier_off(port->ndev); + + __dev_mc_unsync(ndev, icve_del_mc_addr); + __hw_addr_init(&common->mc_list); + + cancel_delayed_work_sync(&common->state_work); + del_timer_sync(&port->rx_timer); + napi_disable(&port->rx_napi); + + cancel_work_sync(&common->rx_mode_work); + + return 0; +} + +static netdev_tx_t icve_start_xmit(struct sk_buff *skb, struct net_device = *ndev) +{ + struct icve_port *port =3D icve_ndev_to_port(ndev); + u32 head, tail; + int num_pkts; + u32 len; + + len =3D skb_headlen(skb); + head =3D port->tx_buffer->head->index; + tail =3D port->tx_buffer->tail->index; + + /* If the buffer queue is full, then drop packet */ + num_pkts =3D head - tail; + num_pkts =3D num_pkts >=3D 0 ? num_pkts : + (num_pkts + port->icve_tx_max_buffers); + + if ((num_pkts + 1) =3D=3D port->icve_tx_max_buffers) { + netdev_warn(ndev, "Tx buffer full %d\n", num_pkts); + goto ring_full; + } + /* Copy length */ + memcpy_toio((void *)port->tx_buffer->buf->base_addr + + MAGIC_NUM_SIZE_TYPE + + (port->tx_buffer->head->index * ICVE_BUFFER_SIZE), + (void *)&len, PKT_LEN_SIZE_TYPE); + /* Copy data to shared mem */ + memcpy_toio((void *)(port->tx_buffer->buf->base_addr + + MAGIC_NUM_SIZE_TYPE + PKT_LEN_SIZE_TYPE + + (port->tx_buffer->head->index * ICVE_BUFFER_SIZE)), + (void *)skb->data, len); + port->tx_buffer->head->index =3D + (port->tx_buffer->head->index + 1) % port->icve_tx_max_buffers; + + ndev->stats.tx_packets++; + ndev->stats.tx_bytes +=3D skb->len; + + 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) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + int ret; + + ret =3D eth_mac_addr(ndev, addr); + + if (ret < 0) + return ret; + icve_create_send_request(common, ICVE_REQ_SET_MAC_ADDR, false); + return ret; +} + +static const struct net_device_ops icve_netdev_ops =3D { + .ndo_open =3D icve_ndo_open, + .ndo_stop =3D icve_ndo_stop, + .ndo_start_xmit =3D icve_start_xmit, + .ndo_set_mac_address =3D icve_set_mac_address, +}; + +static int icve_init_ndev(struct icve_common *common) +{ + struct device *dev =3D &common->rpdev->dev; + struct icve_ndev_priv *ndev_priv; + struct icve_port *port; + static u32 port_id; + int err; + + port =3D common->port; + port->common =3D common; + port->port_id =3D port_id++; + + port->ndev =3D 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 =3D netdev_priv(port->ndev); + ndev_priv->port =3D port; + SET_NETDEV_DEV(port->ndev, dev); + + port->ndev->min_mtu =3D ICVE_MIN_PACKET_SIZE; + port->ndev->max_mtu =3D ICVE_MAX_PACKET_SIZE; + port->ndev->netdev_ops =3D &icve_netdev_ops; + + /* Allocate memory to test without actual RPMsg handshaking */ + port->tx_buffer =3D + 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->buf =3D + devm_kzalloc(dev, sizeof(*port->tx_buffer->buf), GFP_KERNEL); + if (!port->tx_buffer->buf) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + } + + port->rx_buffer =3D + 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->buf =3D + devm_kzalloc(dev, sizeof(*port->rx_buffer->buf), GFP_KERNEL); + if (!port->rx_buffer->buf) { + dev_err(dev, "Memory not available\n"); + return -ENOMEM; + }; + netif_carrier_off(port->ndev); + + netif_napi_add(port->ndev, &port->rx_napi, icve_rx_packets); + timer_setup(&port->rx_timer, icve_rx_timer, 0); + err =3D 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 =3D &rpdev->dev; struct icve_common *common; + int ret =3D 0; =20 common =3D devm_kzalloc(&rpdev->dev, sizeof(*common), GFP_KERNEL); if (!common) @@ -51,12 +485,27 @@ static int icve_rpmsg_probe(struct rpmsg_device *rpdev) common->port =3D devm_kzalloc(dev, sizeof(*common->port), GFP_KERNEL); common->dev =3D dev; common->rpdev =3D rpdev; + common->state =3D ICVE_STATE_PROBE; + spin_lock_init(&common->send_msg_lock); + spin_lock_init(&common->recv_msg_lock); + mutex_init(&common->state_lock); + INIT_DELAYED_WORK(&common->state_work, icve_state_machine); + init_completion(&common->sync_msg); =20 + /* Register the network device */ + ret =3D icve_init_ndev(common); + if (ret) + return ret; return 0; } =20 static void icve_rpmsg_remove(struct rpmsg_device *rpdev) { + struct icve_common *common =3D dev_get_drvdata(&rpdev->dev); + struct icve_port *port =3D common->port; + + netif_napi_del(&port->rx_napi); + del_timer_sync(&port->rx_timer); dev_info(&rpdev->dev, "icve rpmsg client driver is removed\n"); } =20 diff --git a/drivers/net/ethernet/ti/inter_core_virt_eth.h b/drivers/net/et= hernet/ti/inter_core_virt_eth.h index 91a3aba96996..4fc420cb9eab 100644 --- a/drivers/net/ethernet/ti/inter_core_virt_eth.h +++ b/drivers/net/ethernet/ti/inter_core_virt_eth.h @@ -14,14 +14,45 @@ #include #include "icve_rpmsg_common.h" =20 +enum icve_state { + ICVE_STATE_PROBE, + ICVE_STATE_OPEN, + ICVE_STATE_CLOSE, + ICVE_STATE_READY, + ICVE_STATE_RUNNING, + +}; + struct icve_port { + struct icve_shared_mem *tx_buffer; /* Write buffer for data to be consume= d remote side */ + struct icve_shared_mem *rx_buffer; /* Read buffer for data to be consumed= by this driver */ + struct timer_list rx_timer; struct icve_common *common; -} __packed; + struct napi_struct rx_napi; + u8 local_mac_addr[ETH_ALEN]; + struct net_device *ndev; + u32 icve_tx_max_buffers; + u32 icve_rx_max_buffers; + u32 port_id; +}; =20 struct icve_common { struct rpmsg_device *rpdev; + spinlock_t send_msg_lock; /* Acquire this lock while sending RPMsg */ + spinlock_t recv_msg_lock; /* Acquire this lock while processing received = RPMsg */ + struct message send_msg; + struct message recv_msg; struct icve_port *port; struct device *dev; -} __packed; + enum icve_state state; + struct mutex state_lock; /* Lock to be used while changing the interface = state */ + struct delayed_work state_work; + struct completion sync_msg; +}; + +struct icve_ndev_priv { + struct icve_port *port; +}; + =20 #endif /* __INTER_CORE_VIRT_ETH_H__ */ --=20 2.40.1 From nobody Fri Feb 13 06:08:01 2026 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (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 BA93381AB1; Fri, 31 May 2024 06:40:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717137647; cv=none; b=J/TOmKqeds8+pmAr5t1z5g2IjGPiruDpzeem+cIMkiYrJHf2jB7xjOAQzyy1LCtd+iZ2V69l5uMQQv3Qyj3R3H4EzrvVJO5h5uxI2JOGvUH4ajkljMGT8m0AL0+OA4QJOQE0iNJssRpNFrMCB1dtfdO0xKbp01ZHrP7XCtEpNC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717137647; c=relaxed/simple; bh=BDZ/2pu/Wld29GlvisviBxejydCCeYCwVZ9eZWychX0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HDtdOaBGniJgoeDdu49hdc3CxEj79c4HtY5uL8ngOWJeEnM/xVnBci1izCoy2lbdAXaMWKaOPYAoWsAROiXq3WE2MJqS2+tcYmzQFR5DrSe6Dm25c5Y1/qgJRX7ytoZrLSGeT5/UR8dnFK1f1801xnbC3QHHCx0chVAUR/U/3fk= 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=tT1Cfucn; arc=none smtp.client-ip=198.47.19.142 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="tT1Cfucn" Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eEZR121219; Fri, 31 May 2024 01:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1717137614; bh=VMk29xvgHcoMkTC1JSC7HJ1lS34whDEDzI6Xz/EqtPg=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=tT1Cfucn0nGv8Mj2f7o58udB3wvuIffIYwndujWpq+6OKQCZkiO4aMhawV/kqX7Ub 0+dNOB203GYksjnOgx1Jkg7drOge+l4T8aYe3j5VJ6ormN/p7LOcg+Xnq1mVTgw6pL ZR8eDbdbv6Y5Tf0LnjM4nX84JA8WM1oDWDQVL3Mw= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 44V6eEYZ108428 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 31 May 2024 01:40:14 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 31 May 2024 01:40:14 -0500 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) 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 via Frontend Transport; Fri, 31 May 2024 01:40:14 -0500 Received: from fllv0122.itg.ti.com (fllv0122.itg.ti.com [10.247.120.72]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 44V6eEZN121499; Fri, 31 May 2024 01:40:14 -0500 Received: from localhost (linux-team-01.dhcp.ti.com [172.24.227.57]) by fllv0122.itg.ti.com (8.14.7/8.14.7) with ESMTP id 44V6eDvX010395; Fri, 31 May 2024 01:40:14 -0500 From: Yojana Mallik To: , , , , , , , , , , , , CC: , , , Subject: [PATCH net-next v2 3/3] net: ethernet: ti: icve: Add support for multicast filtering Date: Fri, 31 May 2024 12:10:06 +0530 Message-ID: <20240531064006.1223417-4-y-mallik@ti.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240531064006.1223417-1-y-mallik@ti.com> References: <20240531064006.1223417-1-y-mallik@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Content-Type: text/plain; charset="utf-8" Add support for multicast filtering for ICVE driver. Implement the ndo_set_rx_mode callback as icve_set_rx_mode() API. rx_mode_workqueue is initialized in icve_rpmsg_probe() and queued in icve_set_rx_mode(). Signed-off-by: Yojana Mallik --- drivers/net/ethernet/ti/icve_rpmsg_common.h | 4 ++ drivers/net/ethernet/ti/inter_core_virt_eth.c | 63 ++++++++++++++++++- drivers/net/ethernet/ti/inter_core_virt_eth.h | 4 ++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/icve_rpmsg_common.h b/drivers/net/ethe= rnet/ti/icve_rpmsg_common.h index 2e3833de14bd..793baa93e135 100644 --- a/drivers/net/ethernet/ti/icve_rpmsg_common.h +++ b/drivers/net/ethernet/ti/icve_rpmsg_common.h @@ -19,10 +19,14 @@ enum icve_rpmsg_type { /* Request types */ ICVE_REQ_SHM_INFO =3D 0, ICVE_REQ_SET_MAC_ADDR, + ICVE_REQ_ADD_MC_ADDR, + ICVE_REQ_DEL_MC_ADDR, =20 /* Response types */ ICVE_RESP_SHM_INFO, ICVE_RESP_SET_MAC_ADDR, + ICVE_RESP_ADD_MC_ADDR, + ICVE_RESP_DEL_MC_ADDR, =20 /* Notification types */ ICVE_NOTIFY_PORT_UP, diff --git a/drivers/net/ethernet/ti/inter_core_virt_eth.c b/drivers/net/et= hernet/ti/inter_core_virt_eth.c index d96547d317fe..908425af0014 100644 --- a/drivers/net/ethernet/ti/inter_core_virt_eth.c +++ b/drivers/net/ethernet/ti/inter_core_virt_eth.c @@ -46,6 +46,11 @@ static int create_request(struct icve_common *common, ether_addr_copy(msg->req_msg.mac_addr.addr, common->port->ndev->dev_addr); break; + case ICVE_REQ_ADD_MC_ADDR: + case ICVE_REQ_DEL_MC_ADDR: + ether_addr_copy(msg->req_msg.mac_addr.addr, + common->mcast_addr); + break; case ICVE_NOTIFY_PORT_UP: case ICVE_NOTIFY_PORT_DOWN: msg->msg_hdr.msg_type =3D ICVE_NOTIFY_MSG; @@ -87,6 +92,26 @@ static int icve_create_send_request(struct icve_common *= common, return ret; } =20 +static int icve_add_mc_addr(struct net_device *ndev, const u8 *addr) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + int ret =3D 0; + + ether_addr_copy(common->mcast_addr, addr); + icve_create_send_request(common, ICVE_REQ_ADD_MC_ADDR, true); + return ret; +} + +static int icve_del_mc_addr(struct net_device *ndev, const u8 *addr) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + int ret =3D 0; + + ether_addr_copy(common->mcast_addr, addr); + icve_create_send_request(common, ICVE_REQ_DEL_MC_ADDR, true); + return ret; +} + static void icve_state_machine(struct work_struct *work) { struct delayed_work *dwork =3D to_delayed_work(work); @@ -211,6 +236,10 @@ static int icve_rpmsg_cb(struct rpmsg_device *rpdev, v= oid *data, int len, break; case ICVE_RESP_SET_MAC_ADDR: break; + case ICVE_RESP_ADD_MC_ADDR: + case ICVE_RESP_DEL_MC_ADDR: + complete(&common->sync_msg); + break; } =20 break; @@ -395,10 +424,35 @@ static int icve_set_mac_address(struct net_device *nd= ev, void *addr) return ret; } =20 +static void icve_ndo_set_rx_mode_work(struct work_struct *work) +{ + struct icve_common *common; + struct net_device *ndev; + + common =3D container_of(work, struct icve_common, rx_mode_work); + ndev =3D common->port->ndev; + + /* make a mc list copy */ + netif_addr_lock_bh(ndev); + __hw_addr_sync(&common->mc_list, &ndev->mc, ndev->addr_len); + netif_addr_unlock_bh(ndev); + + __hw_addr_sync_dev(&common->mc_list, ndev, icve_add_mc_addr, + icve_del_mc_addr); +} + +static void icve_set_rx_mode(struct net_device *ndev) +{ + struct icve_common *common =3D icve_ndev_to_common(ndev); + + queue_work(common->cmd_wq, &common->rx_mode_work); +} + static const struct net_device_ops icve_netdev_ops =3D { .ndo_open =3D icve_ndo_open, .ndo_stop =3D icve_ndo_stop, .ndo_start_xmit =3D icve_start_xmit, + .ndo_set_rx_mode =3D icve_set_rx_mode, .ndo_set_mac_address =3D icve_set_mac_address, }; =20 @@ -491,7 +545,13 @@ static int icve_rpmsg_probe(struct rpmsg_device *rpdev) mutex_init(&common->state_lock); INIT_DELAYED_WORK(&common->state_work, icve_state_machine); init_completion(&common->sync_msg); - + __hw_addr_init(&common->mc_list); + INIT_WORK(&common->rx_mode_work, icve_ndo_set_rx_mode_work); + common->cmd_wq =3D create_singlethread_workqueue("icve_rx_work"); + if (!common->cmd_wq) { + dev_err(dev, "Failure requesting workqueue\n"); + return -ENOMEM; + } /* Register the network device */ ret =3D icve_init_ndev(common); if (ret) @@ -506,6 +566,7 @@ static void icve_rpmsg_remove(struct rpmsg_device *rpde= v) =20 netif_napi_del(&port->rx_napi); del_timer_sync(&port->rx_timer); + destroy_workqueue(common->cmd_wq); dev_info(&rpdev->dev, "icve rpmsg client driver is removed\n"); } =20 diff --git a/drivers/net/ethernet/ti/inter_core_virt_eth.h b/drivers/net/et= hernet/ti/inter_core_virt_eth.h index 4fc420cb9eab..02c4d23395f5 100644 --- a/drivers/net/ethernet/ti/inter_core_virt_eth.h +++ b/drivers/net/ethernet/ti/inter_core_virt_eth.h @@ -47,7 +47,11 @@ struct icve_common { enum icve_state state; struct mutex state_lock; /* Lock to be used while changing the interface = state */ struct delayed_work state_work; + struct work_struct rx_mode_work; + struct workqueue_struct *cmd_wq; + struct netdev_hw_addr_list mc_list; struct completion sync_msg; + u8 mcast_addr[ETH_ALEN]; }; =20 struct icve_ndev_priv { --=20 2.40.1