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$ 27 */ 28 29#include <dev/nxge/include/xgehal-driver.h> 30#include <dev/nxge/include/xgehal-device.h> 31 32static xge_hal_driver_t g_driver; 33xge_hal_driver_t *g_xge_hal_driver = NULL; 34char *g_xge_hal_log = NULL; 35 36#ifdef XGE_OS_MEMORY_CHECK 37xge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX]; 38int g_malloc_cnt = 0; 39#endif 40 41/* 42 * Runtime tracing support 43 */ 44static unsigned long g_module_mask_default = 0; 45unsigned long *g_module_mask = &g_module_mask_default; 46static int g_level_default = 0; 47int *g_level = &g_level_default; 48 49#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 50static xge_os_tracebuf_t g_tracebuf; 51char *dmesg, *dmesg_start; 52 53/** 54 * xge_hal_driver_tracebuf_dump - Dump the trace buffer. 55 * 56 * Dump the trace buffer contents. 57 */ 58void 59xge_hal_driver_tracebuf_dump(void) 60{ 61 int i; 62 int off = 0; 63 64 if (g_xge_os_tracebuf == NULL) { 65 return; 66 } 67 68 xge_os_printf("################ Trace dump Begin ###############"); 69 if (g_xge_os_tracebuf->wrapped_once) { 70 for (i = 0; i < g_xge_os_tracebuf->size - 71 g_xge_os_tracebuf->offset; i += off) { 72 if (*(dmesg_start + i)) 73 xge_os_printf(dmesg_start + i); 74 off = xge_os_strlen(dmesg_start + i) + 1; 75 } 76 } 77 for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 78 if (*(dmesg + i)) 79 xge_os_printf(dmesg + i); 80 off = xge_os_strlen(dmesg + i) + 1; 81 } 82 xge_os_printf("################ Trace dump End ###############"); 83} 84 85xge_hal_status_e 86xge_hal_driver_tracebuf_read(int bufsize, char *retbuf, int *retsize) 87{ 88 int i; 89 int off = 0, retbuf_off = 0; 90 91 *retsize = 0; 92 *retbuf = 0; 93 94 if (g_xge_os_tracebuf == NULL) { 95 return XGE_HAL_FAIL; 96 } 97 98 if (g_xge_os_tracebuf->wrapped_once) { 99 for (i = 0; i < g_xge_os_tracebuf->size - 100 g_xge_os_tracebuf->offset; i += off) { 101 if (*(dmesg_start + i)) { 102 xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg_start + i); 103 retbuf_off += xge_os_strlen(dmesg_start + i) + 1; 104 if (retbuf_off > bufsize) 105 return XGE_HAL_ERR_OUT_OF_MEMORY; 106 } 107 off = xge_os_strlen(dmesg_start + i) + 1; 108 } 109 } 110 for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 111 if (*(dmesg + i)) { 112 xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg + i); 113 retbuf_off += xge_os_strlen(dmesg + i) + 1; 114 if (retbuf_off > bufsize) 115 return XGE_HAL_ERR_OUT_OF_MEMORY; 116 } 117 off = xge_os_strlen(dmesg + i) + 1; 118 } 119 120 *retsize = retbuf_off; 121 *(retbuf + retbuf_off + 1) = 0; 122 123 return XGE_HAL_OK; 124} 125#endif 126xge_os_tracebuf_t *g_xge_os_tracebuf = NULL; 127 128#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 129void 130xge_hal_driver_bar0_offset_check(void) 131{ 132 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) == 133 0x108); 134 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) == 135 0x08E0); 136 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) == 137 0x09E8); 138 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) == 139 0x1108); 140 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) == 141 0x1170); 142 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) == 143 0x1930); 144 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) == 145 0x19B8); 146 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) == 147 0x2100); 148 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) == 149 0x2128); 150 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) == 151 0x2170); 152 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) == 153 0x2918); 154 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) == 155 0x1040); 156 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) == 157 0x1800); 158 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) == 159 0x2010); 160 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) == 161 0x2810); 162 xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) == 163 0x3000); 164} 165#endif 166 167/** 168 * xge_hal_driver_initialize - Initialize HAL. 169 * @config: HAL configuration, see xge_hal_driver_config_t{}. 170 * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up. 171 * 172 * HAL initialization entry point. Not to confuse with device initialization 173 * (note that HAL "contains" zero or more Xframe devices). 174 * 175 * Returns: XGE_HAL_OK - success; 176 * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid. 177 * 178 * See also: xge_hal_device_initialize(), xge_hal_status_e{}, 179 * xge_hal_uld_cbs_t{}. 180 */ 181xge_hal_status_e 182xge_hal_driver_initialize(xge_hal_driver_config_t *config, 183 xge_hal_uld_cbs_t *uld_callbacks) 184{ 185 xge_hal_status_e status; 186 187 g_xge_hal_driver = &g_driver; 188 189 xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF); 190 xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF); 191 192#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 193 xge_hal_driver_bar0_offset_check(); 194#endif 195 196#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 197 if (config->tracebuf_size == 0) 198 /* 199 * Trace buffer implementation is not lock protected. 200 * The only harm to expect is memcpy() to go beyond of 201 * allowed boundaries. To make it safe (driver-wise), 202 * we pre-allocate needed number of extra bytes. 203 */ 204 config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR + 205 XGE_OS_TRACE_MSGBUF_MAX; 206#endif 207 208 status = __hal_driver_config_check(config); 209 if (status != XGE_HAL_OK) 210 return status; 211 212 xge_os_memzero(g_xge_hal_driver, sizeof(xge_hal_driver_t)); 213 214 /* apply config */ 215 xge_os_memcpy(&g_xge_hal_driver->config, config, 216 sizeof(xge_hal_driver_config_t)); 217 218 /* apply ULD callbacks */ 219 xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks, 220 sizeof(xge_hal_uld_cbs_t)); 221 222 g_xge_hal_driver->is_initialized = 1; 223 224#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 225 g_tracebuf.size = config->tracebuf_size; 226 g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size); 227 if (g_tracebuf.data == NULL) { 228 xge_os_printf("cannot allocate trace buffer!"); 229 return XGE_HAL_ERR_OUT_OF_MEMORY; 230 } 231 /* timestamps disabled by default */ 232 g_tracebuf.timestamp = config->tracebuf_timestamp_en; 233 if (g_tracebuf.timestamp) { 234 xge_os_timestamp(g_tracebuf.msg); 235 g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX - 236 xge_os_strlen(g_tracebuf.msg); 237 } else 238 g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX; 239 g_tracebuf.offset = 0; 240 *g_tracebuf.msg = 0; 241 xge_os_memzero(g_tracebuf.data, g_tracebuf.size); 242 g_xge_os_tracebuf = &g_tracebuf; 243 dmesg = g_tracebuf.data; 244 *dmesg = 0; 245#endif 246 return XGE_HAL_OK; 247} 248 249/** 250 * xge_hal_driver_terminate - Terminate HAL. 251 * 252 * HAL termination entry point. 253 * 254 * See also: xge_hal_device_terminate(). 255 */ 256void 257xge_hal_driver_terminate(void) 258{ 259 g_xge_hal_driver->is_initialized = 0; 260 261#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 262 if (g_tracebuf.size) { 263 xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size); 264 } 265#endif 266 267 g_xge_hal_driver = NULL; 268 269#ifdef XGE_OS_MEMORY_CHECK 270 { 271 int i, leaks=0; 272 xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt); 273 for (i=0; i<g_malloc_cnt; i++) { 274 if (g_malloc_arr[i].ptr != NULL) { 275 xge_os_printf("OSPAL: memory leak detected at " 276 "%s:%d:"XGE_OS_LLXFMT":%d", 277 g_malloc_arr[i].file, 278 g_malloc_arr[i].line, 279 (unsigned long long)(ulong_t) 280 g_malloc_arr[i].ptr, 281 g_malloc_arr[i].size); 282 leaks++; 283 } 284 } 285 if (leaks) { 286 xge_os_printf("OSPAL: %d memory leaks detected", leaks); 287 } else { 288 xge_os_printf("OSPAL: no memory leaks detected"); 289 } 290 } 291#endif 292} 293