1210284Sjmallett/***********************license start*************** 2232812Sjmallett * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 3215990Sjmallett * reserved. 4210284Sjmallett * 5210284Sjmallett * 6215990Sjmallett * Redistribution and use in source and binary forms, with or without 7215990Sjmallett * modification, are permitted provided that the following conditions are 8215990Sjmallett * met: 9210284Sjmallett * 10215990Sjmallett * * Redistributions of source code must retain the above copyright 11215990Sjmallett * notice, this list of conditions and the following disclaimer. 12210284Sjmallett * 13215990Sjmallett * * Redistributions in binary form must reproduce the above 14215990Sjmallett * copyright notice, this list of conditions and the following 15215990Sjmallett * disclaimer in the documentation and/or other materials provided 16215990Sjmallett * with the distribution. 17215990Sjmallett 18232812Sjmallett * * Neither the name of Cavium Inc. nor the names of 19215990Sjmallett * its contributors may be used to endorse or promote products 20215990Sjmallett * derived from this software without specific prior written 21215990Sjmallett * permission. 22215990Sjmallett 23215990Sjmallett * This Software, including technical data, may be subject to U.S. export control 24215990Sjmallett * laws, including the U.S. Export Administration Act and its associated 25215990Sjmallett * regulations, and may be subject to export or import regulations in other 26215990Sjmallett * countries. 27215990Sjmallett 28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38210284Sjmallett ***********************license end**************************************/ 39210284Sjmallett 40210284Sjmallett 41210284Sjmallett 42210284Sjmallett 43210284Sjmallett 44210284Sjmallett 45215990Sjmallett 46210284Sjmallett/** 47210284Sjmallett * @file 48210284Sjmallett * 49210284Sjmallett * Helper functions for FPA setup. 50210284Sjmallett * 51232812Sjmallett * <hr>$Revision: 70030 $<hr> 52210284Sjmallett */ 53210284Sjmallett#include "cvmx.h" 54210284Sjmallett#include "cvmx-bootmem.h" 55210284Sjmallett#include "cvmx-fpa.h" 56210284Sjmallett#include "cvmx-helper-fpa.h" 57210284Sjmallett 58210284Sjmallett/** 59210284Sjmallett * @INTERNAL 60210284Sjmallett * Allocate memory for and initialize a single FPA pool. 61210284Sjmallett * 62210284Sjmallett * @param pool Pool to initialize 63210284Sjmallett * @param buffer_size Size of buffers to allocate in bytes 64210284Sjmallett * @param buffers Number of buffers to put in the pool. Zero is allowed 65210284Sjmallett * @param name String name of the pool for debugging purposes 66210284Sjmallett * @return Zero on success, non-zero on failure 67210284Sjmallett */ 68210284Sjmallettstatic int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size, 69210284Sjmallett uint64_t buffers, const char *name) 70210284Sjmallett{ 71210284Sjmallett uint64_t current_num; 72210284Sjmallett void *memory; 73210284Sjmallett uint64_t align = CVMX_CACHE_LINE_SIZE; 74210284Sjmallett 75210284Sjmallett /* Align the allocation so that power of 2 size buffers are naturally aligned */ 76210284Sjmallett while (align < buffer_size) 77210284Sjmallett align = align << 1; 78210284Sjmallett 79210284Sjmallett if (buffers == 0) 80210284Sjmallett return 0; 81210284Sjmallett 82210284Sjmallett current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool)); 83210284Sjmallett if (current_num) 84210284Sjmallett { 85210284Sjmallett cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. Skipping setup.\n", 86210284Sjmallett pool, name, (unsigned long long)current_num); 87210284Sjmallett return 0; 88210284Sjmallett } 89210284Sjmallett 90210284Sjmallett memory = cvmx_bootmem_alloc(buffer_size * buffers, align); 91210284Sjmallett if (memory == NULL) 92210284Sjmallett { 93210284Sjmallett cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n", pool, name); 94210284Sjmallett return -1; 95210284Sjmallett } 96210284Sjmallett cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers); 97210284Sjmallett return 0; 98210284Sjmallett} 99210284Sjmallett 100210284Sjmallett 101210284Sjmallett/** 102210284Sjmallett * @INTERNAL 103210284Sjmallett * Allocate memory and initialize the FPA pools using memory 104210284Sjmallett * from cvmx-bootmem. Specifying zero for the number of 105210284Sjmallett * buffers will cause that FPA pool to not be setup. This is 106210284Sjmallett * useful if you aren't using some of the hardware and want 107210284Sjmallett * to save memory. Use cvmx_helper_initialize_fpa instead of 108210284Sjmallett * this function directly. 109210284Sjmallett * 110210284Sjmallett * @param pip_pool Should always be CVMX_FPA_PACKET_POOL 111210284Sjmallett * @param pip_size Should always be CVMX_FPA_PACKET_POOL_SIZE 112210284Sjmallett * @param pip_buffers 113210284Sjmallett * Number of packet buffers. 114210284Sjmallett * @param wqe_pool Should always be CVMX_FPA_WQE_POOL 115210284Sjmallett * @param wqe_size Should always be CVMX_FPA_WQE_POOL_SIZE 116210284Sjmallett * @param wqe_entries 117210284Sjmallett * Number of work queue entries 118210284Sjmallett * @param pko_pool Should always be CVMX_FPA_OUTPUT_BUFFER_POOL 119210284Sjmallett * @param pko_size Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 120210284Sjmallett * @param pko_buffers 121210284Sjmallett * PKO Command buffers. You should at minimum have two per 122210284Sjmallett * each PKO queue. 123210284Sjmallett * @param tim_pool Should always be CVMX_FPA_TIMER_POOL 124210284Sjmallett * @param tim_size Should always be CVMX_FPA_TIMER_POOL_SIZE 125210284Sjmallett * @param tim_buffers 126210284Sjmallett * TIM ring buffer command queues. At least two per timer bucket 127215990Sjmallett * is recommended. 128210284Sjmallett * @param dfa_pool Should always be CVMX_FPA_DFA_POOL 129210284Sjmallett * @param dfa_size Should always be CVMX_FPA_DFA_POOL_SIZE 130210284Sjmallett * @param dfa_buffers 131210284Sjmallett * DFA command buffer. A relatively small (32 for example) 132210284Sjmallett * number should work. 133210284Sjmallett * @return Zero on success, non-zero if out of memory 134210284Sjmallett */ 135210284Sjmallettstatic int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size, int pip_buffers, 136210284Sjmallett int wqe_pool, int wqe_size, int wqe_entries, 137210284Sjmallett int pko_pool, int pko_size, int pko_buffers, 138210284Sjmallett int tim_pool, int tim_size, int tim_buffers, 139210284Sjmallett int dfa_pool, int dfa_size, int dfa_buffers) 140210284Sjmallett{ 141210284Sjmallett int status; 142210284Sjmallett 143210284Sjmallett cvmx_fpa_enable(); 144210284Sjmallett 145210284Sjmallett if ((pip_buffers > 0) && (pip_buffers <= 64)) 146210284Sjmallett cvmx_dprintf("Warning: %d packet buffers may not be enough for hardware" 147210284Sjmallett " prefetch. 65 or more is recommended.\n", pip_buffers); 148210284Sjmallett 149210284Sjmallett if (pip_pool >= 0) 150210284Sjmallett { 151210284Sjmallett status = __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size, pip_buffers, 152210284Sjmallett "Packet Buffers"); 153210284Sjmallett if (status) 154210284Sjmallett return status; 155210284Sjmallett } 156210284Sjmallett 157210284Sjmallett if (wqe_pool >= 0) 158210284Sjmallett { 159210284Sjmallett status = __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size, wqe_entries, 160210284Sjmallett "Work Queue Entries"); 161210284Sjmallett if (status) 162210284Sjmallett return status; 163210284Sjmallett } 164210284Sjmallett 165210284Sjmallett if (pko_pool >= 0) 166210284Sjmallett { 167210284Sjmallett status = __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size, pko_buffers, 168210284Sjmallett "PKO Command Buffers"); 169210284Sjmallett if (status) 170210284Sjmallett return status; 171210284Sjmallett } 172210284Sjmallett 173210284Sjmallett if (tim_pool >= 0) 174210284Sjmallett { 175210284Sjmallett status = __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size, tim_buffers, 176210284Sjmallett "TIM Command Buffers"); 177210284Sjmallett if (status) 178210284Sjmallett return status; 179210284Sjmallett } 180210284Sjmallett 181210284Sjmallett if (dfa_pool >= 0) 182210284Sjmallett { 183210284Sjmallett status = __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size, dfa_buffers, 184210284Sjmallett "DFA Command Buffers"); 185210284Sjmallett if (status) 186210284Sjmallett return status; 187210284Sjmallett } 188210284Sjmallett 189210284Sjmallett return 0; 190210284Sjmallett} 191210284Sjmallett 192210284Sjmallett 193210284Sjmallett/** 194210284Sjmallett * Allocate memory and initialize the FPA pools using memory 195210284Sjmallett * from cvmx-bootmem. Sizes of each element in the pools is 196210284Sjmallett * controlled by the cvmx-config.h header file. Specifying 197210284Sjmallett * zero for any parameter will cause that FPA pool to not be 198210284Sjmallett * setup. This is useful if you aren't using some of the 199210284Sjmallett * hardware and want to save memory. 200210284Sjmallett * 201210284Sjmallett * @param packet_buffers 202210284Sjmallett * Number of packet buffers to allocate 203210284Sjmallett * @param work_queue_entries 204210284Sjmallett * Number of work queue entries 205210284Sjmallett * @param pko_buffers 206210284Sjmallett * PKO Command buffers. You should at minimum have two per 207210284Sjmallett * each PKO queue. 208210284Sjmallett * @param tim_buffers 209210284Sjmallett * TIM ring buffer command queues. At least two per timer bucket 210215990Sjmallett * is recommended. 211210284Sjmallett * @param dfa_buffers 212210284Sjmallett * DFA command buffer. A relatively small (32 for example) 213210284Sjmallett * number should work. 214210284Sjmallett * @return Zero on success, non-zero if out of memory 215210284Sjmallett */ 216210284Sjmallettint cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries, 217210284Sjmallett int pko_buffers, int tim_buffers, int dfa_buffers) 218210284Sjmallett{ 219210284Sjmallett#ifndef CVMX_FPA_PACKET_POOL 220210284Sjmallett#define CVMX_FPA_PACKET_POOL -1 221210284Sjmallett#define CVMX_FPA_PACKET_POOL_SIZE 0 222210284Sjmallett#endif 223210284Sjmallett#ifndef CVMX_FPA_WQE_POOL 224210284Sjmallett#define CVMX_FPA_WQE_POOL -1 225210284Sjmallett#define CVMX_FPA_WQE_POOL_SIZE 0 226210284Sjmallett#endif 227210284Sjmallett#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL 228210284Sjmallett#define CVMX_FPA_OUTPUT_BUFFER_POOL -1 229210284Sjmallett#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0 230210284Sjmallett#endif 231210284Sjmallett#ifndef CVMX_FPA_TIMER_POOL 232210284Sjmallett#define CVMX_FPA_TIMER_POOL -1 233210284Sjmallett#define CVMX_FPA_TIMER_POOL_SIZE 0 234210284Sjmallett#endif 235210284Sjmallett#ifndef CVMX_FPA_DFA_POOL 236210284Sjmallett#define CVMX_FPA_DFA_POOL -1 237210284Sjmallett#define CVMX_FPA_DFA_POOL_SIZE 0 238210284Sjmallett#endif 239210284Sjmallett return __cvmx_helper_initialize_fpa( 240210284Sjmallett CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, packet_buffers, 241210284Sjmallett CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE, work_queue_entries, 242210284Sjmallett CVMX_FPA_OUTPUT_BUFFER_POOL, CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, pko_buffers, 243210284Sjmallett CVMX_FPA_TIMER_POOL, CVMX_FPA_TIMER_POOL_SIZE, tim_buffers, 244210284Sjmallett CVMX_FPA_DFA_POOL, CVMX_FPA_DFA_POOL_SIZE, dfa_buffers); 245210284Sjmallett} 246210284Sjmallett 247