1 /***********************license start*************** 2 * Author: Cavium Networks 3 * 4 * Contact: support@caviumnetworks.com 5 * This file is part of the OCTEON SDK 6 * 7 * Copyright (c) 2003-2008 Cavium Networks 8 * 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 12 * 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this file; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * or visit http://www.gnu.org/licenses/. 23 * 24 * This file may also be available under a different license from Cavium. 25 * Contact Cavium Networks for more information 26 ***********************license end**************************************/ 27 28 /* 29 * 30 * Small helper utilities. 31 * 32 */ 33 34 #ifndef __CVMX_HELPER_UTIL_H__ 35 #define __CVMX_HELPER_UTIL_H__ 36 37 /** 38 * Convert a interface mode into a human readable string 39 * 40 * @mode: Mode to convert 41 * 42 * Returns String 43 */ 44 extern const char 45 *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode); 46 47 /** 48 * Setup Random Early Drop to automatically begin dropping packets. 49 * 50 * @pass_thresh: 51 * Packets will begin slowly dropping when there are less than 52 * this many packet buffers free in FPA 0. 53 * @drop_thresh: 54 * All incoming packets will be dropped when there are less 55 * than this many free packet buffers in FPA 0. 56 * Returns Zero on success. Negative on failure 57 */ 58 extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh); 59 60 /** 61 * Get the version of the CVMX libraries. 62 * 63 * Returns Version string. Note this buffer is allocated statically 64 * and will be shared by all callers. 65 */ 66 extern const char *cvmx_helper_get_version(void); 67 68 /** 69 * Setup the common GMX settings that determine the number of 70 * ports. These setting apply to almost all configurations of all 71 * chips. 72 * 73 * @interface: Interface to configure 74 * @num_ports: Number of ports on the interface 75 * 76 * Returns Zero on success, negative on failure 77 */ 78 extern int __cvmx_helper_setup_gmx(int interface, int num_ports); 79 80 /** 81 * Returns the IPD/PKO port number for a port on the given 82 * interface. 83 * 84 * @interface: Interface to use 85 * @port: Port on the interface 86 * 87 * Returns IPD/PKO port number 88 */ 89 extern int cvmx_helper_get_ipd_port(int interface, int port); 90 91 /** 92 * Returns the IPD/PKO port number for the first port on the given 93 * interface. 94 * 95 * @interface: Interface to use 96 * 97 * Returns IPD/PKO port number 98 */ 99 static inline int cvmx_helper_get_first_ipd_port(int interface) 100 { 101 return cvmx_helper_get_ipd_port(interface, 0); 102 } 103 104 /** 105 * Returns the IPD/PKO port number for the last port on the given 106 * interface. 107 * 108 * @interface: Interface to use 109 * 110 * Returns IPD/PKO port number 111 */ 112 static inline int cvmx_helper_get_last_ipd_port(int interface) 113 { 114 extern int cvmx_helper_ports_on_interface(int interface); 115 116 return cvmx_helper_get_first_ipd_port(interface) + 117 cvmx_helper_ports_on_interface(interface) - 1; 118 } 119 120 /** 121 * Free the packet buffers contained in a work queue entry. 122 * The work queue entry is not freed. 123 * 124 * @work: Work queue entry with packet to free 125 */ 126 static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work) 127 { 128 uint64_t number_buffers; 129 union cvmx_buf_ptr buffer_ptr; 130 union cvmx_buf_ptr next_buffer_ptr; 131 uint64_t start_of_buffer; 132 133 number_buffers = work->word2.s.bufs; 134 if (number_buffers == 0) 135 return; 136 buffer_ptr = work->packet_ptr; 137 138 /* 139 * Since the number of buffers is not zero, we know this is 140 * not a dynamic short packet. We need to check if it is a 141 * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is 142 * true, we need to free all buffers except for the first 143 * one. The caller doesn't expect their WQE pointer to be 144 * freed 145 */ 146 start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; 147 if (cvmx_ptr_to_phys(work) == start_of_buffer) { 148 next_buffer_ptr = 149 *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); 150 buffer_ptr = next_buffer_ptr; 151 number_buffers--; 152 } 153 154 while (number_buffers--) { 155 /* 156 * Remember the back pointer is in cache lines, not 157 * 64bit words 158 */ 159 start_of_buffer = 160 ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; 161 /* 162 * Read pointer to next buffer before we free the 163 * current buffer. 164 */ 165 next_buffer_ptr = 166 *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); 167 cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer), 168 buffer_ptr.s.pool, 0); 169 buffer_ptr = next_buffer_ptr; 170 } 171 } 172 173 /** 174 * Returns the interface number for an IPD/PKO port number. 175 * 176 * @ipd_port: IPD/PKO port number 177 * 178 * Returns Interface number 179 */ 180 extern int cvmx_helper_get_interface_num(int ipd_port); 181 182 /** 183 * Returns the interface index number for an IPD/PKO port 184 * number. 185 * 186 * @ipd_port: IPD/PKO port number 187 * 188 * Returns Interface index number 189 */ 190 extern int cvmx_helper_get_interface_index_num(int ipd_port); 191 192 #endif /* __CVMX_HELPER_H__ */ 193