From bcf30d28120c09fd31e7d7728cfcefb712a55676 Mon Sep 17 00:00:00 2001 From: jmallett Date: Wed, 16 Mar 2011 08:51:36 +0000 Subject: o) Clean up FPA pools on module unload. o) Allocate output buffer pool based on available output queues. Submitted by: Bhanu Prakash (with modifications) --- sys/contrib/octeon-sdk/cvmx-fpa.h | 13 +++++++ sys/mips/cavium/octe/ethernet.c | 55 +++++++++++++++++++++++----- sys/mips/cavium/octe/wrapper-cvmx-includes.h | 1 + 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/sys/contrib/octeon-sdk/cvmx-fpa.h b/sys/contrib/octeon-sdk/cvmx-fpa.h index 88de805..b9671a8 100644 --- a/sys/contrib/octeon-sdk/cvmx-fpa.h +++ b/sys/contrib/octeon-sdk/cvmx-fpa.h @@ -154,6 +154,19 @@ static inline void cvmx_fpa_enable(void) } /** + * Reset FPA to disable. Make sure buffers from all FPA pools are freed + * before disabling FPA. + */ +static inline void cvmx_fpa_disable(void) +{ + cvmx_fpa_ctl_status_t status; + + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS); + status.s.reset = 1; + cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64); +} + +/** * Get a new block from the FPA * * @param pool Pool to get the block from diff --git a/sys/mips/cavium/octe/ethernet.c b/sys/mips/cavium/octe/ethernet.c index 710336f..1b69354 100644 --- a/sys/mips/cavium/octe/ethernet.c +++ b/sys/mips/cavium/octe/ethernet.c @@ -98,6 +98,11 @@ struct ifnet *cvm_oct_device[TOTAL_NUMBER_OF_PORTS]; */ static struct taskqueue *cvm_oct_link_taskq; +/* + * Number of buffers in output buffer pool. + */ +static int cvm_oct_num_output_buffers; + /** * Function to update link status. */ @@ -185,13 +190,13 @@ static void cvm_do_timer(void *arg) } } - /** * 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; @@ -199,13 +204,34 @@ static void cvm_oct_configure_common_hw(device_t 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) - cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); + 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); + cvmx_helper_setup_red(num_packet_buffers/4, + num_packet_buffers/8); /* Enable the MII interface */ if (!octeon_is_simulation()) @@ -303,11 +329,13 @@ int cvm_oct_init_module(device_t bus) int num_ports = cvmx_helper_ports_on_interface(interface); int port; - for (port = cvmx_helper_get_ipd_port(interface, 0); port < cvmx_helper_get_ipd_port(interface, num_ports); port++) { + for (port = 0; port < num_ports; port++) { cvmx_pip_prt_tagx_t pip_prt_tagx; - pip_prt_tagx.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(port)); + int pkind = cvmx_helper_get_ipd_port(interface, port); + + pip_prt_tagx.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(pkind)); pip_prt_tagx.s.grp = pow_receive_group; - cvmx_write_csr(CVMX_PIP_PRT_TAGX(port), pip_prt_tagx.u64); + cvmx_write_csr(CVMX_PIP_PRT_TAGX(pkind), pip_prt_tagx.u64); } } @@ -475,4 +503,13 @@ void cvm_oct_cleanup_module(void) cvm_oct_device[port] = NULL; } } + /* Free the HW pools */ + cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, num_packet_buffers); + cvm_oct_mem_empty_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_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, cvm_oct_num_output_buffers); + + /* Disable FPA, all buffers are free, not done by helper shutdown. */ + cvmx_fpa_disable(); } diff --git a/sys/mips/cavium/octe/wrapper-cvmx-includes.h b/sys/mips/cavium/octe/wrapper-cvmx-includes.h index f59a924..a3bb651 100644 --- a/sys/mips/cavium/octe/wrapper-cvmx-includes.h +++ b/sys/mips/cavium/octe/wrapper-cvmx-includes.h @@ -45,5 +45,6 @@ AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR W #include #include #include +#include #endif -- cgit v1.1