-/* $OpenBSD: cn30xxpow.c,v 1.15 2017/11/18 11:27:37 visa Exp $ */
+/* $OpenBSD: cn30xxpow.c,v 1.16 2017/12/05 15:26:47 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h> /* hz */
-#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/octeonvar.h>
#include <octeon/dev/iobusvar.h>
-#include <octeon/dev/cn30xxciureg.h> /* XXX */
#include <octeon/dev/cn30xxpowreg.h>
#include <octeon/dev/cn30xxpowvar.h>
-struct cn30xxpow_intr_handle {
- void *pi_ih;
- struct cn30xxpow_softc *pi_sc;
- int pi_group;
- void (*pi_cb)(void *, uint64_t *);
- void *pi_data;
-};
-
void cn30xxpow_bootstrap(struct octeon_config *);
void cn30xxpow_init(struct cn30xxpow_softc *);
void cn30xxpow_init_regs(struct cn30xxpow_softc *);
-void cn30xxpow_config_int_pc(struct cn30xxpow_softc *, int);
void cn30xxpow_config_int(struct cn30xxpow_softc *, int,
uint64_t, uint64_t, uint64_t);
-void cn30xxpow_intr_work(struct cn30xxpow_softc *,
- struct cn30xxpow_intr_handle *, int);
-int cn30xxpow_intr(void *);
-/* XXX */
struct cn30xxpow_softc cn30xxpow_softc;
-/*
- * XXX: parameter tuning is needed: see files.octeon
- */
-#ifndef OCTEON_ETH_RING_MAX
-#define OCTEON_ETH_RING_MAX 512
-#endif
-#ifndef OCTEON_ETH_RING_MIN
-#define OCTEON_ETH_RING_MIN 1
-#endif
-
-#ifdef OCTEON_ETH_INTR_FEEDBACK_RING
-int max_recv_cnt = OCTEON_ETH_RING_MAX;
-int min_recv_cnt = OCTEON_ETH_RING_MIN;
-int recv_cnt = OCTEON_ETH_RING_MIN;
-int int_rate = 1;
-#else
-/* infinity */
-int max_recv_cnt = 0;
-int min_recv_cnt = 0;
-int recv_cnt = 0;
-#endif
-
/* -------------------------------------------------------------------------- */
/* ---- operation primitive functions */
0x00); /* IQ */
}
-void *
-cn30xxpow_intr_establish(int group, int level,
- void (*cb)(void *, uint64_t *), void (*fcb)(int*, int *, uint64_t, void *),
- void *data, char *what)
-{
- struct cn30xxpow_intr_handle *pow_ih;
-
- KASSERT(group >= 0);
- KASSERT(group < 16);
-
- pow_ih = malloc(sizeof(*pow_ih), M_DEVBUF, M_NOWAIT);
- if (pow_ih == NULL)
- return NULL;
-
- pow_ih->pi_ih = octeon_intr_establish(
- ffs64(CIU_INTX_SUM0_WORKQ_0) - 1 + group,
- level,
- cn30xxpow_intr, pow_ih, what);
- KASSERT(pow_ih->pi_ih != NULL);
-
- pow_ih->pi_sc = &cn30xxpow_softc;
- pow_ih->pi_group = group;
- pow_ih->pi_cb = cb;
- pow_ih->pi_data = data;
-
- return pow_ih;
-}
-
void
cn30xxpow_init(struct cn30xxpow_softc *sc)
{
if (status != 0)
panic("can't map %s space", "pow register");
}
-
-/* -------------------------------------------------------------------------- */
-
-/* ---- interrupt handling */
-
-/*
- * Interrupt handling by fixed count.
- *
- * XXX the fixed count (MAX_RX_CNT) could be changed dynamically?
- *
- * XXX this does not utilize "tag switch" very well
- */
-/*
- * usually all packet recieve
- */
-#define MAX_RX_CNT 0x7fffffff
-
-void
-cn30xxpow_intr_work(struct cn30xxpow_softc *sc,
- struct cn30xxpow_intr_handle *pow_ih, int max_recv_cnt)
-{
- uint64_t *work;
- uint64_t count = 0;
- uint32_t coreid = octeon_get_coreid();
- int recv_cnt = MAX_RX_CNT;
-
- _POW_WR8(sc, POW_PP_GRP_MSK_OFFSET(coreid), 1ULL << pow_ih->pi_group);
-
- if (max_recv_cnt > 0)
- recv_cnt = max_recv_cnt - 1;
-
- cn30xxpow_tag_sw_wait();
- cn30xxpow_work_request_async(OCTEON_CVMSEG_OFFSET(csm_pow_intr),
- POW_NO_WAIT);
-
- for (count = 0; count < recv_cnt; count++) {
- work = (uint64_t *)cn30xxpow_work_response_async(
- OCTEON_CVMSEG_OFFSET(csm_pow_intr));
- if (work == NULL)
- return;
- cn30xxpow_tag_sw_wait();
- cn30xxpow_work_request_async(
- OCTEON_CVMSEG_OFFSET(csm_pow_intr), POW_NO_WAIT);
- (*pow_ih->pi_cb)(pow_ih->pi_data, work);
- }
-
- work = (uint64_t *)cn30xxpow_work_response_async(
- OCTEON_CVMSEG_OFFSET(csm_pow_intr));
- if (work == NULL)
- return;
-
- (*pow_ih->pi_cb)(pow_ih->pi_data, work);
-}
-
-int
-cn30xxpow_intr(void *data)
-{
- struct cn30xxpow_intr_handle *pow_ih = data;
- struct cn30xxpow_softc *sc = pow_ih->pi_sc;
- uint64_t wq_int_mask = 0x1ULL << pow_ih->pi_group;
-
- cn30xxpow_intr_work(sc, pow_ih, recv_cnt);
-
- _POW_WR8(sc, POW_WQ_INT_OFFSET, wq_int_mask << POW_WQ_INT_WQ_INT_SHIFT);
- return 1;
-}
-/* $OpenBSD: cn30xxpowvar.h,v 1.4 2017/11/18 11:27:37 visa Exp $ */
+/* $OpenBSD: cn30xxpowvar.h,v 1.5 2017/12/05 15:26:47 visa Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
};
void cn30xxpow_config(struct cn30xxpow_softc *, int);
-void *cn30xxpow_intr_establish(int, int,
- void (*)(void *, uint64_t *),
- void (*)(int *, int *, uint64_t, void *),
- void *, char *);
-void cn30xxpow_error_int_enable(void *, int);
-uint64_t cn30xxpow_error_int_summary(void *);
-int cn30xxpow_ring_reduce(void *);
-int cn30xxpow_ring_grow(void *);
-int cn30xxpow_ring_size(void);
-int cn30xxpow_ring_intr(void);
#define _POW_RD8(sc, off) \
bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))