memset(ws, 0, sizeof(*ws));
}
-static void
+static int
cn10k_sso_hws_flush_events(void *hws, uint8_t queue_id, uintptr_t base,
cnxk_handle_event_t fn, void *arg)
{
+ uint64_t retry = CNXK_SSO_FLUSH_RETRY_MAX;
struct cn10k_sso_hws *ws = hws;
uint64_t cq_ds_cnt = 1;
uint64_t aq_cnt = 1;
while (aq_cnt || cq_ds_cnt || ds_cnt) {
plt_write64(req, ws->base + SSOW_LF_GWS_OP_GET_WORK0);
- cn10k_sso_hws_get_work_empty(ws, &ev);
+ cn10k_sso_hws_get_work_empty(
+ ws, &ev,
+ (NIX_RX_OFFLOAD_MAX - 1) | NIX_RX_REAS_F |
+ NIX_RX_MULTI_SEG_F | CPT_RX_WQE_F);
if (fn != NULL && ev.u64 != 0)
fn(arg, ev);
if (ev.sched_type != SSO_TT_EMPTY)
- cnxk_sso_hws_swtag_flush(
- ws->base + SSOW_LF_GWS_WQE0,
- ws->base + SSOW_LF_GWS_OP_SWTAG_FLUSH);
+ cnxk_sso_hws_swtag_flush(ws->base);
+ else if (retry-- == 0)
+ break;
do {
val = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
} while (val & BIT_ULL(56));
cq_ds_cnt &= 0x3FFF3FFF0000;
}
+ if (aq_cnt || cq_ds_cnt || ds_cnt)
+ return -EAGAIN;
+
plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
rte_mb();
+
+ return 0;
}
static void
uint64_t u64[2];
} gw;
uint8_t pend_tt;
+ bool is_pend;
plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
/* Wait till getwork/swtp/waitw/desched completes. */
+ is_pend = false;
+ /* Work in WQE0 is always consumed, unless its a SWTAG. */
+ pend_state = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
+ if (pend_state & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(54)) ||
+ ws->swtag_req)
+ is_pend = true;
+
do {
pend_state = plt_read64(base + SSOW_LF_GWS_PENDSTATE);
} while (pend_state & (BIT_ULL(63) | BIT_ULL(62) | BIT_ULL(58) |
BIT_ULL(56) | BIT_ULL(54)));
pend_tt = CNXK_TT_FROM_TAG(plt_read64(base + SSOW_LF_GWS_WQE0));
- if (pend_tt != SSO_TT_EMPTY) { /* Work was pending */
+ if (is_pend && pend_tt != SSO_TT_EMPTY) { /* Work was pending */
if (pend_tt == SSO_TT_ATOMIC || pend_tt == SSO_TT_ORDERED)
cnxk_sso_hws_swtag_untag(base +
SSOW_LF_GWS_OP_SWTAG_UNTAG);
switch (dev->gw_mode) {
case CN10K_GW_MODE_PREF:
+ case CN10K_GW_MODE_PREF_WFE:
while (plt_read64(base + SSOW_LF_GWS_PRF_WQE0) & BIT_ULL(63))
;
break;
- case CN10K_GW_MODE_PREF_WFE:
- while (plt_read64(base + SSOW_LF_GWS_PRF_WQE0) &
- SSOW_LF_GWS_TAG_PEND_GET_WORK_BIT)
- continue;
- plt_write64(0, base + SSOW_LF_GWS_OP_GWC_INVAL);
- break;
case CN10K_GW_MODE_NONE:
default:
break;
rte_free(gws_cookie);
}
+static void
+cn10k_sso_port_quiesce(struct rte_eventdev *event_dev, void *port,
+ rte_eventdev_port_flush_t flush_cb, void *args)
+{
+ struct cnxk_sso_evdev *dev = cnxk_sso_pmd_priv(event_dev);
+ struct cn10k_sso_hws *ws = port;
+ struct rte_event ev;
+ uint64_t ptag;
+ bool is_pend;
+
+ is_pend = false;
+ /* Work in WQE0 is always consumed, unless its a SWTAG. */
+ ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
+ if (ptag & (BIT_ULL(62) | BIT_ULL(54)) || ws->swtag_req)
+ is_pend = true;
+ do {
+ ptag = plt_read64(ws->base + SSOW_LF_GWS_PENDSTATE);
+ } while (ptag &
+ (BIT_ULL(62) | BIT_ULL(58) | BIT_ULL(56) | BIT_ULL(54)));
+
+ cn10k_sso_hws_get_work_empty(ws, &ev,
+ (NIX_RX_OFFLOAD_MAX - 1) | NIX_RX_REAS_F |
+ NIX_RX_MULTI_SEG_F | CPT_RX_WQE_F);
+ if (is_pend && ev.u64) {
+ if (flush_cb)
+ flush_cb(event_dev->data->dev_id, ev, args);
+ cnxk_sso_hws_swtag_flush(ws->base);
+ }
+
+ /* Check if we have work in PRF_WQE0, if so extract it. */
+ switch (dev->gw_mode) {
+ case CN10K_GW_MODE_PREF:
+ case CN10K_GW_MODE_PREF_WFE:
+ while (plt_read64(ws->base + SSOW_LF_GWS_PRF_WQE0) &
+ BIT_ULL(63))
+ ;
+ break;
+ case CN10K_GW_MODE_NONE:
+ default:
+ break;
+ }
+
+ if (CNXK_TT_FROM_TAG(plt_read64(ws->base + SSOW_LF_GWS_PRF_WQE0)) !=
+ SSO_TT_EMPTY) {
+ plt_write64(BIT_ULL(16) | 1,
+ ws->base + SSOW_LF_GWS_OP_GET_WORK0);
+ cn10k_sso_hws_get_work_empty(
+ ws, &ev,
+ (NIX_RX_OFFLOAD_MAX - 1) | NIX_RX_REAS_F |
+ NIX_RX_MULTI_SEG_F | CPT_RX_WQE_F);
+ if (ev.u64) {
+ if (flush_cb)
+ flush_cb(event_dev->data->dev_id, ev, args);
+ cnxk_sso_hws_swtag_flush(ws->base);
+ }
+ }
+ ws->swtag_req = 0;
+ plt_write64(0, ws->base + SSOW_LF_GWS_OP_GWC_INVAL);
+}
+
static int
cn10k_sso_port_link(struct rte_eventdev *event_dev, void *port,
const uint8_t queues[], const uint8_t priorities[],
return 0;
}
+static void
+cn10k_sso_txq_fc_update(const struct rte_eth_dev *eth_dev, int32_t tx_queue_id)
+{
+ struct cnxk_eth_dev *cnxk_eth_dev = eth_dev->data->dev_private;
+ struct cn10k_eth_txq *txq;
+ struct roc_nix_sq *sq;
+ int i;
+
+ if (tx_queue_id < 0) {
+ for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
+ cn10k_sso_txq_fc_update(eth_dev, i);
+ } else {
+ uint16_t sqes_per_sqb;
+
+ sq = &cnxk_eth_dev->sqs[tx_queue_id];
+ txq = eth_dev->data->tx_queues[tx_queue_id];
+ sqes_per_sqb = 1U << txq->sqes_per_sqb_log2;
+ sq->nb_sqb_bufs_adj =
+ sq->nb_sqb_bufs -
+ RTE_ALIGN_MUL_CEIL(sq->nb_sqb_bufs, sqes_per_sqb) /
+ sqes_per_sqb;
+ if (cnxk_eth_dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY)
+ sq->nb_sqb_bufs_adj -= (cnxk_eth_dev->outb.nb_desc /
+ (sqes_per_sqb - 1));
+ txq->nb_sqb_bufs_adj = sq->nb_sqb_bufs_adj;
+ txq->nb_sqb_bufs_adj = (70 * txq->nb_sqb_bufs_adj) / 100;
+ }
+}
+
static int
cn10k_sso_tx_adapter_queue_add(uint8_t id, const struct rte_eventdev *event_dev,
const struct rte_eth_dev *eth_dev,
}
dev->tx_offloads |= tx_offloads;
+ cn10k_sso_txq_fc_update(eth_dev, tx_queue_id);
rc = cn10k_sso_updt_tx_adptr_data(event_dev);
if (rc < 0)
return rc;
static struct eventdev_ops cn10k_sso_dev_ops = {
.dev_infos_get = cn10k_sso_info_get,
.dev_configure = cn10k_sso_dev_configure,
+
.queue_def_conf = cnxk_sso_queue_def_conf,
.queue_setup = cnxk_sso_queue_setup,
.queue_release = cnxk_sso_queue_release,
+ .queue_attr_get = cnxk_sso_queue_attribute_get,
+ .queue_attr_set = cnxk_sso_queue_attribute_set,
+
.port_def_conf = cnxk_sso_port_def_conf,
.port_setup = cn10k_sso_port_setup,
.port_release = cn10k_sso_port_release,
+ .port_quiesce = cn10k_sso_port_quiesce,
.port_link = cn10k_sso_port_link,
.port_unlink = cn10k_sso_port_unlink,
.timeout_ticks = cnxk_sso_timeout_ticks,
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KA, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KAS, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF10KA, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
+ CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KB, PCI_DEVID_CNXK_RVU_SSO_TIM_PF),
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KA, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KAS, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF10KA, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
+ CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KB, PCI_DEVID_CNXK_RVU_SSO_TIM_VF),
{
.vendor_id = 0,
},