Skip to content

Commit

Permalink
event/cnxk: add CN20K timer adapter
Browse files Browse the repository at this point in the history
Add event timer adapter support for CN20K platform.
Implement new HWWQE insertion feature supported by CN20K platform.

Signed-off-by: Pavan Nikhilesh <[email protected]>
  • Loading branch information
PavanNikhilesh authored and jerinjacobk committed Oct 30, 2024
1 parent f3c7b60 commit 822d4ef
Show file tree
Hide file tree
Showing 7 changed files with 350 additions and 12 deletions.
6 changes: 5 additions & 1 deletion drivers/common/cnxk/roc_tim.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ tim_hw_info_get(struct roc_tim *roc_tim)
mbox_alloc_msg_tim_get_hw_info(mbox);
rc = mbox_process_msg(mbox, (void **)&rsp);
if (rc && rc != MBOX_MSG_INVALID) {
plt_err("Failed to get SSO HW info");
plt_err("Failed to get TIM HW info");
rc = -EIO;
goto exit;
}
Expand Down Expand Up @@ -443,6 +443,10 @@ roc_tim_init(struct roc_tim *roc_tim)
nb_lfs = roc_tim->nb_lfs;

rc = tim_hw_info_get(roc_tim);
if (rc) {
plt_tim_dbg("Failed to get TIM HW info");
return 0;
}

rc = tim_free_lf_count_get(dev, &nb_free_lfs);
if (rc) {
Expand Down
16 changes: 15 additions & 1 deletion drivers/event/cnxk/cn20k_eventdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,13 @@ cn20k_sso_tx_adapter_queue_del(uint8_t id, const struct rte_eventdev *event_dev,
return cn20k_sso_updt_tx_adptr_data(event_dev);
}

static int
cn20k_tim_caps_get(const struct rte_eventdev *evdev, uint64_t flags, uint32_t *caps,
const struct event_timer_adapter_ops **ops)
{
return cnxk_tim_caps_get(evdev, flags, caps, ops, cn20k_sso_set_priv_mem);
}

static struct eventdev_ops cn20k_sso_dev_ops = {
.dev_infos_get = cn20k_sso_info_get,
.dev_configure = cn20k_sso_dev_configure,
Expand Down Expand Up @@ -991,6 +998,8 @@ static struct eventdev_ops cn20k_sso_dev_ops = {
.eth_tx_adapter_stop = cnxk_sso_tx_adapter_stop,
.eth_tx_adapter_free = cnxk_sso_tx_adapter_free,

.timer_adapter_caps_get = cn20k_tim_caps_get,

.xstats_get = cnxk_sso_xstats_get,
.xstats_reset = cnxk_sso_xstats_reset,
.xstats_get_names = cnxk_sso_xstats_get_names,
Expand Down Expand Up @@ -1068,4 +1077,9 @@ RTE_PMD_REGISTER_PARAM_STRING(event_cn20k,
CNXK_SSO_XAE_CNT "=<int>"
CNXK_SSO_GGRP_QOS "=<string>"
CNXK_SSO_STASH "=<string>"
CNXK_SSO_FORCE_BP "=1");
CNXK_SSO_FORCE_BP "=1"
CNXK_TIM_DISABLE_NPA "=1"
CNXK_TIM_CHNK_SLOTS "=<int>"
CNXK_TIM_RINGS_LMT "=<int>"
CNXK_TIM_STATS_ENA "=1"
CNXK_TIM_EXT_CLK "=<string>");
6 changes: 6 additions & 0 deletions drivers/event/cnxk/cn20k_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef __CN20K_WORKER_H__
#define __CN20K_WORKER_H__

#include <rte_event_timer_adapter.h>
#include <rte_eventdev.h>

#include "cn20k_eventdev.h"
Expand Down Expand Up @@ -128,6 +129,11 @@ cn20k_sso_hws_post_process(struct cn20k_sso_hws *ws, uint64_t *u64, const uint32
/* Mark vector mempool object as get */
RTE_MEMPOOL_CHECK_COOKIES(rte_mempool_from_obj((void *)u64[1]), (void **)&u64[1], 1,
1);
} else if (CNXK_EVENT_TYPE_FROM_TAG(u64[0]) == RTE_EVENT_TYPE_TIMER) {
struct rte_event_timer *tev = (struct rte_event_timer *)u64[1];

tev->state = RTE_EVENT_TIMER_NOT_ARMED;
u64[1] = tev->ev.u64;
}
}

Expand Down
37 changes: 36 additions & 1 deletion drivers/event/cnxk/cnxk_tim_evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,25 @@ cnxk_tim_chnk_pool_create(struct cnxk_tim_ring *tim_ring,
return rc;
}

static int
cnxk_tim_enable_hwwqe(struct cnxk_tim_evdev *dev, struct cnxk_tim_ring *tim_ring)
{
struct roc_tim_hwwqe_cfg hwwqe_cfg;

memset(&hwwqe_cfg, 0, sizeof(hwwqe_cfg));
hwwqe_cfg.hwwqe_ena = 1;
hwwqe_cfg.grp_ena = 0;
hwwqe_cfg.flw_ctrl_ena = 0;
hwwqe_cfg.result_offset = CNXK_TIM_HWWQE_RES_OFFSET_B;

tim_ring->lmt_base = dev->tim.roc_sso->lmt_base;
return roc_tim_lf_config_hwwqe(&dev->tim, tim_ring->ring_id, &hwwqe_cfg);
}

static void
cnxk_tim_set_fp_ops(struct cnxk_tim_ring *tim_ring)
{
struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
uint8_t prod_flag = !tim_ring->prod_type_sp;

/* [STATS] [DFB/FB] [SP][MP]*/
Expand All @@ -98,6 +114,16 @@ cnxk_tim_set_fp_ops(struct cnxk_tim_ring *tim_ring)
#undef FP
};

if (dev == NULL)
return;

if (dev->tim.feat.hwwqe) {
cnxk_tim_ops.arm_burst = cnxk_tim_arm_burst_hwwqe;
cnxk_tim_ops.arm_tmo_tick_burst = cnxk_tim_arm_tmo_burst_hwwqe;
cnxk_tim_ops.cancel_burst = cnxk_tim_timer_cancel_burst_hwwqe;
return;
}

cnxk_tim_ops.arm_burst =
arm_burst[tim_ring->enable_stats][tim_ring->ena_dfb][prod_flag];
cnxk_tim_ops.arm_tmo_tick_burst =
Expand Down Expand Up @@ -224,12 +250,13 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
}
}

if (tim_ring->disable_npa) {
if (!dev->tim.feat.hwwqe && tim_ring->disable_npa) {
tim_ring->nb_chunks =
tim_ring->nb_timers /
CNXK_TIM_NB_CHUNK_SLOTS(tim_ring->chunk_sz);
tim_ring->nb_chunks = tim_ring->nb_chunks * tim_ring->nb_bkts;
} else {
tim_ring->disable_npa = 0;
tim_ring->nb_chunks = tim_ring->nb_timers;
}

Expand All @@ -255,6 +282,14 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
goto tim_chnk_free;
}

if (dev->tim.feat.hwwqe) {
rc = cnxk_tim_enable_hwwqe(dev, tim_ring);
if (rc < 0) {
plt_err("Failed to enable hwwqe");
goto tim_chnk_free;
}
}

plt_write64((uint64_t)tim_ring->bkt, tim_ring->base + TIM_LF_RING_BASE);
plt_write64(tim_ring->aura, tim_ring->base + TIM_LF_RING_AURA);

Expand Down
14 changes: 14 additions & 0 deletions drivers/event/cnxk/cnxk_tim_evdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <rte_malloc.h>
#include <rte_memzone.h>
#include <rte_reciprocal.h>
#include <rte_vect.h>

#define NSECPERSEC 1E9
#define USECPERSEC 1E6
Expand All @@ -29,6 +30,8 @@
#define CNXK_TIM_MIN_CHUNK_SLOTS (0x1)
#define CNXK_TIM_MAX_CHUNK_SLOTS (0x1FFE)
#define CNXK_TIM_MAX_POOL_CACHE_SZ (16)
#define CNXK_TIM_HWWQE_RES_OFFSET_B (24)
#define CNXK_TIM_ENT_PER_LMT (7)

#define CN9K_TIM_MIN_TMO_TKS (256)

Expand Down Expand Up @@ -124,6 +127,7 @@ struct __rte_cache_aligned cnxk_tim_ring {
uintptr_t tbase;
uint64_t (*tick_fn)(uint64_t tbase);
uint64_t ring_start_cyc;
uint64_t lmt_base;
struct cnxk_tim_bkt *bkt;
struct rte_mempool *chunk_pool;
struct rte_reciprocal_u64 fast_div;
Expand Down Expand Up @@ -310,11 +314,21 @@ TIM_ARM_FASTPATH_MODES
TIM_ARM_TMO_FASTPATH_MODES
#undef FP

uint16_t cnxk_tim_arm_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint16_t nb_timers);

uint16_t cnxk_tim_arm_tmo_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint64_t timeout_tick,
const uint16_t nb_timers);

uint16_t
cnxk_tim_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim,
const uint16_t nb_timers);

uint16_t cnxk_tim_timer_cancel_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint16_t nb_timers);

int cnxk_tim_remaining_ticks_get(const struct rte_event_timer_adapter *adapter,
const struct rte_event_timer *evtim, uint64_t *ticks_remaining);

Expand Down
82 changes: 73 additions & 9 deletions drivers/event/cnxk/cnxk_tim_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,6 @@ cnxk_tim_arm_checks(const struct cnxk_tim_ring *const tim_ring,
return -EINVAL;
}

static inline void
cnxk_tim_format_event(const struct rte_event_timer *const tim,
struct cnxk_tim_ent *const entry)
{
entry->w0 = (tim->ev.event & 0xFFC000000000) >> 6 |
(tim->ev.event & 0xFFFFFFFFF);
entry->wqe = tim->ev.u64;
}

static __rte_always_inline uint16_t
cnxk_tim_timer_arm_burst(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint16_t nb_timers,
Expand Down Expand Up @@ -77,6 +68,24 @@ cnxk_tim_timer_arm_burst(const struct rte_event_timer_adapter *adptr,
return index;
}

uint16_t
cnxk_tim_arm_burst_hwwqe(const struct rte_event_timer_adapter *adptr, struct rte_event_timer **tim,
const uint16_t nb_timers)
{
struct cnxk_tim_ring *tim_ring = adptr->data->adapter_priv;
uint16_t index;

for (index = 0; index < nb_timers; index++) {
if (cnxk_tim_arm_checks(tim_ring, tim[index]))
break;

if (cnxk_tim_add_entry_hwwqe(tim_ring, tim[index]))
break;
}

return index;
}

#define FP(_name, _f3, _f2, _f1, _flags) \
uint16_t __rte_noinline cnxk_tim_arm_burst_##_name( \
const struct rte_event_timer_adapter *adptr, \
Expand Down Expand Up @@ -132,6 +141,29 @@ cnxk_tim_timer_arm_tmo_brst(const struct rte_event_timer_adapter *adptr,
return set_timers;
}

uint16_t
cnxk_tim_arm_tmo_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint64_t timeout_tick,
const uint16_t nb_timers)
{
struct cnxk_tim_ring *tim_ring = adptr->data->adapter_priv;
uint16_t idx;

if (unlikely(!timeout_tick || timeout_tick > tim_ring->nb_bkts)) {
const enum rte_event_timer_state state = timeout_tick ?
RTE_EVENT_TIMER_ERROR_TOOLATE :
RTE_EVENT_TIMER_ERROR_TOOEARLY;
for (idx = 0; idx < nb_timers; idx++)
tim[idx]->state = state;

rte_errno = EINVAL;
return 0;
}

return cnxk_tim_add_entry_tmo_hwwqe(tim_ring, tim, timeout_tick * tim_ring->tck_int,
nb_timers);
}

#define FP(_name, _f2, _f1, _flags) \
uint16_t __rte_noinline cnxk_tim_arm_tmo_tick_burst_##_name( \
const struct rte_event_timer_adapter *adptr, \
Expand Down Expand Up @@ -174,6 +206,38 @@ cnxk_tim_timer_cancel_burst(const struct rte_event_timer_adapter *adptr,
return index;
}

uint16_t
cnxk_tim_timer_cancel_burst_hwwqe(const struct rte_event_timer_adapter *adptr,
struct rte_event_timer **tim, const uint16_t nb_timers)
{
uint64_t __rte_atomic *status;
uint16_t i;

RTE_SET_USED(adptr);
for (i = 0; i < nb_timers; i++) {
if (tim[i]->state == RTE_EVENT_TIMER_CANCELED) {
rte_errno = EALREADY;
break;
}

if (tim[i]->state != RTE_EVENT_TIMER_ARMED) {
rte_errno = EINVAL;
break;
}

status = (uint64_t __rte_atomic *)&tim[i]->impl_opaque[1];
if (!rte_atomic_compare_exchange_strong_explicit(status, (uint64_t *)&tim[i], 0,
rte_memory_order_release,
rte_memory_order_relaxed)) {
rte_errno = ENOENT;
break;
}
tim[i]->state = RTE_EVENT_TIMER_CANCELED;
}

return i;
}

int
cnxk_tim_remaining_ticks_get(const struct rte_event_timer_adapter *adapter,
const struct rte_event_timer *evtim, uint64_t *ticks_remaining)
Expand Down
Loading

0 comments on commit 822d4ef

Please sign in to comment.