From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC156C433ED for ; Wed, 19 May 2021 12:37:34 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6FFDE611AD for ; Wed, 19 May 2021 12:37:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6FFDE611AD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=marvell.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:CC:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Jx8fNWHoXYVGUX9lzfp86Xh94FqdVX7ruYEAjJrbcFs=; b=GhOng7kR9FgOQb+Tbn/+NX7sm F+T9LSQIBgf7PYWlT9pY4PnomkllccP0YNVU92ASBLBZ8eSG6h1pbz/1ctQGVI/PoU88icfPR6YY4 Tq8sHBfjxQXijk/V3ppEI6Os7GHM9fLfuA48AiKKhIpyCjTfjwOdJO7ynn51Zt/Lj1mNGvLRg5Zi5 4J3pl/EK68McE29ZlwmBqXIhJk/GZ+4EnpeIuZiyCoApfYDryqceVgACatps3WxkJ5+g0qZQaG27+ ueu26LkdyR5XoomhoTAVjOvhGy2hXPIxijTOBOPG4l2QOz3uDZANk4S61sLFmnVZZ+S6n9g0tm92t PLZy5MNnw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ljLRV-003viF-IC; Wed, 19 May 2021 12:36:53 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ljKBR-003jIi-AF for linux-nvme@desiato.infradead.org; Wed, 19 May 2021 11:16:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=37LYrEZPw+g4n02VmjUWaw7nlCIuhrzSljoOl/PbVM4=; b=pEsnF9c/J7lyCuiPJI0kOAJesK RDRoIP9MeQamR6bSJZnSxciYcOcIukBZFdqJ7lBbYkIP5ovLG1/bhWbBlkbLhjQrTRrvRcf4CQ7bK QQVNyoHTRrNwJL9zWPFRRBEGbvGZ6HPbmjYPp5Q4xrivKHmWuDtiwME5Op1GdCQ84BBJ5223KoUMp OLj5mrqea0rwwlkOk9IdFWoxxRjeruNPEb0NYtzAZRBvVRP2ex4T058b6CE5nlxbfaUYvONziiDHY PLGJjseBPjdFmsoFzTCuP3IJa8jZpGB1UAY4KS5kVbP5jZEWLO+l8SLpyqjUlsYlv3i0/9JPuz89M 0hF66twA==; Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ljKBO-00FOUv-9G for linux-nvme@lists.infradead.org; Wed, 19 May 2021 11:16:11 +0000 Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 14JBAUL3007723; Wed, 19 May 2021 04:16:05 -0700 Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com with ESMTP id 38mqcwhy7k-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 19 May 2021 04:16:04 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 19 May 2021 04:16:02 -0700 Received: from lbtlvb-pcie154.il.qlogic.org (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 19 May 2021 04:15:59 -0700 From: Shai Malin To: , , , , , , , CC: , , , , , Subject: [RFC PATCH v5 21/27] qedn: Add support of configuring HW filter block Date: Wed, 19 May 2021 14:13:34 +0300 Message-ID: <20210519111340.20613-22-smalin@marvell.com> X-Mailer: git-send-email 2.16.6 In-Reply-To: <20210519111340.20613-1-smalin@marvell.com> References: <20210519111340.20613-1-smalin@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: OhsJyh5ngMPHz1yIZXnseV1CNj9PevmZ X-Proofpoint-ORIG-GUID: OhsJyh5ngMPHz1yIZXnseV1CNj9PevmZ X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-05-19_04:2021-05-19, 2021-05-19 signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210519_041610_467329_D901BA54 X-CRM114-Status: GOOD ( 20.59 ) X-BeenThere: linux-nvme@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-nvme" Errors-To: linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org From: Prabhakar Kushwaha HW filter can be configured to filter TCP packets based on either source or target TCP port. QEDN leverage this feature to route NVMeTCP traffic. This patch configures HW filter block based on source port for all receiving packets to deliver correct QEDN PF. Acked-by: Igor Russkikh Signed-off-by: Prabhakar Kushwaha Signed-off-by: Omkar Kulkarni Signed-off-by: Michal Kalderon Signed-off-by: Ariel Elior Signed-off-by: Shai Malin Reviewed-by: Hannes Reinecke --- drivers/nvme/hw/qedn/qedn.h | 15 ++++ drivers/nvme/hw/qedn/qedn_main.c | 114 ++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/hw/qedn/qedn.h b/drivers/nvme/hw/qedn/qedn.h index ac1880d1bde9..82261fa95f5d 100644 --- a/drivers/nvme/hw/qedn/qedn.h +++ b/drivers/nvme/hw/qedn/qedn.h @@ -38,6 +38,11 @@ #define QEDN_IRQ_NAME_LEN 24 #define QEDN_IRQ_NO_FLAGS 0 +/* HW defines */ + +/* QEDN_MAX_LLH_PORTS will be extended in future */ +#define QEDN_MAX_LLH_PORTS 16 + /* Destroy connection defines */ #define QEDN_NON_ABORTIVE_TERMINATION 0 #define QEDN_ABORTIVE_TERMINATION 1 @@ -77,6 +82,7 @@ enum qedn_state { QEDN_STATE_CORE_PROBED = 0, QEDN_STATE_CORE_OPEN, + QEDN_STATE_LLH_PORT_FILTER_SET, QEDN_STATE_MFW_STATE, QEDN_STATE_NVMETCP_OPEN, QEDN_STATE_IRQ_SET, @@ -108,6 +114,8 @@ struct qedn_ctx { /* Accessed with atomic bit ops, used with enum qedn_state */ unsigned long state; + u8 num_llh_filters; + struct list_head llh_filter_list; u8 local_mac_addr[ETH_ALEN]; u16 mtu; @@ -174,6 +182,12 @@ enum qedn_conn_state { CONN_STATE_DESTROY_COMPLETE }; +struct qedn_llh_filter { + struct list_head entry; + u16 port; + u16 ref_cnt; +}; + struct qedn_ctrl { struct list_head glb_entry; struct list_head pf_entry; @@ -253,5 +267,6 @@ int qedn_initialize_endpoint(struct qedn_endpoint *ep, u8 *local_mac_addr, int qedn_wait_for_conn_est(struct qedn_conn_ctx *conn_ctx); int qedn_set_con_state(struct qedn_conn_ctx *conn_ctx, enum qedn_conn_state new_state); void qedn_terminate_connection(struct qedn_conn_ctx *conn_ctx); +__be16 qedn_get_in_port(struct sockaddr_storage *sa); #endif /* _QEDN_H_ */ diff --git a/drivers/nvme/hw/qedn/qedn_main.c b/drivers/nvme/hw/qedn/qedn_main.c index f132c049601f..85126f488f9b 100644 --- a/drivers/nvme/hw/qedn/qedn_main.c +++ b/drivers/nvme/hw/qedn/qedn_main.c @@ -22,6 +22,81 @@ static struct pci_device_id qedn_pci_tbl[] = { {0, 0}, }; +__be16 qedn_get_in_port(struct sockaddr_storage *sa) +{ + return sa->ss_family == AF_INET + ? ((struct sockaddr_in *)sa)->sin_port + : ((struct sockaddr_in6 *)sa)->sin6_port; +} + +struct qedn_llh_filter *qedn_add_llh_filter(struct qedn_ctx *qedn, u16 tcp_port) +{ + struct qedn_llh_filter *llh_filter = NULL; + struct qedn_llh_filter *llh_tmp = NULL; + bool new_filter = 1; + int rc = 0; + + /* Check if LLH filter already defined */ + list_for_each_entry_safe(llh_filter, llh_tmp, &qedn->llh_filter_list, entry) { + if (llh_filter->port == tcp_port) { + new_filter = 0; + llh_filter->ref_cnt++; + break; + } + } + + if (new_filter) { + if (qedn->num_llh_filters >= QEDN_MAX_LLH_PORTS) { + pr_err("PF reached the max target ports limit %u. %u\n", + qedn->dev_info.common.abs_pf_id, + qedn->num_llh_filters); + + return NULL; + } + + rc = qed_ops->add_src_tcp_port_filter(qedn->cdev, tcp_port); + if (rc) { + pr_err("LLH port configuration failed. port:%u; rc:%u\n", tcp_port, rc); + + return NULL; + } + + llh_filter = kzalloc(sizeof(*llh_filter), GFP_KERNEL); + if (!llh_filter) { + qed_ops->remove_src_tcp_port_filter(qedn->cdev, tcp_port); + + return NULL; + } + + llh_filter->port = tcp_port; + llh_filter->ref_cnt = 1; + ++qedn->num_llh_filters; + list_add_tail(&llh_filter->entry, &qedn->llh_filter_list); + set_bit(QEDN_STATE_LLH_PORT_FILTER_SET, &qedn->state); + } + + return llh_filter; +} + +void qedn_dec_llh_filter(struct qedn_ctx *qedn, struct qedn_llh_filter *llh_filter) +{ + if (!llh_filter) + return; + + llh_filter->ref_cnt--; + if (!llh_filter->ref_cnt) { + list_del(&llh_filter->entry); + + /* Remove LLH protocol port filter */ + qed_ops->remove_src_tcp_port_filter(qedn->cdev, llh_filter->port); + + --qedn->num_llh_filters; + kfree(llh_filter); + if (!qedn->num_llh_filters) + clear_bit(QEDN_STATE_LLH_PORT_FILTER_SET, &qedn->state); + } +} + static bool qedn_matches_qede(struct qedn_ctx *qedn, struct pci_dev *qede_pdev) { struct pci_dev *qedn_pdev = qedn->pdev; @@ -88,8 +163,10 @@ qedn_claim_dev(struct nvme_tcp_ofld_dev *dev, static int qedn_setup_ctrl(struct nvme_tcp_ofld_ctrl *ctrl, bool new) { struct nvme_tcp_ofld_dev *dev = ctrl->dev; + struct qedn_llh_filter *llh_filter = NULL; struct qedn_ctrl *qctrl = NULL; struct qedn_ctx *qedn = NULL; + __be16 remote_port; int rc = 0; if (new) { @@ -116,15 +193,42 @@ static int qedn_setup_ctrl(struct nvme_tcp_ofld_ctrl *ctrl, bool new) qedn = (struct qedn_ctx *)dev->private_data; qctrl->qedn = qedn; - /* Placeholder - setup LLH filter */ + if (qedn->num_llh_filters == 0) { + qedn->mtu = dev->ndev->mtu; + memcpy(qedn->local_mac_addr, dev->ndev->dev_addr, ETH_ALEN); + } + + remote_port = qedn_get_in_port(&ctrl->conn_params.remote_ip_addr); + if (new) { + llh_filter = qedn_add_llh_filter(qedn, ntohs(remote_port)); + if (!llh_filter) { + rc = -EFAULT; + goto err_out; + } + + qctrl->llh_filter = llh_filter; + set_bit(LLH_FILTER, &qctrl->agg_state); + } return 0; + +err_out: + flush_workqueue(qctrl->sp_wq); + kfree(qctrl); + + return rc; } static int qedn_release_ctrl(struct nvme_tcp_ofld_ctrl *ctrl) { struct qedn_ctrl *qctrl = (struct qedn_ctrl *)ctrl->private_data; + if (test_and_clear_bit(LLH_FILTER, &qctrl->agg_state) && + qctrl->llh_filter) { + qedn_dec_llh_filter(qctrl->qedn, qctrl->llh_filter); + qctrl->llh_filter = NULL; + } + if (test_and_clear_bit(QEDN_STATE_SP_WORK_THREAD_SET, &qctrl->agg_state)) flush_workqueue(qctrl->sp_wq); @@ -405,6 +509,8 @@ static int qedn_setup_irq(struct qedn_ctx *qedn) static inline void qedn_init_pf_struct(struct qedn_ctx *qedn) { + INIT_LIST_HEAD(&qedn->llh_filter_list); + qedn->num_llh_filters = 0; hash_init(qedn->conn_ctx_hash); } @@ -650,6 +756,12 @@ static void __qedn_remove(struct pci_dev *pdev) return; } + if (test_and_clear_bit(QEDN_STATE_LLH_PORT_FILTER_SET, &qedn->state)) { + pr_err("LLH port configuration removal. %d filters still set\n", + qedn->num_llh_filters); + qed_ops->clear_all_filters(qedn->cdev); + } + if (test_and_clear_bit(QEDN_STATE_REGISTERED_OFFLOAD_DEV, &qedn->state)) nvme_tcp_ofld_unregister_dev(&qedn->qedn_ofld_dev); -- 2.22.0 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme