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; }
/** * @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; }
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); }
/** * 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 }