xgehal-driver.c revision 171095
1/*- 2 * Copyright (c) 2002-2007 Neterion, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/nxge/xgehal/xgehal-driver.c 171095 2007-06-29 22:47:18Z sam $ 27 */ 28 29/* 30 * FileName : xgehal-driver.c 31 * 32 * Description: HAL driver object functionality 33 * 34 * Created: 10 May 2004 35 */ 36 37#include <dev/nxge/include/xgehal-driver.h> 38#include <dev/nxge/include/xgehal-device.h> 39 40static xge_hal_driver_t g_driver; 41xge_hal_driver_t *g_xge_hal_driver = NULL; 42char *g_xge_hal_log = NULL; 43 44#ifdef XGE_OS_MEMORY_CHECK 45xge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX]; 46int g_malloc_cnt = 0; 47#endif 48 49/* 50 * Runtime tracing support 51 */ 52static unsigned long g_module_mask_default = 0; 53unsigned long *g_module_mask = &g_module_mask_default; 54static int g_level_default = 0; 55int *g_level = &g_level_default; 56 57#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 58static xge_os_tracebuf_t g_tracebuf; 59char *dmesg, *dmesg_start; 60 61/** 62 * xge_hal_driver_tracebuf_dump - Dump the trace buffer. 63 * 64 * Dump the trace buffer contents. 65 */ 66void 67xge_hal_driver_tracebuf_dump(void) 68{ 69 int i; 70 int off = 0; 71 72 if (g_xge_os_tracebuf == NULL) { 73 return; 74 } 75 76 xge_os_printf("################ Trace dump Begin ###############"); 77 if (g_xge_os_tracebuf->wrapped_once) { 78 for (i = 0; i < g_xge_os_tracebuf->size - 79 g_xge_os_tracebuf->offset; i += off) { 80 if (*(dmesg_start + i)) 81 xge_os_printf(dmesg_start + i); 82 off = xge_os_strlen(dmesg_start + i) + 1; 83 } 84 } 85 for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 86 if (*(dmesg + i)) 87 xge_os_printf(dmesg + i); 88 off = xge_os_strlen(dmesg + i) + 1; 89 } 90 xge_os_printf("################ Trace dump End ###############"); 91} 92 93xge_hal_status_e 94xge_hal_driver_tracebuf_read(int bufsize, char *retbuf, int *retsize) 95{ 96 int i; 97 int off = 0, retbuf_off = 0; 98 99 *retsize = 0; 100 *retbuf = 0; 101 102 if (g_xge_os_tracebuf == NULL) { 103 return XGE_HAL_FAIL; 104 } 105 106 if (g_xge_os_tracebuf->wrapped_once) { 107 for (i = 0; i < g_xge_os_tracebuf->size - 108 g_xge_os_tracebuf->offset; i += off) { 109 if (*(dmesg_start + i)) { 110 xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg_start + i); 111 retbuf_off += xge_os_strlen(dmesg_start + i) + 1; 112 if (retbuf_off > bufsize) 113 return XGE_HAL_ERR_OUT_OF_MEMORY; 114 } 115 off = xge_os_strlen(dmesg_start + i) + 1; 116 } 117 } 118 for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 119 if (*(dmesg + i)) { 120 xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg + i); 121 retbuf_off += xge_os_strlen(dmesg + i) + 1; 122 if (retbuf_off > bufsize) 123 return XGE_HAL_ERR_OUT_OF_MEMORY; 124 } 125 off = xge_os_strlen(dmesg + i) + 1; 126 } 127 128 *retsize = retbuf_off; 129 *(retbuf + retbuf_off + 1) = 0; 130 131 return XGE_HAL_OK; 132} 133#endif 134xge_os_tracebuf_t *g_xge_os_tracebuf = NULL; 135 136#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 137void 138xge_hal_driver_bar0_offset_check(void) 139{ 140 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) == 141 0x108); 142 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) == 143 0x08E0); 144 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) == 145 0x09E8); 146 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) == 147 0x1108); 148 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) == 149 0x1170); 150 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) == 151 0x1930); 152 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) == 153 0x19B8); 154 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) == 155 0x2100); 156 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) == 157 0x2128); 158 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) == 159 0x2170); 160 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) == 161 0x2918); 162 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) == 163 0x1040); 164 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) == 165 0x1800); 166 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) == 167 0x2010); 168 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) == 169 0x2810); 170 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) == 171 0x3000); 172} 173#endif 174 175/** 176 * xge_hal_driver_initialize - Initialize HAL. 177 * @config: HAL configuration, see xge_hal_driver_config_t{}. 178 * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up. 179 * 180 * HAL initialization entry point. Not to confuse with device initialization 181 * (note that HAL "contains" zero or more Xframe devices). 182 * 183 * Returns: XGE_HAL_OK - success; 184 * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid. 185 * 186 * See also: xge_hal_device_initialize(), xge_hal_status_e{}, 187 * xge_hal_uld_cbs_t{}. 188 */ 189xge_hal_status_e 190xge_hal_driver_initialize(xge_hal_driver_config_t *config, 191 xge_hal_uld_cbs_t *uld_callbacks) 192{ 193 xge_hal_status_e status; 194 195 g_xge_hal_driver = &g_driver; 196 197 xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF); 198 xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF); 199 200#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 201 xge_hal_driver_bar0_offset_check(); 202#endif 203 204#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 205 if (config->tracebuf_size == 0) 206 /* 207 * Trace buffer implementation is not lock protected. 208 * The only harm to expect is memcpy() to go beyond of 209 * allowed boundaries. To make it safe (driver-wise), 210 * we pre-allocate needed number of extra bytes. 211 */ 212 config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR + 213 XGE_OS_TRACE_MSGBUF_MAX; 214#endif 215 216 status = __hal_driver_config_check(config); 217 if (status != XGE_HAL_OK) 218 return status; 219 220 xge_os_memzero(g_xge_hal_driver, sizeof(xge_hal_driver_t)); 221 222 /* apply config */ 223 xge_os_memcpy(&g_xge_hal_driver->config, config, 224 sizeof(xge_hal_driver_config_t)); 225 226 /* apply ULD callbacks */ 227 xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks, 228 sizeof(xge_hal_uld_cbs_t)); 229 230 g_xge_hal_driver->is_initialized = 1; 231 232#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 233 g_tracebuf.size = config->tracebuf_size; 234 g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size); 235 if (g_tracebuf.data == NULL) { 236 xge_os_printf("cannot allocate trace buffer!"); 237 return XGE_HAL_ERR_OUT_OF_MEMORY; 238 } 239 /* timestamps disabled by default */ 240 g_tracebuf.timestamp = config->tracebuf_timestamp_en; 241 if (g_tracebuf.timestamp) { 242 xge_os_timestamp(g_tracebuf.msg); 243 g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX - 244 xge_os_strlen(g_tracebuf.msg); 245 } else 246 g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX; 247 g_tracebuf.offset = 0; 248 *g_tracebuf.msg = 0; 249 xge_os_memzero(g_tracebuf.data, g_tracebuf.size); 250 g_xge_os_tracebuf = &g_tracebuf; 251 dmesg = g_tracebuf.data; 252 *dmesg = 0; 253#endif 254 return XGE_HAL_OK; 255} 256 257/** 258 * xge_hal_driver_terminate - Terminate HAL. 259 * 260 * HAL termination entry point. 261 * 262 * See also: xge_hal_device_terminate(). 263 */ 264void 265xge_hal_driver_terminate(void) 266{ 267 g_xge_hal_driver->is_initialized = 0; 268 269#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 270 if (g_tracebuf.size) { 271 xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size); 272 } 273#endif 274 275 g_xge_hal_driver = NULL; 276 277#ifdef XGE_OS_MEMORY_CHECK 278 { 279 int i, leaks=0; 280 xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt); 281 for (i=0; i<g_malloc_cnt; i++) { 282 if (g_malloc_arr[i].ptr != NULL) { 283 xge_os_printf("OSPAL: memory leak detected at " 284 "%s:%d:"XGE_OS_LLXFMT":%d", 285 g_malloc_arr[i].file, 286 g_malloc_arr[i].line, 287 (unsigned long long)(ulong_t) 288 g_malloc_arr[i].ptr, 289 g_malloc_arr[i].size); 290 leaks++; 291 } 292 } 293 if (leaks) { 294 xge_os_printf("OSPAL: %d memory leaks detected", leaks); 295 } else { 296 xge_os_printf("OSPAL: no memory leaks detected"); 297 } 298 } 299#endif 300} 301