From nobody Fri Dec 19 04:56:34 2025 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (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 5EF0744C7C; Thu, 13 Feb 2025 17:31:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739467901; cv=none; b=bFtZiaPyAbmtw4M36CAMwZ7d3pSM/wYFthr9AWO3DldahzVCaoeZr1+Fpl40CDbU/8jAFuMtuSnq90ktZqiVTp5mgLmaD6oV072e0L1v3CHQMQjLaSHxFLD34B+feovnynZlHvjsFkimZaOJv6pk/nC9XPI0ni2ia2YB62Hvgf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739467901; c=relaxed/simple; bh=fj/2pbq9tAnrGun6ZHjSUES9YOpp/oe19TZ1UXPRuT8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XOZYsn/GC7qNBapYpXtyXWGDZDq5seSyzyB+retHExM1YXWJ2uxZeBVKmEOfVfljucJ0xiej6Bw/wsrYnv1OaHjz3/VuAbp190qkOlnRRQ3Z2sirDrmx/Z8S+VBQvA79mDPlKmK7fezK+VjABeAVZcZJAM4y/MFR84L5AEBJYoI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=OEFIlFBw; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="OEFIlFBw" Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 51DFFMdJ016418; Thu, 13 Feb 2025 09:31:21 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=Z FjkXj77bL9BlSZPw/8R+dC7jR6YedXuOQM2SnbZSGM=; b=OEFIlFBwpwZSweImQ joKG3Tx1ZV3+lhaf0h8c9oIc+j/hJpoo+/KS+hdSlE7O1BzJM+cGzGGXW65BHO3p GLPcpXUoHvT0AhpzWw0P233SLGGrUKR5EsUnn42Z5T3PHsx9sUS699VK4R9M3v09 wTtBYDkvBARtB5vXv0aFjR0LlNpcfnEcsf7E0RPr6Rb4nQKPLZU/3pGa034EGpIP E3IvgCD7erx/yoDR0sfaC6+PhIBlV8AOx/byqBEfFrsw28S45SC4z3BH1prYsXmD fJ25ZBBP6nsEEs4LpUXWJ/IP+9saXo4pg0iLn+zcFJtpgKBV/TWeBwM4yQimNcdG pLxpA== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 44sk7h8bee-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 13 Feb 2025 09:31:21 -0800 (PST) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Thu, 13 Feb 2025 09:31:19 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Thu, 13 Feb 2025 09:31:19 -0800 Received: from hyd1425.marvell.com (unknown [10.29.37.152]) by maili.marvell.com (Postfix) with ESMTP id C44013F7125; Thu, 13 Feb 2025 09:05:33 -0800 (PST) From: Sai Krishna To: , , , , , , , , , , , , , CC: Sai Krishna Subject: [net-next PATCH v9 5/6] octeontx2-af: CN20K mbox implementation for AF's VF Date: Thu, 13 Feb 2025 22:35:03 +0530 Message-ID: <20250213170504.3892412-6-saikrishnag@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250213170504.3892412-1-saikrishnag@marvell.com> References: <20250213170504.3892412-1-saikrishnag@marvell.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-Proofpoint-GUID: fUleCCQeCw4fHU9Tl2wB6hTvF5QiBH9F X-Proofpoint-ORIG-GUID: fUleCCQeCw4fHU9Tl2wB6hTvF5QiBH9F X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-13_07,2025-02-13_01,2024-11-22_01 Content-Type: text/plain; charset="utf-8" This patch implements the CN20k MBOX communication between AF and AF's VFs. This implementation uses separate trigger interrupts for request, response messages against using trigger message data in CN10K. Signed-off-by: Sunil Kovvuri Goutham Signed-off-by: Sai Krishna --- .../ethernet/marvell/octeontx2/af/cn20k/api.h | 4 + .../marvell/octeontx2/af/cn20k/mbox_init.c | 163 +++++++++++++++++- .../ethernet/marvell/octeontx2/af/cn20k/reg.h | 37 ++++ .../net/ethernet/marvell/octeontx2/af/mbox.c | 20 +++ .../net/ethernet/marvell/octeontx2/af/rvu.c | 67 ++++--- .../net/ethernet/marvell/octeontx2/af/rvu.h | 3 + .../ethernet/marvell/octeontx2/nic/cn20k.c | 47 +++++ .../marvell/octeontx2/nic/otx2_common.h | 17 ++ .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 6 +- .../ethernet/marvell/octeontx2/nic/otx2_reg.h | 15 ++ .../ethernet/marvell/octeontx2/nic/otx2_vf.c | 38 +++- 11 files changed, 380 insertions(+), 37 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/api.h index 9436a4a4d815..0617bf5a56e9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h @@ -13,6 +13,7 @@ struct ng_rvu { struct mbox_ops *rvu_mbox_ops; struct qmem *pf_mbox_addr; + struct qmem *vf_mbox_addr; }; =20 struct rvu; @@ -20,6 +21,7 @@ struct rvu; /* Mbox related APIs */ int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int num); int cn20k_register_afpf_mbox_intr(struct rvu *rvu); +int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start); int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr, int num, int type, unsigned long *pf_bmap); void cn20k_rvu_enable_mbox_intr(struct rvu *rvu); @@ -27,4 +29,6 @@ void cn20k_rvu_unregister_interrupts(struct rvu *rvu); void cn20k_free_mbox_memory(struct rvu *rvu); int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev, void *reg_base, int direction, int ndevs); +void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs); +void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs); #endif /* CN20K_API_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c b/= drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c index 81e6c55a04a1..c6e35bbe0c3e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c @@ -13,6 +13,91 @@ #include "reg.h" #include "api.h" =20 +static irqreturn_t cn20k_afvf_mbox_intr_handler(int irq, void *rvu_irq) +{ + struct rvu_irq_data *rvu_irq_data =3D rvu_irq; + struct rvu *rvu =3D rvu_irq_data->rvu; + u64 intr; + + /* Sync with mbox memory region */ + rmb(); + + /* Clear interrupts */ + intr =3D rvupf_read64(rvu, rvu_irq_data->intr_status); + rvupf_write64(rvu, rvu_irq_data->intr_status, intr); + + if (intr) + trace_otx2_msg_interrupt(rvu->pdev, "VF(s) to AF", intr); + + rvu_irq_data->afvf_queue_work_hdlr(&rvu->afvf_wq_info, rvu_irq_data->star= t, + rvu_irq_data->mdevs, intr); + + return IRQ_HANDLED; +} + +int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start) +{ + struct rvu_irq_data *irq_data; + int intr_vec, offset, vec =3D 0; + int err; + + /* irq data for 4 VFPF intr vectors */ + irq_data =3D devm_kcalloc(rvu->dev, 4, + sizeof(struct rvu_irq_data), GFP_KERNEL); + if (!irq_data) + return -ENOMEM; + + for (intr_vec =3D RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=3D + RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; + intr_vec++, vec++) { + switch (intr_vec) { + case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0: + irq_data[vec].intr_status =3D + RVU_MBOX_PF_VFPF_INTX(0); + irq_data[vec].start =3D 0; + irq_data[vec].mdevs =3D 64; + break; + case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1: + irq_data[vec].intr_status =3D + RVU_MBOX_PF_VFPF_INTX(1); + irq_data[vec].start =3D 64; + irq_data[vec].mdevs =3D 64; + break; + case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0: + irq_data[vec].intr_status =3D + RVU_MBOX_PF_VFPF1_INTX(0); + irq_data[vec].start =3D 0; + irq_data[vec].mdevs =3D 64; + break; + case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1: + irq_data[vec].intr_status =3D RVU_MBOX_PF_VFPF1_INTX(1); + irq_data[vec].start =3D 64; + irq_data[vec].mdevs =3D 64; + break; + } + irq_data[vec].afvf_queue_work_hdlr =3D + rvu_queue_work; + offset =3D pf_vec_start + intr_vec; + irq_data[vec].vec_num =3D offset; + irq_data[vec].rvu =3D rvu; + + sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAF VFAF%d Mbox%d", + vec / 2, vec % 2); + err =3D request_irq(pci_irq_vector(rvu->pdev, offset), + rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0, + &rvu->irq_name[offset * NAME_SIZE], + &irq_data[vec]); + if (err) { + dev_err(rvu->dev, + "RVUAF: IRQ registration failed for AFVF mbox irq\n"); + return err; + } + rvu->irq_allocated[offset] =3D true; + } + + return 0; +} + /* CN20K mbox PFx =3D> AF irq handler */ static irqreturn_t cn20k_mbox_pf_common_intr_handler(int irq, void *rvu_ir= q) { @@ -150,6 +235,21 @@ int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void *= *mbox_addr, int region; u64 bar; =20 + if (type =3D=3D TYPE_AFVF) { + for (region =3D 0; region < num; region++) { + if (!test_bit(region, pf_bmap)) + continue; + + bar =3D (u64)phys_to_virt((u64)rvu->ng_rvu->vf_mbox_addr->base); + bar +=3D region * MBOX_SIZE; + mbox_addr[region] =3D (void *)bar; + + if (!mbox_addr[region]) + return -ENOMEM; + } + return 0; + } + for (region =3D 0; region < num; region++) { if (!test_bit(region, pf_bmap)) continue; @@ -167,6 +267,7 @@ int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **= mbox_addr, =20 static struct mbox_ops cn20k_mbox_ops =3D { .pf_intr_handler =3D cn20k_mbox_pf_common_intr_handler, + .afvf_intr_handler =3D cn20k_afvf_mbox_intr_handler, }; =20 static int rvu_alloc_mbox_memory(struct rvu *rvu, int type, @@ -184,6 +285,9 @@ static int rvu_alloc_mbox_memory(struct rvu *rvu, int t= ype, * * AF will access mbox memory using direct physical addresses * and PFs will access the same shared memory from BAR2. + * + * PF <=3D> VF mbox memory also works in the same fashion. + * AFPF, PFVF requires IOVA to be used to maintain the mailbox msgs */ =20 err =3D qmem_alloc(rvu->dev, &mbox_addr, ndevs, mbox_size); @@ -200,6 +304,10 @@ static int rvu_alloc_mbox_memory(struct rvu *rvu, int = type, iova +=3D mbox_size; } break; + case TYPE_AFVF: + rvu->ng_rvu->vf_mbox_addr =3D mbox_addr; + rvupf_write64(rvu, RVU_PF_VF_MBOX_ADDR, (u64)mbox_addr->iova); + break; default: return 0; } @@ -216,9 +324,13 @@ int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int= ndevs) =20 rvu->ng_rvu->rvu_mbox_ops =3D &cn20k_mbox_ops; =20 - for (dev =3D 0; dev < ndevs; dev++) - rvu_write64(rvu, BLKADDR_RVUM, - RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE)); + if (type =3D=3D TYPE_AFVF) { + rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_PF_VF_CFG, ilog2(MBOX_SIZE)); + } else { + for (dev =3D 0; dev < ndevs; dev++) + rvu_write64(rvu, BLKADDR_RVUM, + RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE)); + } =20 return rvu_alloc_mbox_memory(rvu, type, ndevs, MBOX_SIZE); } @@ -226,6 +338,51 @@ int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int= ndevs) void cn20k_free_mbox_memory(struct rvu *rvu) { qmem_free(rvu->dev, rvu->ng_rvu->pf_mbox_addr); + qmem_free(rvu->dev, rvu->ng_rvu->vf_mbox_addr); +} + +void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs) +{ + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(vfs)); + + if (vfs <=3D 64) + return; + + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)= ); + rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(1), INTR_MASK(vfs - 64)); +} + +void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs) +{ + /* Clear any pending interrupts and enable AF VF interrupts for + * the first 64 VFs. + */ + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(vfs)); + + /* FLR */ + rvupf_write64(rvu, RVU_PF_VFFLR_INTX(0), INTR_MASK(vfs)); + rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(0), INTR_MASK(vfs)); + + /* Same for remaining VFs, if any. */ + if (vfs <=3D 64) + return; + + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)= ); + + rvupf_write64(rvu, RVU_PF_VFFLR_INTX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); + rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1SX(1), INTR_MASK(vfs - 64)); } =20 int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf, diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h b/driver= s/net/ethernet/marvell/octeontx2/af/cn20k/reg.h index df2d52567da7..affb39803120 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h @@ -41,4 +41,41 @@ #define NIX_CINTX_INT_W1S(a) (0xd30 | (a) << 12) #define NIX_QINTX_CNT(a) (0xc00 | (a) << 12) =20 +#define RVU_MBOX_AF_VFAF_INT(a) (0x3000 | (a) << 6) +#define RVU_MBOX_AF_VFAF_INT_W1S(a) (0x3008 | (a) << 6) +#define RVU_MBOX_AF_VFAF_INT_ENA_W1S(a) (0x3010 | (a) << 6) +#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6) +#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6) +#define RVU_MBOX_AF_VFAF1_INT(a) (0x3020 | (a) << 6) +#define RVU_MBOX_AF_VFAF1_INT_W1S(a) (0x3028 | (a) << 6) +#define RVU_MBOX_AF_VFAF1_IN_ENA_W1S(a) (0x3030 | (a) << 6) +#define RVU_MBOX_AF_VFAF1_IN_ENA_W1C(a) (0x3038 | (a) << 6) + +#define RVU_MBOX_AF_AFVFX_TRIG(a, b) (0x10000 | (a) << 4 | (b) << 3) +#define RVU_MBOX_AF_VFX_ADDR(a) (0x20000 | (a) << 4) +#define RVU_MBOX_AF_VFX_CFG(a) (0x28000 | (a) << 4) + +#define RVU_MBOX_PF_VFX_PFVF_TRIGX(a) (0x2000 | (a) << 3) + +#define RVU_MBOX_PF_VFPF_INTX(a) (0x1000 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_W1SX(a) (0x1020 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_ENA_W1SX(a) (0x1040 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_ENA_W1CX(a) (0x1060 | (a) << 3) + +#define RVU_MBOX_PF_VFPF1_INTX(a) (0x1080 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_W1SX(a) (0x10a0 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(a) (0x10c0 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(a) (0x10e0 | (a) << 3) + +#define RVU_MBOX_PF_VF_ADDR (0xC40) +#define RVU_MBOX_PF_LMTLINE_ADDR (0xC48) +#define RVU_MBOX_PF_VF_CFG (0xC60) + +#define RVU_MBOX_VF_VFPF_TRIGX(a) (0x3000 | (a) << 3) +#define RVU_MBOX_VF_INT (0x20) +#define RVU_MBOX_VF_INT_W1S (0x28) +#define RVU_MBOX_VF_INT_ENA_W1S (0x30) +#define RVU_MBOX_VF_INT_ENA_W1C (0x38) + +#define RVU_MBOX_VF_VFAF_TRIGX(a) (0x2000 | (a) << 3) #endif /* RVU_MBOX_REG_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c b/drivers/net= /ethernet/marvell/octeontx2/af/mbox.c index bf69019d7bcd..d5adf62d15b7 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c @@ -63,24 +63,28 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci= _dev *pdev, { switch (direction) { case MBOX_DIR_AFPF: + case MBOX_DIR_PFVF: mbox->tx_start =3D MBOX_DOWN_TX_START; mbox->rx_start =3D MBOX_DOWN_RX_START; mbox->tx_size =3D MBOX_DOWN_TX_SIZE; mbox->rx_size =3D MBOX_DOWN_RX_SIZE; break; case MBOX_DIR_PFAF: + case MBOX_DIR_VFPF: mbox->tx_start =3D MBOX_DOWN_RX_START; mbox->rx_start =3D MBOX_DOWN_TX_START; mbox->tx_size =3D MBOX_DOWN_RX_SIZE; mbox->rx_size =3D MBOX_DOWN_TX_SIZE; break; case MBOX_DIR_AFPF_UP: + case MBOX_DIR_PFVF_UP: mbox->tx_start =3D MBOX_UP_TX_START; mbox->rx_start =3D MBOX_UP_RX_START; mbox->tx_size =3D MBOX_UP_TX_SIZE; mbox->rx_size =3D MBOX_UP_RX_SIZE; break; case MBOX_DIR_PFAF_UP: + case MBOX_DIR_VFPF_UP: mbox->tx_start =3D MBOX_UP_RX_START; mbox->rx_start =3D MBOX_UP_TX_START; mbox->tx_size =3D MBOX_UP_RX_SIZE; @@ -107,6 +111,22 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pc= i_dev *pdev, mbox->trigger =3D RVU_MBOX_PF_PFAF_TRIGX(1); mbox->tr_shift =3D 0; break; + case MBOX_DIR_PFVF: + mbox->trigger =3D RVU_MBOX_PF_VFX_PFVF_TRIGX(1); + mbox->tr_shift =3D 4; + break; + case MBOX_DIR_PFVF_UP: + mbox->trigger =3D RVU_MBOX_PF_VFX_PFVF_TRIGX(0); + mbox->tr_shift =3D 4; + break; + case MBOX_DIR_VFPF: + mbox->trigger =3D RVU_MBOX_VF_VFPF_TRIGX(0); + mbox->tr_shift =3D 0; + break; + case MBOX_DIR_VFPF_UP: + mbox->trigger =3D RVU_MBOX_VF_VFPF_TRIGX(1); + mbox->tr_shift =3D 0; + break; default: return -ENODEV; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.c index fd38f3d8c236..6e4416046b21 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -2441,6 +2441,7 @@ static int rvu_get_mbox_regions(struct rvu *rvu, void= **mbox_addr, =20 static struct mbox_ops rvu_mbox_ops =3D { .pf_intr_handler =3D rvu_mbox_pf_intr_handler, + .afvf_intr_handler =3D rvu_mbox_intr_handler, }; =20 static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw, @@ -2984,6 +2985,10 @@ static int rvu_afvf_msix_vectors_num_ok(struct rvu *= rvu) * VF interrupts can be handled. Offset equal to zero means * that PF vectors are not configured and overlapping AF vectors. */ + if (is_cn20k(rvu->pdev)) + return (pfvf->msix.max >=3D (int)RVU_AF_CN20K_INT_VEC_CNT + + (int)RVU_MBOX_PF_INT_VEC_CNT) && offset; + return (pfvf->msix.max >=3D (int)RVU_AF_INT_VEC_CNT + (int)RVU_PF_INT_VEC_CNT) && offset; } @@ -3092,34 +3097,40 @@ static int rvu_register_interrupts(struct rvu *rvu) /* Get PF MSIX vectors offset. */ pf_vec_start =3D rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_INT_CFG(0)) & 0x3ff; + if (!is_cn20k(rvu->pdev)) { + /* Register MBOX0 interrupt. */ + offset =3D pf_vec_start + RVU_PF_INT_VEC_VFPF_MBOX0; + sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAFVF Mbox0"); + ret =3D request_irq(pci_irq_vector(rvu->pdev, offset), + rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0, + &rvu->irq_name[offset * NAME_SIZE], + rvu); + if (ret) + dev_err(rvu->dev, + "RVUAF: IRQ registration failed for Mbox0\n"); =20 - /* Register MBOX0 interrupt. */ - offset =3D pf_vec_start + RVU_PF_INT_VEC_VFPF_MBOX0; - sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAFVF Mbox0"); - ret =3D request_irq(pci_irq_vector(rvu->pdev, offset), - rvu_mbox_intr_handler, 0, - &rvu->irq_name[offset * NAME_SIZE], - rvu); - if (ret) - dev_err(rvu->dev, - "RVUAF: IRQ registration failed for Mbox0\n"); - - rvu->irq_allocated[offset] =3D true; + rvu->irq_allocated[offset] =3D true; =20 - /* Register MBOX1 interrupt. MBOX1 IRQ number follows MBOX0 so - * simply increment current offset by 1. - */ - offset =3D pf_vec_start + RVU_PF_INT_VEC_VFPF_MBOX1; - sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAFVF Mbox1"); - ret =3D request_irq(pci_irq_vector(rvu->pdev, offset), - rvu_mbox_intr_handler, 0, - &rvu->irq_name[offset * NAME_SIZE], - rvu); - if (ret) - dev_err(rvu->dev, - "RVUAF: IRQ registration failed for Mbox1\n"); + /* Register MBOX1 interrupt. MBOX1 IRQ number follows MBOX0 so + * simply increment current offset by 1. + */ + offset =3D pf_vec_start + RVU_PF_INT_VEC_VFPF_MBOX1; + sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAFVF Mbox1"); + ret =3D request_irq(pci_irq_vector(rvu->pdev, offset), + rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0, + &rvu->irq_name[offset * NAME_SIZE], + rvu); + if (ret) + dev_err(rvu->dev, + "RVUAF: IRQ registration failed for Mbox1\n"); =20 - rvu->irq_allocated[offset] =3D true; + rvu->irq_allocated[offset] =3D true; + } else { + ret =3D cn20k_register_afvf_mbox_intr(rvu, pf_vec_start); + if (ret) + dev_err(rvu->dev, + "RVUAF: IRQ registration failed for Mbox\n"); + } =20 /* Register FLR interrupt handler for AF's VFs */ offset =3D pf_vec_start + RVU_PF_INT_VEC_VFFLR0; @@ -3230,6 +3241,9 @@ static void rvu_disable_afvf_intr(struct rvu *rvu) { int vfs =3D rvu->vfs; =20 + if (is_cn20k(rvu->pdev)) + return cn20k_rvu_disable_afvf_intr(rvu, vfs); + rvupf_write64(rvu, RVU_PF_VFPF_MBOX_INT_ENA_W1CX(0), INTR_MASK(vfs)); rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(vfs)); rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(vfs)); @@ -3246,6 +3260,9 @@ static void rvu_enable_afvf_intr(struct rvu *rvu) { int vfs =3D rvu->vfs; =20 + if (is_cn20k(rvu->pdev)) + return cn20k_rvu_enable_afvf_intr(rvu, vfs); + /* Clear any pending interrupts and enable AF VF interrupts for * the first 64 VFs. */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/= ethernet/marvell/octeontx2/af/rvu.h index 34f60e27f95e..2e665b716085 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -476,6 +476,8 @@ struct rvu_irq_data { u64 intr_status; void (*rvu_queue_work_hdlr)(struct mbox_wq_info *mw, int first, int mdevs, u64 intr); + void (*afvf_queue_work_hdlr)(struct mbox_wq_info *mw, int first, + int mdevs, u64 intr); struct rvu *rvu; int vec_num; int start; @@ -484,6 +486,7 @@ struct rvu_irq_data { =20 struct mbox_ops { irqreturn_t (*pf_intr_handler)(int irq, void *rvu_irq); + irqreturn_t (*afvf_intr_handler)(int irq, void *rvu_irq); }; =20 struct channel_fwdata { diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c b/drivers/n= et/ethernet/marvell/octeontx2/nic/cn20k.c index d7a5f5449d55..ef37aa0564b5 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c @@ -12,6 +12,7 @@ =20 static struct dev_hw_ops cn20k_hw_ops =3D { .pfaf_mbox_intr_handler =3D cn20k_pfaf_mbox_intr_handler, + .vfaf_mbox_intr_handler =3D cn20k_vfaf_mbox_intr_handler, }; =20 void cn20k_init(struct otx2_nic *pfvf) @@ -61,3 +62,49 @@ irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *= pf_irq) =20 return IRQ_HANDLED; } + +irqreturn_t cn20k_vfaf_mbox_intr_handler(int irq, void *vf_irq) +{ + struct otx2_nic *vf =3D vf_irq; + struct otx2_mbox_dev *mdev; + struct otx2_mbox *mbox; + struct mbox_hdr *hdr; + int vf_trig_val; + + vf_trig_val =3D otx2_read64(vf, RVU_VF_INT) & 0x3; + /* Clear the IRQ */ + otx2_write64(vf, RVU_VF_INT, vf_trig_val); + + /* Read latest mbox data */ + smp_rmb(); + + if (vf_trig_val & BIT_ULL(1)) { + /* Check for PF =3D> VF response messages */ + mbox =3D &vf->mbox.mbox; + mdev =3D &mbox->dev[0]; + otx2_sync_mbox_bbuf(mbox, 0); + + hdr =3D (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); + if (hdr->num_msgs) + queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk); + + trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF0 to VF", + BIT_ULL(1)); + } + + if (vf_trig_val & BIT_ULL(0)) { + /* Check for PF =3D> VF notification messages */ + mbox =3D &vf->mbox.mbox_up; + mdev =3D &mbox->dev[0]; + otx2_sync_mbox_bbuf(mbox, 0); + + hdr =3D (struct mbox_hdr *)(mdev->mbase + mbox->rx_start); + if (hdr->num_msgs) + queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk); + + trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF0 to VF", + BIT_ULL(0)); + } + + return IRQ_HANDLED; +} diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/dri= vers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index fc1200f51215..1757d183b775 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -64,6 +64,8 @@ =20 irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq); irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *pf_irq); +irqreturn_t cn20k_vfaf_mbox_intr_handler(int irq, void *vf_irq); +irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq); =20 enum arua_mapped_qtypes { AURA_NIX_RQ, @@ -243,6 +245,7 @@ struct otx2_hw { u16 nix_msixoff; /* Offset of NIX vectors */ char *irq_name; cpumask_var_t *affinity_mask; + struct pf_irq_data *pfvf_irq_devid[4]; =20 /* Stats */ struct otx2_dev_stats dev_stats; @@ -364,6 +367,7 @@ struct dev_hw_ops { int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); void (*aura_freeptr)(void *dev, int aura, u64 buf); irqreturn_t (*pfaf_mbox_intr_handler)(int irq, void *pf_irq); + irqreturn_t (*vfaf_mbox_intr_handler)(int irq, void *pf_irq); }; =20 #define CN10K_MCS_SA_PER_SC 4 @@ -431,6 +435,16 @@ struct cn10k_mcs_cfg { struct list_head rxsc_list; }; =20 +struct pf_irq_data { + u64 intr_status; + void (*pf_queue_work_hdlr)(struct mbox *mb, struct workqueue_struct *mw, + int first, int mdevs, u64 intr); + struct otx2_nic *pf; + int vec_num; + int start; + int mdevs; +}; + struct otx2_nic { void __iomem *reg_base; struct net_device *netdev; @@ -474,6 +488,7 @@ struct otx2_nic { struct mbox *mbox_pfvf; struct workqueue_struct *mbox_wq; struct workqueue_struct *mbox_pfvf_wq; + struct qmem *pfvf_mbox_addr; =20 u8 total_vfs; u16 pcifunc; /* RVU PF_FUNC */ @@ -1171,4 +1186,6 @@ static inline int mcam_entry_cmp(const void *a, const= void *b) dma_addr_t otx2_dma_map_skb_frag(struct otx2_nic *pfvf, struct sk_buff *skb, int seg, int *len); void otx2_dma_unmap_skb_frags(struct otx2_nic *pfvf, struct sg_list *sg); +void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq, + int first, int mdevs, u64 intr); #endif /* OTX2_COMMON_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers= /net/ethernet/marvell/octeontx2/nic/otx2_pf.c index e4b99c25f849..503d73ce5661 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -295,8 +295,8 @@ static int otx2_pf_flr_init(struct otx2_nic *pf, int nu= m_vfs) return 0; } =20 -static void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *m= box_wq, - int first, int mdevs, u64 intr) +void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq, + int first, int mdevs, u64 intr) { struct otx2_mbox_dev *mdev; struct otx2_mbox *mbox; @@ -540,7 +540,7 @@ static void otx2_pfvf_mbox_up_handler(struct work_struc= t *work) } } =20 -static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) +irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) { struct otx2_nic *pf =3D (struct otx2_nic *)(pf_irq); int vfs =3D pf->total_vfs; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h b/driver= s/net/ethernet/marvell/octeontx2/nic/otx2_reg.h index 901f8cf7f27a..1cd576fd09c5 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h @@ -44,6 +44,17 @@ #define RVU_PF_VF_MBOX_ADDR (0xC40) #define RVU_PF_LMTLINE_ADDR (0xC48) =20 +#define RVU_MBOX_PF_VFX_PFVF_TRIGX(a) (0x2000 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INTX(a) (0x1000 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_W1SX(a) (0x1020 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_ENA_W1SX(a) (0x1040 | (a) << 3) +#define RVU_MBOX_PF_VFPF_INT_ENA_W1CX(a) (0x1060 | (a) << 3) + +#define RVU_MBOX_PF_VFPF1_INTX(a) (0x1080 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_W1SX(a) (0x10a0 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(a) (0x10c0 | (a) << 3) +#define RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(a) (0x10e0 | (a) << 3) + /* RVU VF registers */ #define RVU_VF_VFPF_MBOX0 (0x00000) #define RVU_VF_VFPF_MBOX1 (0x00008) @@ -61,6 +72,7 @@ /* CN20K RVU_MBOX_E: RVU PF/VF MBOX Address Range Enumeration */ #define RVU_MBOX_AF_PFX_ADDR(a) (0x5000 | (a) << 4) #define RVU_PFX_FUNC_PFAF_MBOX (0x80000) +#define RVU_PFX_FUNCX_VFAF_MBOX (0x40000) =20 #define RVU_FUNC_BLKADDR_SHIFT 20 #define RVU_FUNC_BLKADDR_MASK 0x1FULL @@ -147,4 +159,7 @@ #define LMT_LF_LMTLINEX(a) (LMT_LFBASE | 0x000 | (a) << 12) #define LMT_LF_LMTCANCEL (LMT_LFBASE | 0x400) =20 +/* CN20K registers */ +#define RVU_PF_DISC (0x0) + #endif /* OTX2_REG_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers= /net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 9c69d06a36cd..f3c841dc27cc 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -240,6 +240,10 @@ static void otx2vf_disable_mbox_intr(struct otx2_nic *= vf) =20 /* Disable VF =3D> PF mailbox IRQ */ otx2_write64(vf, RVU_VF_INT_ENA_W1C, BIT_ULL(0)); + + if (is_cn20k(vf->pdev)) + otx2_write64(vf, RVU_VF_INT_ENA_W1C, BIT_ULL(0) | BIT_ULL(1)); + free_irq(vector, vf); } =20 @@ -252,9 +256,18 @@ static int otx2vf_register_mbox_intr(struct otx2_nic *= vf, bool probe_pf) =20 /* Register mailbox interrupt handler */ irq_name =3D &hw->irq_name[RVU_VF_INT_VEC_MBOX * NAME_SIZE]; - snprintf(irq_name, NAME_SIZE, "RVUVFAF Mbox"); - err =3D request_irq(pci_irq_vector(vf->pdev, RVU_VF_INT_VEC_MBOX), - otx2vf_vfaf_mbox_intr_handler, 0, irq_name, vf); + snprintf(irq_name, NAME_SIZE, "RVUVF%d AFVF Mbox", ((vf->pcifunc & + RVU_PFVF_FUNC_MASK) - 1)); + + if (!is_cn20k(vf->pdev)) { + err =3D request_irq(pci_irq_vector(vf->pdev, RVU_VF_INT_VEC_MBOX), + otx2vf_vfaf_mbox_intr_handler, 0, irq_name, vf); + } else { + err =3D request_irq(pci_irq_vector(vf->pdev, RVU_VF_INT_VEC_MBOX), + vf->hw_ops->vfaf_mbox_intr_handler, 0, irq_name, + vf); + } + if (err) { dev_err(vf->dev, "RVUPF: IRQ registration failed for VFAF mbox irq\n"); @@ -264,8 +277,15 @@ static int otx2vf_register_mbox_intr(struct otx2_nic *= vf, bool probe_pf) /* Enable mailbox interrupt for msgs coming from PF. * First clear to avoid spurious interrupts, if any. */ - otx2_write64(vf, RVU_VF_INT, BIT_ULL(0)); - otx2_write64(vf, RVU_VF_INT_ENA_W1S, BIT_ULL(0)); + if (!is_cn20k(vf->pdev)) { + otx2_write64(vf, RVU_VF_INT, BIT_ULL(0)); + otx2_write64(vf, RVU_VF_INT_ENA_W1S, BIT_ULL(0)); + } else { + otx2_write64(vf, RVU_VF_INT, BIT_ULL(0) | BIT_ULL(1) | + BIT_ULL(2) | BIT_ULL(3)); + otx2_write64(vf, RVU_VF_INT_ENA_W1S, BIT_ULL(0) | + BIT_ULL(1) | BIT_ULL(2) | BIT_ULL(3)); + } =20 if (!probe_pf) return 0; @@ -315,7 +335,13 @@ static int otx2vf_vfaf_mbox_init(struct otx2_nic *vf) if (!vf->mbox_wq) return -ENOMEM; =20 - if (test_bit(CN10K_MBOX, &vf->hw.cap_flag)) { + /* For cn20k platform, VF mailbox region is in dram aliased from AF + * VF MBOX ADDR, MBOX is a separate RVU block. + */ + if (is_cn20k(vf->pdev)) { + hwbase =3D vf->reg_base + RVU_VF_MBOX_REGION + ((u64)BLKADDR_MBOX << + RVU_FUNC_BLKADDR_SHIFT); + } else if (test_bit(CN10K_MBOX, &vf->hw.cap_flag)) { /* For cn10k platform, VF mailbox region is in its BAR2 * register space */ --=20 2.25.1