lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAH-L+nM6PJ6e=S7LTivrV2KvFMdZ7XJGzp3Rq3Y_zuxyhOM+Ng@mail.gmail.com>
Date: Wed, 12 Jun 2024 21:15:17 +0530
From: Kalesh Anakkur Purayil <kalesh-anakkur.purayil@...adcom.com>
To: Bharat Bhushan <bbhushan2@...vell.com>
Cc: netdev@...r.kernel.org, linux-kernel@...r.kernel.org, sgoutham@...vell.com, 
	gakula@...vell.com, sbhatta@...vell.com, hkelam@...vell.com, 
	davem@...emloft.net, edumazet@...gle.com, kuba@...nel.org, pabeni@...hat.com, 
	jerinj@...vell.com, lcherian@...vell.com, richardcochran@...il.com
Subject: Re: [net-next,v4 4/8] cn10k-ipsec: Initialize crypto hardware for
 outb inline ipsec

On Wed, Jun 12, 2024 at 7:18 PM Bharat Bhushan <bbhushan2@...vell.com> wrote:
>
> One crypto hardware logical function (cpt-lf) per netdev is
> required for inline ipsec outbound functionality. Allocate,
> attach and initialize one crypto hardware function when
> enabling inline ipsec crypto offload. Crypto hardware
> function will be detached and freed on disabling inline
> ipsec.
>
> Signed-off-by: Bharat Bhushan <bbhushan2@...vell.com>
> ---
> v3->v4:
>  - Added some other cleanup comment from Kalesh Anakkur Purayil
>  - Fixed enabling nixlf for crypto operation
>
> v1->v2:
>  - Fix compilation error to build driver a module
>  - Fix couple of compilation warnings
>
>  .../ethernet/marvell/octeontx2/af/rvu_nix.c   |   6 +
>  .../ethernet/marvell/octeontx2/nic/Makefile   |   1 +
>  .../marvell/octeontx2/nic/cn10k_ipsec.c       | 393 ++++++++++++++++++
>  .../marvell/octeontx2/nic/cn10k_ipsec.h       | 104 +++++
>  .../marvell/octeontx2/nic/otx2_common.h       |  18 +
>  .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  14 +-
>  .../ethernet/marvell/octeontx2/nic/otx2_vf.c  |  10 +-
>  7 files changed, 544 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
>  create mode 100644 drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
>
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> index b7633d9c2c40..b7938565338f 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> @@ -5030,6 +5030,7 @@ static int rvu_nix_block_init(struct rvu *rvu, struct nix_hw *nix_hw)
>  int rvu_nix_init(struct rvu *rvu)
>  {
>         struct rvu_hwinfo *hw = rvu->hw;
> +       struct rvu_block *block;
>         struct nix_hw *nix_hw;
>         int blkaddr = 0, err;
>         int i = 0;
> @@ -5051,6 +5052,11 @@ int rvu_nix_init(struct rvu *rvu)
>                 i++;
>         }
>
> +       /* Enable NIXLF for CPT operation */
> +       block = &hw->block[BLKADDR_NIX0];
> +       __set_bit((block->lf.max - 1), block->lf.bmap);
> +       rvu_write64(rvu, BLKADDR_NIX0, NIX_PRIV_LFX_CFG |
> +                   ((block->lf.max - 1) << 8), BIT_ULL(63));
>         return 0;
>  }
>
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile
> index 5664f768cb0c..9695f967d416 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile
> @@ -14,5 +14,6 @@ rvu_nicvf-y := otx2_vf.o otx2_devlink.o
>  rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o
>  rvu_nicvf-$(CONFIG_DCB) += otx2_dcbnl.o
>  rvu_nicpf-$(CONFIG_MACSEC) += cn10k_macsec.o
> +rvu_nicpf-$(CONFIG_XFRM_OFFLOAD) += cn10k_ipsec.o
>
>  ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
> new file mode 100644
> index 000000000000..fc1029c17c00
> --- /dev/null
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
> @@ -0,0 +1,393 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Marvell IPSEC offload driver
> + *
> + * Copyright (C) 2024 Marvell.
> + */
> +
> +#include <net/xfrm.h>
> +#include <linux/netdevice.h>
> +#include <linux/bitfield.h>
> +
> +#include "otx2_common.h"
> +#include "cn10k_ipsec.h"
> +
> +static bool is_dev_support_inline_ipsec(struct pci_dev *pdev)
> +{
> +       return is_dev_cn10ka_b0(pdev) || is_dev_cn10kb(pdev);
> +}
> +
> +static int cn10k_outb_cptlf_attach(struct otx2_nic *pf)
> +{
> +       struct rsrc_attach *attach;
> +       int ret;
> +
> +       mutex_lock(&pf->mbox.lock);
> +       /* Get memory to put this msg */
> +       attach = otx2_mbox_alloc_msg_attach_resources(&pf->mbox);
> +       if (!attach) {
> +               ret = -ENOMEM;
> +               goto unlock;
> +       }
> +
> +       attach->cptlfs = true;
> +       attach->modify = true;
> +
> +       /* Send attach request to AF */
> +       ret = otx2_sync_mbox_msg(&pf->mbox);
> +
> +unlock:
> +       mutex_unlock(&pf->mbox.lock);
> +       return ret;
> +}
> +
> +static int cn10k_outb_cptlf_detach(struct otx2_nic *pf)
> +{
> +       struct rsrc_detach *detach;
> +       int ret;
[Kalesh] As an optimization, you can assign ret = -ENOMEM here and
call goto directly in the failure path. This applies to functions
below as well.
> +
> +       mutex_lock(&pf->mbox.lock);
> +       detach = otx2_mbox_alloc_msg_detach_resources(&pf->mbox);
> +       if (!detach) {
> +               ret = -ENOMEM;
> +               goto unlock;
> +       }
> +
> +       detach->partial = true;
> +       detach->cptlfs = true;
> +
> +       /* Send detach request to AF */
> +       otx2_sync_mbox_msg(&pf->mbox);
> +
> +unlock:
> +       mutex_unlock(&pf->mbox.lock);
> +       return ret;
> +}
> +
> +static int cn10k_outb_cptlf_alloc(struct otx2_nic *pf)
> +{
> +       struct cpt_lf_alloc_req_msg *req;
> +       int ret;
> +
> +       mutex_lock(&pf->mbox.lock);
> +       req = otx2_mbox_alloc_msg_cpt_lf_alloc(&pf->mbox);
> +       if (!req) {
> +               ret = -ENOMEM;
> +               goto unlock;
> +       }
> +
> +       /* PF function */
> +       req->nix_pf_func = pf->pcifunc;
> +       /* Enable SE-IE Engine Group */
> +       req->eng_grpmsk = 1 << CN10K_DEF_CPT_IPSEC_EGRP;
> +
> +       ret = otx2_sync_mbox_msg(&pf->mbox);
> +
> +unlock:
> +       mutex_unlock(&pf->mbox.lock);
> +       return ret;
> +}
> +
> +static void cn10k_outb_cptlf_free(struct otx2_nic *pf)
> +{
> +       mutex_lock(&pf->mbox.lock);
> +       otx2_mbox_alloc_msg_cpt_lf_free(&pf->mbox);
> +       otx2_sync_mbox_msg(&pf->mbox);
> +       mutex_unlock(&pf->mbox.lock);
> +}
> +
> +static int cn10k_outb_cptlf_config(struct otx2_nic *pf)
> +{
> +       struct cpt_inline_ipsec_cfg_msg *req;
> +       int ret;
> +
> +       mutex_lock(&pf->mbox.lock);
> +       req = otx2_mbox_alloc_msg_cpt_inline_ipsec_cfg(&pf->mbox);
> +       if (!req) {
> +               ret = -ENOMEM;
> +               goto unlock;
> +       }
> +
> +       req->dir = CPT_INLINE_OUTBOUND;
> +       req->enable = 1;
> +       req->nix_pf_func = pf->pcifunc;
> +       ret = otx2_sync_mbox_msg(&pf->mbox);
> +unlock:
> +       mutex_unlock(&pf->mbox.lock);
> +       return ret;
> +}
> +
> +static void cn10k_outb_cptlf_iq_enable(struct otx2_nic *pf)
> +{
> +       u64 reg_val;
> +
> +       /* Set Execution Enable of instruction queue */
> +       reg_val = otx2_read64(pf, CN10K_CPT_LF_INPROG);
> +       reg_val |= BIT_ULL(16);
> +       otx2_write64(pf, CN10K_CPT_LF_INPROG, reg_val);
> +
> +       /* Set iqueue's enqueuing */
> +       reg_val = otx2_read64(pf, CN10K_CPT_LF_CTL);
> +       reg_val |= BIT_ULL(0);
> +       otx2_write64(pf, CN10K_CPT_LF_CTL, reg_val);
> +}
> +
> +static void cn10k_outb_cptlf_iq_disable(struct otx2_nic *pf)
> +{
> +       u32 inflight, grb_cnt, gwb_cnt;
> +       u32 nq_ptr, dq_ptr;
> +       int timeout = 20;
> +       u64 reg_val;
> +       int cnt;
> +
> +       /* Disable instructions enqueuing */
> +       otx2_write64(pf, CN10K_CPT_LF_CTL, 0ull);
> +
> +       /* Wait for instruction queue to become empty.
> +        * CPT_LF_INPROG.INFLIGHT count is zero
> +        */
> +       do {
> +               reg_val = otx2_read64(pf, CN10K_CPT_LF_INPROG);
> +               inflight = FIELD_GET(CPT_LF_INPROG_INFLIGHT, reg_val);
> +               if (!inflight)
> +                       break;
> +
> +               usleep_range(10000, 20000);
> +               if (timeout-- < 0) {
> +                       netdev_err(pf->netdev, "Timeout to cleanup CPT IQ\n");
> +                       break;
> +               }
> +       } while (1);
> +
> +       /* Disable executions in the LF's queue,
> +        * the queue should be empty at this point
> +        */
> +       reg_val &= ~BIT_ULL(16);
> +       otx2_write64(pf, CN10K_CPT_LF_INPROG, reg_val);
> +
> +       /* Wait for instruction queue to become empty */
> +       cnt = 0;
> +       do {
> +               reg_val = otx2_read64(pf, CN10K_CPT_LF_INPROG);
> +               if (reg_val & BIT_ULL(31))
> +                       cnt = 0;
> +               else
> +                       cnt++;
> +               reg_val = otx2_read64(pf, CN10K_CPT_LF_Q_GRP_PTR);
> +               nq_ptr = FIELD_GET(CPT_LF_Q_GRP_PTR_DQ_PTR, reg_val);
> +               dq_ptr = FIELD_GET(CPT_LF_Q_GRP_PTR_DQ_PTR, reg_val);
> +       } while ((cnt < 10) && (nq_ptr != dq_ptr));
> +
> +       cnt = 0;
> +       do {
> +               reg_val = otx2_read64(pf, CN10K_CPT_LF_INPROG);
> +               inflight = FIELD_GET(CPT_LF_INPROG_INFLIGHT, reg_val);
> +               grb_cnt = FIELD_GET(CPT_LF_INPROG_GRB_CNT, reg_val);
> +               gwb_cnt = FIELD_GET(CPT_LF_INPROG_GWB_CNT, reg_val);
> +               if (inflight == 0 && gwb_cnt < 40 &&
> +                   (grb_cnt == 0 || grb_cnt == 40))
> +                       cnt++;
> +               else
> +                       cnt = 0;
> +       } while (cnt < 10);
> +}
> +
> +/* Allocate memory for CPT outbound Instruction queue.
> + * Instruction queue memory format is:
> + *      -----------------------------
> + *     | Instruction Group memory    |
> + *     |  (CPT_LF_Q_SIZE[SIZE_DIV40] |
> + *     |   x 16 Bytes)               |
> + *     |                             |
> + *      ----------------------------- <-- CPT_LF_Q_BASE[ADDR]
> + *     | Flow Control (128 Bytes)    |
> + *     |                             |
> + *      -----------------------------
> + *     |  Instruction Memory         |
> + *     |  (CPT_LF_Q_SIZE[SIZE_DIV40] |
> + *     |   × 40 × 64 bytes)          |
> + *     |                             |
> + *      -----------------------------
> + */
> +static int cn10k_outb_cptlf_iq_alloc(struct otx2_nic *pf)
> +{
> +       struct cn10k_cpt_inst_queue *iq = &pf->ipsec.iq;
> +
> +       iq->size = CN10K_CPT_INST_QLEN_BYTES + CN10K_CPT_Q_FC_LEN +
> +                   CN10K_CPT_INST_GRP_QLEN_BYTES + OTX2_ALIGN;
> +
> +       iq->real_vaddr = dma_alloc_coherent(pf->dev, iq->size,
> +                                           &iq->real_dma_addr, GFP_KERNEL);
> +       if (!iq->real_vaddr)
> +               return -ENOMEM;
> +
> +       /* iq->vaddr/dma_addr points to Flow Control location */
> +       iq->vaddr = iq->real_vaddr + CN10K_CPT_INST_GRP_QLEN_BYTES;
> +       iq->dma_addr = iq->real_dma_addr + CN10K_CPT_INST_GRP_QLEN_BYTES;
> +
> +       /* Align pointers */
> +       iq->vaddr = PTR_ALIGN(iq->vaddr, OTX2_ALIGN);
> +       iq->dma_addr = PTR_ALIGN(iq->dma_addr, OTX2_ALIGN);
> +       return 0;
> +}
> +
> +static void cn10k_outb_cptlf_iq_free(struct otx2_nic *pf)
> +{
> +       struct cn10k_cpt_inst_queue *iq = &pf->ipsec.iq;
> +
> +       if (!iq->real_vaddr)
[Kalesh] This check does not look correct. You should free only if
allocation has succeeded.
> +               dma_free_coherent(pf->dev, iq->size, iq->real_vaddr,
> +                                 iq->real_dma_addr);
> +
> +       iq->real_vaddr = NULL;
> +       iq->vaddr = NULL;
> +}
> +
> +static int cn10k_outb_cptlf_iq_init(struct otx2_nic *pf)
> +{
> +       u64 reg_val;
> +       int ret;
> +
> +       /* Allocate Memory for CPT IQ */
> +       ret = cn10k_outb_cptlf_iq_alloc(pf);
> +       if (ret)
> +               return ret;
> +
> +       /* Disable IQ */
> +       cn10k_outb_cptlf_iq_disable(pf);
> +
> +       /* Set IQ base address */
> +       otx2_write64(pf, CN10K_CPT_LF_Q_BASE, pf->ipsec.iq.dma_addr);
> +
> +       /* Set IQ size */
> +       reg_val = FIELD_PREP(CPT_LF_Q_SIZE_DIV40, CN10K_CPT_SIZE_DIV40 +
> +                            CN10K_CPT_EXTRA_SIZE_DIV40);
> +       otx2_write64(pf, CN10K_CPT_LF_Q_SIZE, reg_val);
> +
> +       return 0;
> +}
> +
> +static int cn10k_outb_cptlf_init(struct otx2_nic *pf)
> +{
> +       int ret;
> +
> +       /* Initialize CPTLF Instruction Queue (IQ) */
> +       ret = cn10k_outb_cptlf_iq_init(pf);
> +       if (ret)
> +               return ret;
> +
> +       /* Configure CPTLF for outbound inline ipsec */
> +       ret = cn10k_outb_cptlf_config(pf);
> +       if (ret)
> +               goto iq_clean;
> +
> +       /* Enable CPTLF IQ */
> +       cn10k_outb_cptlf_iq_enable(pf);
> +       return 0;
> +iq_clean:
> +       cn10k_outb_cptlf_iq_free(pf);
> +       return ret;
> +}
> +
> +static int cn10k_outb_cpt_init(struct net_device *netdev)
> +{
> +       struct otx2_nic *pf = netdev_priv(netdev);
> +       int ret;
> +
> +       mutex_lock(&pf->ipsec.lock);
> +
> +       /* Attach a CPT LF for outbound inline ipsec */
> +       ret = cn10k_outb_cptlf_attach(pf);
> +       if (ret)
> +               goto unlock;
> +
> +       /* Allocate a CPT LF for outbound inline ipsec */
> +       ret = cn10k_outb_cptlf_alloc(pf);
> +       if (ret)
> +               goto detach;
> +
> +       /* Initialize the CPTLF for outbound inline ipsec */
> +       ret = cn10k_outb_cptlf_init(pf);
> +       if (ret)
> +               goto lf_free;
> +
> +       pf->ipsec.io_addr = (__force u64)otx2_get_regaddr(pf,
> +                                               CN10K_CPT_LF_NQX(0));
> +
> +       /* Set inline ipsec enabled for this device */
> +       pf->flags |= OTX2_FLAG_INLINE_IPSEC_ENABLED;
> +
> +       goto unlock;
> +
> +lf_free:
> +       cn10k_outb_cptlf_free(pf);
> +detach:
> +       cn10k_outb_cptlf_detach(pf);
> +unlock:
> +       mutex_unlock(&pf->ipsec.lock);
> +       return ret;
> +}
> +
> +static int cn10k_outb_cpt_clean(struct otx2_nic *pf)
> +{
> +       int ret;
> +
> +       mutex_lock(&pf->ipsec.lock);
> +
> +       /* Set inline ipsec disabled for this device */
> +       pf->flags &= ~OTX2_FLAG_INLINE_IPSEC_ENABLED;
> +
> +       /* Disable CPTLF Instruction Queue (IQ) */
> +       cn10k_outb_cptlf_iq_disable(pf);
> +
> +       /* Set IQ base address and size to 0 */
> +       otx2_write64(pf, CN10K_CPT_LF_Q_BASE, 0);
> +       otx2_write64(pf, CN10K_CPT_LF_Q_SIZE, 0);
> +
> +       /* Free CPTLF IQ */
> +       cn10k_outb_cptlf_iq_free(pf);
> +
> +       /* Free and detach CPT LF */
> +       cn10k_outb_cptlf_free(pf);
> +       ret = cn10k_outb_cptlf_detach(pf);
> +       if (ret)
> +               netdev_err(pf->netdev, "Failed to detach CPT LF\n");
> +
> +       mutex_unlock(&pf->ipsec.lock);
> +       return ret;
> +}
> +
> +int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable)
> +{
> +       struct otx2_nic *pf = netdev_priv(netdev);
> +
> +       /* Inline ipsec supported on cn10k */
> +       if (!is_dev_support_inline_ipsec(pf->pdev))
> +               return -EOPNOTSUPP;
> +
> +       if (!enable)
> +               return cn10k_outb_cpt_clean(pf);
> +
> +       /* Initialize CPT for outbound inline ipsec */
> +       return cn10k_outb_cpt_init(netdev);
> +}
> +
> +int cn10k_ipsec_init(struct net_device *netdev)
> +{
> +       struct otx2_nic *pf = netdev_priv(netdev);
> +
> +       if (!is_dev_support_inline_ipsec(pf->pdev))
> +               return 0;
> +
> +       mutex_init(&pf->ipsec.lock);
> +       return 0;
> +}
> +EXPORT_SYMBOL(cn10k_ipsec_init);
> +
> +void cn10k_ipsec_clean(struct otx2_nic *pf)
> +{
> +       if (!is_dev_support_inline_ipsec(pf->pdev))
> +               return;
> +
> +       cn10k_outb_cpt_clean(pf);
> +}
> +EXPORT_SYMBOL(cn10k_ipsec_clean);
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
> new file mode 100644
> index 000000000000..b322e19d5e23
> --- /dev/null
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
> @@ -0,0 +1,104 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Marvell IPSEC offload driver
> + *
> + * Copyright (C) 2024 Marvell.
> + */
> +
> +#ifndef CN10K_IPSEC_H
> +#define CN10K_IPSEC_H
> +
> +#include <linux/types.h>
> +
> +/* CPT instruction size in bytes */
> +#define CN10K_CPT_INST_SIZE    64
> +
> +/* CPT instruction (CPT_INST_S) queue length */
> +#define CN10K_CPT_INST_QLEN    8200
> +
> +/* CPT instruction queue size passed to HW is in units of
> + * 40*CPT_INST_S messages.
> + */
> +#define CN10K_CPT_SIZE_DIV40 (CN10K_CPT_INST_QLEN / 40)
> +
> +/* CPT needs 320 free entries */
> +#define CN10K_CPT_INST_QLEN_EXTRA_BYTES        (320 * CN10K_CPT_INST_SIZE)
> +#define CN10K_CPT_EXTRA_SIZE_DIV40     (320 / 40)
> +
> +/* CPT instruction queue length in bytes */
> +#define CN10K_CPT_INST_QLEN_BYTES                                      \
> +               ((CN10K_CPT_SIZE_DIV40 * 40 * CN10K_CPT_INST_SIZE) +    \
> +               CN10K_CPT_INST_QLEN_EXTRA_BYTES)
> +
> +/* CPT instruction group queue length in bytes */
> +#define CN10K_CPT_INST_GRP_QLEN_BYTES                                  \
> +               ((CN10K_CPT_SIZE_DIV40 + CN10K_CPT_EXTRA_SIZE_DIV40) * 16)
> +
> +/* CPT FC length in bytes */
> +#define CN10K_CPT_Q_FC_LEN 128
> +
> +/* Default CPT engine group for inline ipsec */
> +#define CN10K_DEF_CPT_IPSEC_EGRP 1
> +
> +/* CN10K CPT LF registers */
> +#define CPT_LFBASE                     (BLKTYPE_CPT << RVU_FUNC_BLKADDR_SHIFT)
> +#define CN10K_CPT_LF_CTL               (CPT_LFBASE | 0x10)
> +#define CN10K_CPT_LF_INPROG            (CPT_LFBASE | 0x40)
> +#define CN10K_CPT_LF_Q_BASE            (CPT_LFBASE | 0xf0)
> +#define CN10K_CPT_LF_Q_SIZE            (CPT_LFBASE | 0x100)
> +#define CN10K_CPT_LF_Q_INST_PTR                (CPT_LFBASE | 0x110)
> +#define CN10K_CPT_LF_Q_GRP_PTR         (CPT_LFBASE | 0x120)
> +#define CN10K_CPT_LF_NQX(a)            (CPT_LFBASE | 0x400 | (a) << 3)
> +#define CN10K_CPT_LF_CTX_FLUSH         (CPT_LFBASE | 0x510)
> +
> +struct cn10k_cpt_inst_queue {
> +       u8 *vaddr;
> +       u8 *real_vaddr;
> +       dma_addr_t dma_addr;
> +       dma_addr_t real_dma_addr;
> +       u32 size;
> +};
> +
> +struct cn10k_ipsec {
> +       /* Outbound CPT */
> +       u64 io_addr;
> +       /* Lock to protect SA management */
> +       struct mutex lock;
> +       struct cn10k_cpt_inst_queue iq;
> +};
> +
> +/* CPT LF_INPROG Register */
> +#define CPT_LF_INPROG_INFLIGHT GENMASK_ULL(8, 0)
> +#define CPT_LF_INPROG_GRB_CNT  GENMASK_ULL(39, 32)
> +#define CPT_LF_INPROG_GWB_CNT  GENMASK_ULL(47, 40)
> +
> +/* CPT LF_Q_GRP_PTR Register */
> +#define CPT_LF_Q_GRP_PTR_DQ_PTR        GENMASK_ULL(14, 0)
> +#define CPT_LF_Q_GRP_PTR_NQ_PTR        GENMASK_ULL(46, 32)
> +
> +/* CPT LF_Q_SIZE Register */
> +#define CPT_LF_Q_BASE_ADDR GENMASK_ULL(52, 7)
> +
> +/* CPT LF_Q_SIZE Register */
> +#define CPT_LF_Q_SIZE_DIV40 GENMASK_ULL(14, 0)
> +
> +#ifdef CONFIG_XFRM_OFFLOAD
> +int cn10k_ipsec_init(struct net_device *netdev);
> +void cn10k_ipsec_clean(struct otx2_nic *pf);
> +int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable);
> +#else
> +static inline __maybe_unused int cn10k_ipsec_init(struct net_device *netdev)
> +{
> +       return 0;
> +}
> +
> +static inline __maybe_unused void cn10k_ipsec_clean(struct otx2_nic *pf)
> +{
> +}
> +
> +static inline __maybe_unused
> +int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable)
> +{
> +       return 0;
> +}
> +#endif
> +#endif // CN10K_IPSEC_H
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> index 42a759a33c11..859bbc78e653 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> @@ -29,6 +29,7 @@
>  #include "otx2_devlink.h"
>  #include <rvu_trace.h>
>  #include "qos.h"
> +#include "cn10k_ipsec.h"
>
>  /* IPv4 flag more fragment bit */
>  #define IPV4_FLAG_MORE                         0x20
> @@ -39,6 +40,7 @@
>  #define PCI_DEVID_OCTEONTX2_RVU_AFVF           0xA0F8
>
>  #define PCI_SUBSYS_DEVID_96XX_RVU_PFVF         0xB200
> +#define PCI_SUBSYS_DEVID_CN10K_A_RVU_PFVF      0xB900
>  #define PCI_SUBSYS_DEVID_CN10K_B_RVU_PFVF      0xBD00
>
>  /* PCI BAR nos */
> @@ -467,6 +469,7 @@ struct otx2_nic {
>  #define OTX2_FLAG_PTP_ONESTEP_SYNC             BIT_ULL(15)
>  #define OTX2_FLAG_ADPTV_INT_COAL_ENABLED BIT_ULL(16)
>  #define OTX2_FLAG_TC_MARK_ENABLED              BIT_ULL(17)
> +#define OTX2_FLAG_INLINE_IPSEC_ENABLED         BIT_ULL(18)
>         u64                     flags;
>         u64                     *cq_op_addr;
>
> @@ -534,6 +537,9 @@ struct otx2_nic {
>  #if IS_ENABLED(CONFIG_MACSEC)
>         struct cn10k_mcs_cfg    *macsec_cfg;
>  #endif
> +
> +       /* Inline ipsec */
> +       struct cn10k_ipsec      ipsec;
>  };
>
>  static inline bool is_otx2_lbkvf(struct pci_dev *pdev)
> @@ -578,6 +584,15 @@ static inline bool is_dev_cn10kb(struct pci_dev *pdev)
>         return pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_B_RVU_PFVF;
>  }
>
> +static inline bool is_dev_cn10ka_b0(struct pci_dev *pdev)
> +{
> +       if (pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_RVU_PFVF &&
> +           (pdev->revision & 0xFF) == 0x54)
> +               return true;
> +
> +       return false;
> +}
> +
>  static inline void otx2_setup_dev_hw_settings(struct otx2_nic *pfvf)
>  {
>         struct otx2_hw *hw = &pfvf->hw;
> @@ -627,6 +642,9 @@ static inline void __iomem *otx2_get_regaddr(struct otx2_nic *nic, u64 offset)
>         case BLKTYPE_NPA:
>                 blkaddr = BLKADDR_NPA;
>                 break;
> +       case BLKTYPE_CPT:
> +               blkaddr = BLKADDR_CPT0;
> +               break;
>         default:
>                 blkaddr = BLKADDR_RVUM;
>                 break;
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> index cbd5050f58e8..a7e17d870420 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> @@ -26,6 +26,7 @@
>  #include "cn10k.h"
>  #include "qos.h"
>  #include <rvu_trace.h>
> +#include "cn10k_ipsec.h"
>
>  #define DRV_NAME       "rvu_nicpf"
>  #define DRV_STRING     "Marvell RVU NIC Physical Function Driver"
> @@ -2201,6 +2202,10 @@ static int otx2_set_features(struct net_device *netdev,
>                 return otx2_enable_rxvlan(pf,
>                                           features & NETIF_F_HW_VLAN_CTAG_RX);
>
> +       if (changed & NETIF_F_HW_ESP)
> +               return cn10k_ipsec_ethtool_init(netdev,
> +                                               features & NETIF_F_HW_ESP);
> +
>         return otx2_handle_ntuple_tc_features(netdev, features);
>  }
>
> @@ -3065,10 +3070,14 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>         /* reset CGX/RPM MAC stats */
>         otx2_reset_mac_stats(pf);
>
> +       err = cn10k_ipsec_init(netdev);
> +       if (err)
> +               goto err_mcs_free;
> +
>         err = register_netdev(netdev);
>         if (err) {
>                 dev_err(dev, "Failed to register netdevice\n");
> -               goto err_mcs_free;
> +               goto err_ipsec_clean;
>         }
>
>         err = otx2_wq_init(pf);
> @@ -3109,6 +3118,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>         otx2_mcam_flow_del(pf);
>  err_unreg_netdev:
>         unregister_netdev(netdev);
> +err_ipsec_clean:
> +       cn10k_ipsec_clean(pf);
>  err_mcs_free:
>         cn10k_mcs_free(pf);
>  err_del_mcam_entries:
> @@ -3286,6 +3297,7 @@ static void otx2_remove(struct pci_dev *pdev)
>
>         otx2_unregister_dl(pf);
>         unregister_netdev(netdev);
> +       cn10k_ipsec_clean(pf);
>         cn10k_mcs_free(pf);
>         otx2_sriov_disable(pf->pdev);
>         otx2_sriov_vfcfg_cleanup(pf);
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
> index 99fcc5661674..6fc70c3cafb6 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
> @@ -14,6 +14,7 @@
>  #include "otx2_reg.h"
>  #include "otx2_ptp.h"
>  #include "cn10k.h"
> +#include "cn10k_ipsec.h"
>
>  #define DRV_NAME       "rvu_nicvf"
>  #define DRV_STRING     "Marvell RVU NIC Virtual Function Driver"
> @@ -682,10 +683,14 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>                 snprintf(netdev->name, sizeof(netdev->name), "lbk%d", n);
>         }
>
> +       err = cn10k_ipsec_init(netdev);
> +       if (err)
> +               goto err_ptp_destroy;
> +
>         err = register_netdev(netdev);
>         if (err) {
>                 dev_err(dev, "Failed to register netdevice\n");
> -               goto err_ptp_destroy;
> +               goto err_ipsec_clean;
>         }
>
>         err = otx2_wq_init(vf);
> @@ -719,6 +724,8 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>         otx2_shutdown_tc(vf);
>  err_unreg_netdev:
>         unregister_netdev(netdev);
> +err_ipsec_clean:
> +       cn10k_ipsec_clean(vf);
>  err_ptp_destroy:
>         otx2_ptp_destroy(vf);
>  err_detach_rsrc:
> @@ -771,6 +778,7 @@ static void otx2vf_remove(struct pci_dev *pdev)
>         unregister_netdev(netdev);
>         if (vf->otx2_wq)
>                 destroy_workqueue(vf->otx2_wq);
> +       cn10k_ipsec_clean(vf);
>         otx2_ptp_destroy(vf);
>         otx2_mcam_flow_del(vf);
>         otx2_shutdown_tc(vf);
> --
> 2.34.1
>
>


-- 
Regards,
Kalesh A P

Download attachment "smime.p7s" of type "application/pkcs7-signature" (4239 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ