From patchwork Tue Apr 6 14:40:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nithin Dabilpuram X-Patchwork-Id: 90682 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4BAABA0546; Tue, 6 Apr 2021 16:43:16 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C371E14104B; Tue, 6 Apr 2021 16:42:18 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id C596F14103F for ; Tue, 6 Apr 2021 16:42:16 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 136Ee7dO000967 for ; Tue, 6 Apr 2021 07:42:16 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=tbMrHpy3bS+nj7Adc18asdEl9ubICdq3ypP9bt4Q/Ic=; b=HnyuEjondlomm8jCDkQohkEim2D2C8ntXcU9cTEio/IBdEZu7611P7yquvSbH5R6wkKt NfIQCAAW7wpvzfQ4OM6paBdrIH15dxeMsFjeU9QdMagwxkVu7m0AsBHjYzFdjP6VCMH8 +WjgytOt45eknEUVXDMjmF18wPo7sWoExG1qdiByPYjjDY7vmeA4tPw6WnHAeR9EiBzL qJYq6YxhgWayRaRmXrPH14wePhJHx7LknPkHcVEt7k3L0ExQS4+fVLiP4Tr4fQwgsexR cv61ggJLR/erw8XtaUrt/kXlDW5ES7SIDRU7dCVr3poXs1VD5JCMgWFgrzAuQrwTZTCl xw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com with ESMTP id 37r72p30bg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Tue, 06 Apr 2021 07:42:15 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 6 Apr 2021 07:42:14 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 6 Apr 2021 07:42:14 -0700 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id DB8713F7040; Tue, 6 Apr 2021 07:42:11 -0700 (PDT) From: Nithin Dabilpuram To: CC: , , , , , , Date: Tue, 6 Apr 2021 20:10:59 +0530 Message-ID: <20210406144144.19925-8-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20210406144144.19925-1-ndabilpuram@marvell.com> References: <20210305133918.8005-1-ndabilpuram@marvell.com> <20210406144144.19925-1-ndabilpuram@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: RA8eyqW_DRlJC3GW-36zeEGZFDT9en0s X-Proofpoint-ORIG-GUID: RA8eyqW_DRlJC3GW-36zeEGZFDT9en0s X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.761 definitions=2021-04-06_03:2021-04-01, 2021-04-06 signatures=0 Subject: [dpdk-dev] [PATCH v5 07/52] common/cnxk: add mailbox base infra X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Jerin Jacob This patch adds mailbox infra API's to communicate with Kernel AF driver. These API's will be used by all the other cnxk drivers for mbox init/fini, send/recv functionality. Signed-off-by: Jerin Jacob --- drivers/common/cnxk/meson.build | 1 + drivers/common/cnxk/roc_dev_priv.h | 3 + drivers/common/cnxk/roc_mbox.c | 483 ++++++++++++++++++++++++++++++++++++ drivers/common/cnxk/roc_mbox_priv.h | 215 ++++++++++++++++ drivers/common/cnxk/roc_platform.c | 1 + drivers/common/cnxk/roc_platform.h | 3 + drivers/common/cnxk/roc_priv.h | 3 + drivers/common/cnxk/roc_utils.c | 7 + drivers/common/cnxk/roc_utils.h | 2 + drivers/common/cnxk/version.map | 2 + 10 files changed, 720 insertions(+) create mode 100644 drivers/common/cnxk/roc_mbox.c create mode 100644 drivers/common/cnxk/roc_mbox_priv.h diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build index 3e0678d..a7e7968 100644 --- a/drivers/common/cnxk/meson.build +++ b/drivers/common/cnxk/meson.build @@ -11,6 +11,7 @@ endif config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON' deps = ['eal', 'pci', 'bus_pci', 'mbuf'] sources = files('roc_irq.c', + 'roc_mbox.c', 'roc_model.c', 'roc_platform.c', 'roc_utils.c') diff --git a/drivers/common/cnxk/roc_dev_priv.h b/drivers/common/cnxk/roc_dev_priv.h index 2254677..c7f79f7 100644 --- a/drivers/common/cnxk/roc_dev_priv.h +++ b/drivers/common/cnxk/roc_dev_priv.h @@ -5,6 +5,9 @@ #ifndef _ROC_DEV_PRIV_H #define _ROC_DEV_PRIV_H +extern uint16_t dev_rclk_freq; +extern uint16_t dev_sclk_freq; + int dev_irq_register(struct plt_intr_handle *intr_handle, plt_intr_callback_fn cb, void *data, unsigned int vec); void dev_irq_unregister(struct plt_intr_handle *intr_handle, diff --git a/drivers/common/cnxk/roc_mbox.c b/drivers/common/cnxk/roc_mbox.c new file mode 100644 index 0000000..6f4ee68 --- /dev/null +++ b/drivers/common/cnxk/roc_mbox.c @@ -0,0 +1,483 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include +#include + +#include "roc_api.h" +#include "roc_priv.h" + +#define RVU_AF_AFPF_MBOX0 (0x02000) +#define RVU_AF_AFPF_MBOX1 (0x02008) + +#define RVU_PF_PFAF_MBOX0 (0xC00) +#define RVU_PF_PFAF_MBOX1 (0xC08) + +#define RVU_PF_VFX_PFVF_MBOX0 (0x0000) +#define RVU_PF_VFX_PFVF_MBOX1 (0x0008) + +#define RVU_VF_VFPF_MBOX0 (0x0000) +#define RVU_VF_VFPF_MBOX1 (0x0008) + +/* RCLK, SCLK in MHz */ +uint16_t dev_rclk_freq; +uint16_t dev_sclk_freq; + +static inline uint16_t +msgs_offset(void) +{ + return PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); +} + +void +mbox_fini(struct mbox *mbox) +{ + mbox->reg_base = 0; + mbox->hwbase = 0; + plt_free(mbox->dev); + mbox->dev = NULL; +} + +void +mbox_reset(struct mbox *mbox, int devid) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + struct mbox_hdr *tx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->tx_start); + struct mbox_hdr *rx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start); + + plt_spinlock_lock(&mdev->mbox_lock); + mdev->msg_size = 0; + mdev->rsp_size = 0; + tx_hdr->msg_size = 0; + tx_hdr->num_msgs = 0; + rx_hdr->msg_size = 0; + rx_hdr->num_msgs = 0; + plt_spinlock_unlock(&mdev->mbox_lock); +} + +int +mbox_init(struct mbox *mbox, uintptr_t hwbase, uintptr_t reg_base, + int direction, int ndevs, uint64_t intr_offset) +{ + struct mbox_dev *mdev; + char *var, *var_to; + int devid; + + mbox->intr_offset = intr_offset; + mbox->reg_base = reg_base; + mbox->hwbase = hwbase; + + switch (direction) { + case MBOX_DIR_AFPF: + case MBOX_DIR_PFVF: + mbox->tx_start = MBOX_DOWN_TX_START; + mbox->rx_start = MBOX_DOWN_RX_START; + mbox->tx_size = MBOX_DOWN_TX_SIZE; + mbox->rx_size = MBOX_DOWN_RX_SIZE; + break; + case MBOX_DIR_PFAF: + case MBOX_DIR_VFPF: + mbox->tx_start = MBOX_DOWN_RX_START; + mbox->rx_start = MBOX_DOWN_TX_START; + mbox->tx_size = MBOX_DOWN_RX_SIZE; + mbox->rx_size = MBOX_DOWN_TX_SIZE; + break; + case MBOX_DIR_AFPF_UP: + case MBOX_DIR_PFVF_UP: + mbox->tx_start = MBOX_UP_TX_START; + mbox->rx_start = MBOX_UP_RX_START; + mbox->tx_size = MBOX_UP_TX_SIZE; + mbox->rx_size = MBOX_UP_RX_SIZE; + break; + case MBOX_DIR_PFAF_UP: + case MBOX_DIR_VFPF_UP: + mbox->tx_start = MBOX_UP_RX_START; + mbox->rx_start = MBOX_UP_TX_START; + mbox->tx_size = MBOX_UP_RX_SIZE; + mbox->rx_size = MBOX_UP_TX_SIZE; + break; + default: + return -ENODEV; + } + + switch (direction) { + case MBOX_DIR_AFPF: + case MBOX_DIR_AFPF_UP: + mbox->trigger = RVU_AF_AFPF_MBOX0; + mbox->tr_shift = 4; + break; + case MBOX_DIR_PFAF: + case MBOX_DIR_PFAF_UP: + mbox->trigger = RVU_PF_PFAF_MBOX1; + mbox->tr_shift = 0; + break; + case MBOX_DIR_PFVF: + case MBOX_DIR_PFVF_UP: + mbox->trigger = RVU_PF_VFX_PFVF_MBOX0; + mbox->tr_shift = 12; + break; + case MBOX_DIR_VFPF: + case MBOX_DIR_VFPF_UP: + mbox->trigger = RVU_VF_VFPF_MBOX1; + mbox->tr_shift = 0; + break; + default: + return -ENODEV; + } + + mbox->dev = plt_zmalloc(ndevs * sizeof(struct mbox_dev), ROC_ALIGN); + if (!mbox->dev) { + mbox_fini(mbox); + return -ENOMEM; + } + mbox->ndevs = ndevs; + for (devid = 0; devid < ndevs; devid++) { + mdev = &mbox->dev[devid]; + mdev->mbase = (void *)(mbox->hwbase + (devid * MBOX_SIZE)); + plt_spinlock_init(&mdev->mbox_lock); + /* Init header to reset value */ + mbox_reset(mbox, devid); + } + + var = getenv("ROC_CN10K_MBOX_TIMEOUT"); + var_to = getenv("ROC_MBOX_TIMEOUT"); + + if (var) + mbox->rsp_tmo = atoi(var); + else if (var_to) + mbox->rsp_tmo = atoi(var_to); + else + mbox->rsp_tmo = MBOX_RSP_TIMEOUT; + + return 0; +} + +/** + * @internal + * Allocate a message response + */ +struct mbox_msghdr * +mbox_alloc_msg_rsp(struct mbox *mbox, int devid, int size, int size_rsp) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + struct mbox_msghdr *msghdr = NULL; + + plt_spinlock_lock(&mdev->mbox_lock); + size = PLT_ALIGN(size, MBOX_MSG_ALIGN); + size_rsp = PLT_ALIGN(size_rsp, MBOX_MSG_ALIGN); + /* Check if there is space in mailbox */ + if ((mdev->msg_size + size) > mbox->tx_size - msgs_offset()) + goto exit; + if ((mdev->rsp_size + size_rsp) > mbox->rx_size - msgs_offset()) + goto exit; + if (mdev->msg_size == 0) + mdev->num_msgs = 0; + mdev->num_msgs++; + + msghdr = (struct mbox_msghdr *)(((uintptr_t)mdev->mbase + + mbox->tx_start + msgs_offset() + + mdev->msg_size)); + + /* Clear the whole msg region */ + mbox_memset(msghdr, 0, sizeof(*msghdr) + size); + /* Init message header with reset values */ + msghdr->ver = MBOX_VERSION; + mdev->msg_size += size; + mdev->rsp_size += size_rsp; + msghdr->next_msgoff = mdev->msg_size + msgs_offset(); +exit: + plt_spinlock_unlock(&mdev->mbox_lock); + + return msghdr; +} + +/** + * @internal + * Send a mailbox message + */ +void +mbox_msg_send(struct mbox *mbox, int devid) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + struct mbox_hdr *tx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->tx_start); + struct mbox_hdr *rx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start); + + /* Reset header for next messages */ + tx_hdr->msg_size = mdev->msg_size; + mdev->msg_size = 0; + mdev->rsp_size = 0; + mdev->msgs_acked = 0; + + /* num_msgs != 0 signals to the peer that the buffer has a number of + * messages. So this should be written after copying txmem + */ + tx_hdr->num_msgs = mdev->num_msgs; + rx_hdr->num_msgs = 0; + + /* Sync mbox data into memory */ + plt_wmb(); + + /* The interrupt should be fired after num_msgs is written + * to the shared memory + */ + plt_write64(1, (volatile void *)(mbox->reg_base + + (mbox->trigger | + (devid << mbox->tr_shift)))); +} + +/** + * @internal + * Wait and get mailbox response + */ +int +mbox_get_rsp(struct mbox *mbox, int devid, void **msg) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + struct mbox_msghdr *msghdr; + uint64_t offset; + int rc; + + rc = mbox_wait_for_rsp(mbox, devid); + if (rc < 0) + return -EIO; + + plt_rmb(); + + offset = mbox->rx_start + + PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); + msghdr = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset); + if (msg != NULL) + *msg = msghdr; + + return msghdr->rc; +} + +/** + * Polling for given wait time to get mailbox response + */ +static int +mbox_poll(struct mbox *mbox, uint32_t wait) +{ + uint32_t timeout = 0, sleep = 1; + uint32_t wait_us = wait * 1000; + uint64_t rsp_reg = 0; + uintptr_t reg_addr; + + reg_addr = mbox->reg_base + mbox->intr_offset; + do { + rsp_reg = plt_read64(reg_addr); + + if (timeout >= wait_us) + return -ETIMEDOUT; + + plt_delay_us(sleep); + timeout += sleep; + } while (!rsp_reg); + + plt_rmb(); + + /* Clear interrupt */ + plt_write64(rsp_reg, reg_addr); + + /* Reset mbox */ + mbox_reset(mbox, 0); + + return 0; +} + +/** + * @internal + * Wait and get mailbox response with timeout + */ +int +mbox_get_rsp_tmo(struct mbox *mbox, int devid, void **msg, uint32_t tmo) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + struct mbox_msghdr *msghdr; + uint64_t offset; + int rc; + + rc = mbox_wait_for_rsp_tmo(mbox, devid, tmo); + if (rc != 1) + return -EIO; + + plt_rmb(); + + offset = mbox->rx_start + + PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); + msghdr = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset); + if (msg != NULL) + *msg = msghdr; + + return msghdr->rc; +} + +static int +mbox_wait(struct mbox *mbox, int devid, uint32_t rst_timo) +{ + volatile struct mbox_dev *mdev = &mbox->dev[devid]; + uint32_t timeout = 0, sleep = 1; + + rst_timo = rst_timo * 1000; /* Milli seconds to micro seconds */ + while (mdev->num_msgs > mdev->msgs_acked) { + plt_delay_us(sleep); + timeout += sleep; + if (timeout >= rst_timo) { + struct mbox_hdr *tx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + + mbox->tx_start); + struct mbox_hdr *rx_hdr = + (struct mbox_hdr *)((uintptr_t)mdev->mbase + + mbox->rx_start); + + plt_err("MBOX[devid: %d] message wait timeout %d, " + "num_msgs: %d, msgs_acked: %d " + "(tx/rx num_msgs: %d/%d), msg_size: %d, " + "rsp_size: %d", + devid, timeout, mdev->num_msgs, + mdev->msgs_acked, tx_hdr->num_msgs, + rx_hdr->num_msgs, mdev->msg_size, + mdev->rsp_size); + + return -EIO; + } + plt_rmb(); + } + return 0; +} + +int +mbox_wait_for_rsp_tmo(struct mbox *mbox, int devid, uint32_t tmo) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + int rc = 0; + + /* Sync with mbox region */ + plt_rmb(); + + if (mbox->trigger == RVU_PF_VFX_PFVF_MBOX1 || + mbox->trigger == RVU_PF_VFX_PFVF_MBOX0) { + /* In case of VF, Wait a bit more to account round trip delay */ + tmo = tmo * 2; + } + + /* Wait message */ + if (plt_thread_is_intr()) + rc = mbox_poll(mbox, tmo); + else + rc = mbox_wait(mbox, devid, tmo); + + if (!rc) + rc = mdev->num_msgs; + + return rc; +} + +/** + * @internal + * Wait for the mailbox response + */ +int +mbox_wait_for_rsp(struct mbox *mbox, int devid) +{ + return mbox_wait_for_rsp_tmo(mbox, devid, mbox->rsp_tmo); +} + +int +mbox_get_availmem(struct mbox *mbox, int devid) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + int avail; + + plt_spinlock_lock(&mdev->mbox_lock); + avail = mbox->tx_size - mdev->msg_size - msgs_offset(); + plt_spinlock_unlock(&mdev->mbox_lock); + + return avail; +} + +int +send_ready_msg(struct mbox *mbox, uint16_t *pcifunc) +{ + struct ready_msg_rsp *rsp; + int rc; + + mbox_alloc_msg_ready(mbox); + + rc = mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; + + if (rsp->hdr.ver != MBOX_VERSION) { + plt_err("Incompatible MBox versions(AF: 0x%04x Client: 0x%04x)", + rsp->hdr.ver, MBOX_VERSION); + return -EPIPE; + } + + if (pcifunc) + *pcifunc = rsp->hdr.pcifunc; + + /* Save rclk & sclk freq */ + if (!dev_rclk_freq || !dev_sclk_freq) { + dev_rclk_freq = rsp->rclk_freq; + dev_sclk_freq = rsp->sclk_freq; + } + return 0; +} + +int +reply_invalid_msg(struct mbox *mbox, int devid, uint16_t pcifunc, uint16_t id) +{ + struct msg_rsp *rsp; + + rsp = (struct msg_rsp *)mbox_alloc_msg(mbox, devid, sizeof(*rsp)); + if (!rsp) + return -ENOMEM; + rsp->hdr.id = id; + rsp->hdr.sig = MBOX_RSP_SIG; + rsp->hdr.rc = MBOX_MSG_INVALID; + rsp->hdr.pcifunc = pcifunc; + + return 0; +} + +/** + * @internal + * Convert mail box ID to name + */ +const char * +mbox_id2name(uint16_t id) +{ + switch (id) { + default: + return "INVALID ID"; +#define M(_name, _id, _1, _2, _3) \ + case _id: \ + return #_name; + MBOX_MESSAGES + MBOX_UP_CGX_MESSAGES +#undef M + } +} + +int +mbox_id2size(uint16_t id) +{ + switch (id) { + default: + return 0; +#define M(_1, _id, _2, _req_type, _3) \ + case _id: \ + return sizeof(struct _req_type); + MBOX_MESSAGES + MBOX_UP_CGX_MESSAGES +#undef M + } +} diff --git a/drivers/common/cnxk/roc_mbox_priv.h b/drivers/common/cnxk/roc_mbox_priv.h new file mode 100644 index 0000000..84516fb --- /dev/null +++ b/drivers/common/cnxk/roc_mbox_priv.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef __ROC_MBOX_PRIV_H__ +#define __ROC_MBOX_PRIV_H__ + +#include +#include +#include + +#define SZ_64K (64ULL * 1024ULL) +#define SZ_1K (1ULL * 1024ULL) +#define MBOX_SIZE SZ_64K + +/* AF/PF: PF initiated, PF/VF VF initiated */ +#define MBOX_DOWN_RX_START 0 +#define MBOX_DOWN_RX_SIZE (46 * SZ_1K) +#define MBOX_DOWN_TX_START (MBOX_DOWN_RX_START + MBOX_DOWN_RX_SIZE) +#define MBOX_DOWN_TX_SIZE (16 * SZ_1K) +/* AF/PF: AF initiated, PF/VF PF initiated */ +#define MBOX_UP_RX_START (MBOX_DOWN_TX_START + MBOX_DOWN_TX_SIZE) +#define MBOX_UP_RX_SIZE SZ_1K +#define MBOX_UP_TX_START (MBOX_UP_RX_START + MBOX_UP_RX_SIZE) +#define MBOX_UP_TX_SIZE SZ_1K + +#if MBOX_UP_TX_SIZE + MBOX_UP_TX_START != MBOX_SIZE +#error "Incorrect mailbox area sizes" +#endif + +#define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull)) + +#define MBOX_RSP_TIMEOUT 3000 /* Time to wait for mbox response in ms */ + +#define MBOX_MSG_ALIGN 16 /* Align mbox msg start to 16bytes */ + +/* Mailbox directions */ +#define MBOX_DIR_AFPF 0 /* AF replies to PF */ +#define MBOX_DIR_PFAF 1 /* PF sends messages to AF */ +#define MBOX_DIR_PFVF 2 /* PF replies to VF */ +#define MBOX_DIR_VFPF 3 /* VF sends messages to PF */ +#define MBOX_DIR_AFPF_UP 4 /* AF sends messages to PF */ +#define MBOX_DIR_PFAF_UP 5 /* PF replies to AF */ +#define MBOX_DIR_PFVF_UP 6 /* PF sends messages to VF */ +#define MBOX_DIR_VFPF_UP 7 /* VF replies to PF */ + +struct mbox_dev { + void *mbase; /* This dev's mbox region */ + plt_spinlock_t mbox_lock; + uint16_t msg_size; /* Total msg size to be sent */ + uint16_t rsp_size; /* Total rsp size to be sure the reply is ok */ + uint16_t num_msgs; /* No of msgs sent or waiting for response */ + uint16_t msgs_acked; /* No of msgs for which response is received */ +}; + +struct mbox { + uintptr_t hwbase; /* Mbox region advertised by HW */ + uintptr_t reg_base; /* CSR base for this dev */ + uint64_t trigger; /* Trigger mbox notification */ + uint16_t tr_shift; /* Mbox trigger shift */ + uint64_t rx_start; /* Offset of Rx region in mbox memory */ + uint64_t tx_start; /* Offset of Tx region in mbox memory */ + uint16_t rx_size; /* Size of Rx region */ + uint16_t tx_size; /* Size of Tx region */ + uint16_t ndevs; /* The number of peers */ + struct mbox_dev *dev; + uint64_t intr_offset; /* Offset to interrupt register */ + uint32_t rsp_tmo; +}; + +const char *mbox_id2name(uint16_t id); +int mbox_id2size(uint16_t id); +void mbox_reset(struct mbox *mbox, int devid); +int mbox_init(struct mbox *mbox, uintptr_t hwbase, uintptr_t reg_base, + int direction, int ndevsi, uint64_t intr_offset); +void mbox_fini(struct mbox *mbox); +void mbox_msg_send(struct mbox *mbox, int devid); +int mbox_wait_for_rsp(struct mbox *mbox, int devid); +int mbox_wait_for_rsp_tmo(struct mbox *mbox, int devid, uint32_t tmo); +int mbox_get_rsp(struct mbox *mbox, int devid, void **msg); +int mbox_get_rsp_tmo(struct mbox *mbox, int devid, void **msg, uint32_t tmo); +int mbox_get_availmem(struct mbox *mbox, int devid); +struct mbox_msghdr *mbox_alloc_msg_rsp(struct mbox *mbox, int devid, int size, + int size_rsp); + +static inline struct mbox_msghdr * +mbox_alloc_msg(struct mbox *mbox, int devid, int size) +{ + return mbox_alloc_msg_rsp(mbox, devid, size, 0); +} + +static inline void +mbox_req_init(uint16_t mbox_id, void *msghdr) +{ + struct mbox_msghdr *hdr = msghdr; + + hdr->sig = MBOX_REQ_SIG; + hdr->ver = MBOX_VERSION; + hdr->id = mbox_id; + hdr->pcifunc = 0; +} + +static inline void +mbox_rsp_init(uint16_t mbox_id, void *msghdr) +{ + struct mbox_msghdr *hdr = msghdr; + + hdr->sig = MBOX_RSP_SIG; + hdr->rc = -ETIMEDOUT; + hdr->id = mbox_id; +} + +static inline bool +mbox_nonempty(struct mbox *mbox, int devid) +{ + struct mbox_dev *mdev = &mbox->dev[devid]; + bool ret; + + plt_spinlock_lock(&mdev->mbox_lock); + ret = mdev->num_msgs != 0; + plt_spinlock_unlock(&mdev->mbox_lock); + + return ret; +} + +static inline int +mbox_process(struct mbox *mbox) +{ + mbox_msg_send(mbox, 0); + return mbox_get_rsp(mbox, 0, NULL); +} + +static inline int +mbox_process_msg(struct mbox *mbox, void **msg) +{ + mbox_msg_send(mbox, 0); + return mbox_get_rsp(mbox, 0, msg); +} + +static inline int +mbox_process_tmo(struct mbox *mbox, uint32_t tmo) +{ + mbox_msg_send(mbox, 0); + return mbox_get_rsp_tmo(mbox, 0, NULL, tmo); +} + +static inline int +mbox_process_msg_tmo(struct mbox *mbox, void **msg, uint32_t tmo) +{ + mbox_msg_send(mbox, 0); + return mbox_get_rsp_tmo(mbox, 0, msg, tmo); +} + +int send_ready_msg(struct mbox *mbox, uint16_t *pf_func /* out */); +int reply_invalid_msg(struct mbox *mbox, int devid, uint16_t pf_func, + uint16_t id); + +#define M(_name, _id, _fn_name, _req_type, _rsp_type) \ + static inline struct _req_type *mbox_alloc_msg_##_fn_name( \ + struct mbox *mbox) \ + { \ + struct _req_type *req; \ + req = (struct _req_type *)mbox_alloc_msg_rsp( \ + mbox, 0, sizeof(struct _req_type), \ + sizeof(struct _rsp_type)); \ + if (!req) \ + return NULL; \ + req->hdr.sig = MBOX_REQ_SIG; \ + req->hdr.id = _id; \ + plt_mbox_dbg("id=0x%x (%s)", req->hdr.id, \ + mbox_id2name(req->hdr.id)); \ + return req; \ + } + +MBOX_MESSAGES +#undef M + +/* This is required for copy operations from device memory which do not work on + * addresses which are unaligned to 16B. This is because of specific + * optimizations to libc memcpy. + */ +static inline volatile void * +mbox_memcpy(volatile void *d, const volatile void *s, size_t l) +{ + const volatile uint8_t *sb; + volatile uint8_t *db; + size_t i; + + if (!d || !s) + return NULL; + db = (volatile uint8_t *)d; + sb = (const volatile uint8_t *)s; + for (i = 0; i < l; i++) + db[i] = sb[i]; + return d; +} + +/* This is required for memory operations from device memory which do not + * work on addresses which are unaligned to 16B. This is because of specific + * optimizations to libc memset. + */ +static inline void +mbox_memset(volatile void *d, uint8_t val, size_t l) +{ + volatile uint8_t *db; + size_t i = 0; + + if (!d || !l) + return; + db = (volatile uint8_t *)d; + for (i = 0; i < l; i++) + db[i] = val; +} + +#endif /* __ROC_MBOX_PRIV_H__ */ diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c index 0c352f8..4147f59 100644 --- a/drivers/common/cnxk/roc_platform.c +++ b/drivers/common/cnxk/roc_platform.c @@ -57,3 +57,4 @@ roc_plt_init(void) } RTE_LOG_REGISTER(cnxk_logtype_base, pmd.cnxk.base, NOTICE); +RTE_LOG_REGISTER(cnxk_logtype_mbox, pmd.cnxk.mbox, NOTICE); diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h index 5675359..84c2da4 100644 --- a/drivers/common/cnxk/roc_platform.h +++ b/drivers/common/cnxk/roc_platform.h @@ -133,6 +133,8 @@ /* Log */ extern int cnxk_logtype_base; +extern int cnxk_logtype_mbox; + #define plt_err(fmt, args...) \ RTE_LOG(ERR, PMD, "%s():%u " fmt "\n", __func__, __LINE__, ##args) #define plt_info(fmt, args...) RTE_LOG(INFO, PMD, fmt "\n", ##args) @@ -148,6 +150,7 @@ extern int cnxk_logtype_base; ##args) #define plt_base_dbg(fmt, ...) plt_dbg(base, fmt, ##__VA_ARGS__) +#define plt_mbox_dbg(fmt, ...) plt_dbg(mbox, fmt, ##__VA_ARGS__) #ifdef __cplusplus #define CNXK_PCI_ID(subsystem_dev, dev) \ diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h index cd87035..c385f11 100644 --- a/drivers/common/cnxk/roc_priv.h +++ b/drivers/common/cnxk/roc_priv.h @@ -8,6 +8,9 @@ /* Utils */ #include "roc_util_priv.h" +/* Mbox */ +#include "roc_mbox_priv.h" + /* Dev */ #include "roc_dev_priv.h" diff --git a/drivers/common/cnxk/roc_utils.c b/drivers/common/cnxk/roc_utils.c index c48f027..b21064a 100644 --- a/drivers/common/cnxk/roc_utils.c +++ b/drivers/common/cnxk/roc_utils.c @@ -33,3 +33,10 @@ roc_error_msg_get(int errorcode) return err_msg; } + +void +roc_clk_freq_get(uint16_t *rclk_freq, uint16_t *sclk_freq) +{ + *rclk_freq = dev_rclk_freq; + *sclk_freq = dev_sclk_freq; +} diff --git a/drivers/common/cnxk/roc_utils.h b/drivers/common/cnxk/roc_utils.h index 634810e..32d44ae 100644 --- a/drivers/common/cnxk/roc_utils.h +++ b/drivers/common/cnxk/roc_utils.h @@ -10,4 +10,6 @@ /* Utils */ const char *__roc_api roc_error_msg_get(int errorcode); +void __roc_api roc_clk_freq_get(uint16_t *rclk_freq, uint16_t *sclk_freq); + #endif /* _ROC_UTILS_H_ */ diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index e2cb838..8ea8e95 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -2,6 +2,8 @@ INTERNAL { global: cnxk_logtype_base; + cnxk_logtype_mbox; + roc_clk_freq_get; roc_error_msg_get; roc_model; roc_plt_init;