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