Exemplo n.º 1
0
static void cvm_oct_configure_common_hw(void)
{
	/* Setup the FPA */
	cvmx_fpa_enable();
	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
			     num_packet_buffers);
	cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
			     num_packet_buffers);
	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
		cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
				     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 1024);

#ifdef __LITTLE_ENDIAN
	{
		union cvmx_ipd_ctl_status ipd_ctl_status;

		ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
		ipd_ctl_status.s.pkt_lend = 1;
		ipd_ctl_status.s.wqe_lend = 1;
		cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
	}
#endif

	cvmx_helper_setup_red(num_packet_buffers / 4, num_packet_buffers / 8);
}
/**
 * @INTERNAL
 * Allocate memory and initialize the FPA pools using memory
 * from cvmx-bootmem. Specifying zero for the number of
 * buffers will cause that FPA pool to not be setup. This is
 * useful if you aren't using some of the hardware and want
 * to save memory. Use cvmx_helper_initialize_fpa instead of
 * this function directly.
 *
 * @param pip_pool Should always be CVMX_FPA_PACKET_POOL
 * @param pip_size Should always be CVMX_FPA_PACKET_POOL_SIZE
 * @param pip_buffers
 *                 Number of packet buffers.
 * @param wqe_pool Should always be CVMX_FPA_WQE_POOL
 * @param wqe_size Should always be CVMX_FPA_WQE_POOL_SIZE
 * @param wqe_entries
 *                 Number of work queue entries
 * @param pko_pool Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
 * @param pko_size Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
 * @param pko_buffers
 *                 PKO Command buffers. You should at minimum have two per
 *                 each PKO queue.
 * @param tim_pool Should always be CVMX_FPA_TIMER_POOL
 * @param tim_size Should always be CVMX_FPA_TIMER_POOL_SIZE
 * @param tim_buffers
 *                 TIM ring buffer command queues. At least two per timer bucket
 *                 is recommended.
 * @param dfa_pool Should always be CVMX_FPA_DFA_POOL
 * @param dfa_size Should always be CVMX_FPA_DFA_POOL_SIZE
 * @param dfa_buffers
 *                 DFA command buffer. A relatively small (32 for example)
 *                 number should work.
 * @return Zero on success, non-zero if out of memory
 */
static int
__cvmx_helper_initialize_fpa(int pip_pool, int pip_size, int pip_buffers,
			     int wqe_pool, int wqe_size, int wqe_entries,
			     int pko_pool, int pko_size, int pko_buffers,
			     int tim_pool, int tim_size, int tim_buffers,
			     int dfa_pool, int dfa_size, int dfa_buffers)
{
	int status;
#define __init_fpa_pool(pool, size, buffers, str)                              \
	if (pool >= 0) {                                                       \
		status = __cvmx_helper_initialize_fpa_pool(pool, size, buffers,\
							   str);	       \
		if (status)						       \
			return status;                                         \
	}

	cvmx_fpa_enable();

	if ((pip_buffers > 0) && (pip_buffers <= 64))
		cvmx_dprintf("Warning: %d packet buffers may not be enough for"
			     "hardware prefetch. 65 or more is recommended.\n",
			     pip_buffers);

	__init_fpa_pool(pip_pool, pip_size, pip_buffers, "Packet Buffers");
	__init_fpa_pool(wqe_pool, wqe_size, wqe_entries, "Work Q Entries");
	__init_fpa_pool(pko_pool, pko_size, pko_buffers, "PKO Cmd Buffers");
	__init_fpa_pool(tim_pool, tim_size, tim_buffers, "TIM Cmd Buffers");
	__init_fpa_pool(dfa_pool, dfa_size, dfa_buffers, "DFA Cmd Buffers");

	return 0;
}
Exemplo n.º 3
0
/**
 * @INTERNAL
 * Allocate memory and initialize the FPA pools using memory
 * from cvmx-bootmem. Specifying zero for the number of
 * buffers will cause that FPA pool to not be setup. This is
 * useful if you aren't using some of the hardware and want
 * to save memory. Use cvmx_helper_initialize_fpa instead of
 * this function directly.
 *
 * @param pip_pool Should always be CVMX_FPA_PACKET_POOL
 * @param pip_size Should always be CVMX_FPA_PACKET_POOL_SIZE
 * @param pip_buffers
 *                 Number of packet buffers.
 * @param wqe_pool Should always be CVMX_FPA_WQE_POOL
 * @param wqe_size Should always be CVMX_FPA_WQE_POOL_SIZE
 * @param wqe_entries
 *                 Number of work queue entries
 * @param pko_pool Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
 * @param pko_size Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
 * @param pko_buffers
 *                 PKO Command buffers. You should at minimum have two per
 *                 each PKO queue.
 * @param tim_pool Should always be CVMX_FPA_TIMER_POOL
 * @param tim_size Should always be CVMX_FPA_TIMER_POOL_SIZE
 * @param tim_buffers
 *                 TIM ring buffer command queues. At least two per timer bucket
 *                 is recommened.
 * @param dfa_pool Should always be CVMX_FPA_DFA_POOL
 * @param dfa_size Should always be CVMX_FPA_DFA_POOL_SIZE
 * @param dfa_buffers
 *                 DFA command buffer. A relatively small (32 for example)
 *                 number should work.
 * @return Zero on success, non-zero if out of memory
 */
static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size, int pip_buffers,
                                        int wqe_pool, int wqe_size, int wqe_entries,
                                        int pko_pool, int pko_size, int pko_buffers,
                                        int tim_pool, int tim_size, int tim_buffers,
                                        int dfa_pool, int dfa_size, int dfa_buffers)
{
    int status;

    cvmx_fpa_enable();

    if ((pip_buffers > 0) && (pip_buffers <= 64))
        cvmx_dprintf("Warning: %d packet buffers may not be enough for hardware"
                     " prefetch. 65 or more is recommended.\n", pip_buffers);

    if (pip_pool >= 0)
    {
        status = __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size, pip_buffers,
                                                 "Packet Buffers");
        if (status)
            return status;
    }

    if (wqe_pool >= 0)
    {
        status = __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size, wqe_entries,
                                                 "Work Queue Entries");
        if (status)
            return status;
    }

    if (pko_pool >= 0)
    {
        status = __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size, pko_buffers,
                                                 "PKO Command Buffers");
        if (status)
            return status;
    }

    if (tim_pool >= 0)
    {
        status = __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size, tim_buffers,
                                                 "TIM Command Buffers");
        if (status)
            return status;
    }

    if (dfa_pool >= 0)
    {
        status = __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size, dfa_buffers,
                                                 "DFA Command Buffers");
        if (status)
            return status;
    }

    return 0;
}
Exemplo n.º 4
0
static __init void cvm_oct_configure_common_hw(void)
{
	/* Setup the FPA */
	cvmx_fpa_enable();
	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
			     num_packet_buffers);
	cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
			     num_packet_buffers);
	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
		cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
				     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);

	if (USE_RED)
		cvmx_helper_setup_red(num_packet_buffers / 4,
				      num_packet_buffers / 8);

}
Exemplo n.º 5
0
/**
 * Configure common hardware for all interfaces
 */
static void cvm_oct_configure_common_hw(device_t bus)
{
	struct octebus_softc *sc;
	int pko_queues;
	int error;
	int rid;

        sc = device_get_softc(bus);

	/* Setup the FPA */
	cvmx_fpa_enable();
	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
			     num_packet_buffers);
	cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
			     num_packet_buffers);
	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) {
		/*
		 * If the FPA uses different pools for output buffers and
		 * packets, size the output buffer pool based on the number
		 * of PKO queues.
		 */
		if (OCTEON_IS_MODEL(OCTEON_CN38XX))
			pko_queues = 128;
		else if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
			pko_queues = 32;
		else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
			pko_queues = 32;
		else
			pko_queues = 256;

		cvm_oct_num_output_buffers = 4 * pko_queues;
		cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
				     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
				     cvm_oct_num_output_buffers);
	}

	if (USE_RED)
		cvmx_helper_setup_red(num_packet_buffers/4,
				      num_packet_buffers/8);

	/* Enable the MII interface */
	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM)
		cvmx_write_csr(CVMX_SMI_EN, 1);

	/* Register an IRQ hander for to receive POW interrupts */
        rid = 0;
        sc->sc_rx_irq = bus_alloc_resource(bus, SYS_RES_IRQ, &rid,
					   OCTEON_IRQ_WORKQ0 + pow_receive_group,
					   OCTEON_IRQ_WORKQ0 + pow_receive_group,
					   1, RF_ACTIVE);
        if (sc->sc_rx_irq == NULL) {
                device_printf(bus, "could not allocate workq irq");
		return;
        }

        error = bus_setup_intr(bus, sc->sc_rx_irq, INTR_TYPE_NET | INTR_MPSAFE,
			       cvm_oct_do_interrupt, NULL, cvm_oct_device,
			       &sc->sc_rx_intr_cookie);
        if (error != 0) {
                device_printf(bus, "could not setup workq irq");
		return;
        }


#ifdef SMP
	{
		cvmx_ciu_intx0_t en;
		int core;

		CPU_FOREACH(core) {
			if (core == PCPU_GET(cpuid))
				continue;

			en.u64 = cvmx_read_csr(CVMX_CIU_INTX_EN0(core*2));
			en.s.workq |= (1<<pow_receive_group);
			cvmx_write_csr(CVMX_CIU_INTX_EN0(core*2), en.u64);
		}
	}
#endif
}