1171095Ssam/*- 2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc. 3171095Ssam * All rights reserved. 4171095Ssam * 5171095Ssam * Redistribution and use in source and binary forms, with or without 6171095Ssam * modification, are permitted provided that the following conditions 7171095Ssam * are met: 8171095Ssam * 1. Redistributions of source code must retain the above copyright 9171095Ssam * notice, this list of conditions and the following disclaimer. 10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright 11171095Ssam * notice, this list of conditions and the following disclaimer in the 12171095Ssam * documentation and/or other materials provided with the distribution. 13171095Ssam * 14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171095Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171095Ssam * SUCH DAMAGE. 25171095Ssam * 26171095Ssam * $FreeBSD$ 27171095Ssam */ 28171095Ssam 29171095Ssam#include <dev/nxge/include/xgehal-driver.h> 30171095Ssam#include <dev/nxge/include/xgehal-device.h> 31171095Ssam 32171095Ssamstatic xge_hal_driver_t g_driver; 33171095Ssamxge_hal_driver_t *g_xge_hal_driver = NULL; 34171095Ssamchar *g_xge_hal_log = NULL; 35171095Ssam 36171095Ssam#ifdef XGE_OS_MEMORY_CHECK 37171095Ssamxge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX]; 38171095Ssamint g_malloc_cnt = 0; 39171095Ssam#endif 40171095Ssam 41171095Ssam/* 42171095Ssam * Runtime tracing support 43171095Ssam */ 44171095Ssamstatic unsigned long g_module_mask_default = 0; 45171095Ssamunsigned long *g_module_mask = &g_module_mask_default; 46171095Ssamstatic int g_level_default = 0; 47171095Ssamint *g_level = &g_level_default; 48171095Ssam 49171095Ssam#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 50171095Ssamstatic xge_os_tracebuf_t g_tracebuf; 51171095Ssamchar *dmesg, *dmesg_start; 52171095Ssam 53171095Ssam/** 54171095Ssam * xge_hal_driver_tracebuf_dump - Dump the trace buffer. 55171095Ssam * 56171095Ssam * Dump the trace buffer contents. 57171095Ssam */ 58171095Ssamvoid 59171095Ssamxge_hal_driver_tracebuf_dump(void) 60171095Ssam{ 61171095Ssam int i; 62171095Ssam int off = 0; 63171095Ssam 64171095Ssam if (g_xge_os_tracebuf == NULL) { 65173139Srwatson return; 66171095Ssam } 67171095Ssam 68171095Ssam xge_os_printf("################ Trace dump Begin ###############"); 69171095Ssam if (g_xge_os_tracebuf->wrapped_once) { 70173139Srwatson for (i = 0; i < g_xge_os_tracebuf->size - 71173139Srwatson g_xge_os_tracebuf->offset; i += off) { 72173139Srwatson if (*(dmesg_start + i)) 73173139Srwatson xge_os_printf(dmesg_start + i); 74173139Srwatson off = xge_os_strlen(dmesg_start + i) + 1; 75173139Srwatson } 76171095Ssam } 77171095Ssam for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 78173139Srwatson if (*(dmesg + i)) 79173139Srwatson xge_os_printf(dmesg + i); 80173139Srwatson off = xge_os_strlen(dmesg + i) + 1; 81171095Ssam } 82171095Ssam xge_os_printf("################ Trace dump End ###############"); 83171095Ssam} 84171095Ssam 85171095Ssamxge_hal_status_e 86171095Ssamxge_hal_driver_tracebuf_read(int bufsize, char *retbuf, int *retsize) 87171095Ssam{ 88171095Ssam int i; 89171095Ssam int off = 0, retbuf_off = 0; 90171095Ssam 91171095Ssam *retsize = 0; 92171095Ssam *retbuf = 0; 93171095Ssam 94171095Ssam if (g_xge_os_tracebuf == NULL) { 95173139Srwatson return XGE_HAL_FAIL; 96171095Ssam } 97171095Ssam 98171095Ssam if (g_xge_os_tracebuf->wrapped_once) { 99173139Srwatson for (i = 0; i < g_xge_os_tracebuf->size - 100173139Srwatson g_xge_os_tracebuf->offset; i += off) { 101173139Srwatson if (*(dmesg_start + i)) { 102173139Srwatson xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg_start + i); 103173139Srwatson retbuf_off += xge_os_strlen(dmesg_start + i) + 1; 104173139Srwatson if (retbuf_off > bufsize) 105173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 106173139Srwatson } 107173139Srwatson off = xge_os_strlen(dmesg_start + i) + 1; 108173139Srwatson } 109171095Ssam } 110171095Ssam for (i = 0; i < g_xge_os_tracebuf->offset; i += off) { 111173139Srwatson if (*(dmesg + i)) { 112173139Srwatson xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg + i); 113173139Srwatson retbuf_off += xge_os_strlen(dmesg + i) + 1; 114173139Srwatson if (retbuf_off > bufsize) 115173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 116173139Srwatson } 117173139Srwatson off = xge_os_strlen(dmesg + i) + 1; 118171095Ssam } 119171095Ssam 120171095Ssam *retsize = retbuf_off; 121171095Ssam *(retbuf + retbuf_off + 1) = 0; 122171095Ssam 123171095Ssam return XGE_HAL_OK; 124171095Ssam} 125171095Ssam#endif 126171095Ssamxge_os_tracebuf_t *g_xge_os_tracebuf = NULL; 127171095Ssam 128171095Ssam#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 129171095Ssamvoid 130171095Ssamxge_hal_driver_bar0_offset_check(void) 131171095Ssam{ 132171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) == 133173139Srwatson 0x108); 134171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) == 135173139Srwatson 0x08E0); 136171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) == 137173139Srwatson 0x09E8); 138171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) == 139173139Srwatson 0x1108); 140171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) == 141173139Srwatson 0x1170); 142171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) == 143173139Srwatson 0x1930); 144171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) == 145173139Srwatson 0x19B8); 146171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) == 147173139Srwatson 0x2100); 148171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) == 149173139Srwatson 0x2128); 150171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) == 151173139Srwatson 0x2170); 152171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) == 153173139Srwatson 0x2918); 154171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) == 155173139Srwatson 0x1040); 156171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) == 157173139Srwatson 0x1800); 158171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) == 159173139Srwatson 0x2010); 160171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) == 161173139Srwatson 0x2810); 162171095Ssam xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) == 163173139Srwatson 0x3000); 164171095Ssam} 165171095Ssam#endif 166171095Ssam 167171095Ssam/** 168171095Ssam * xge_hal_driver_initialize - Initialize HAL. 169171095Ssam * @config: HAL configuration, see xge_hal_driver_config_t{}. 170171095Ssam * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up. 171171095Ssam * 172171095Ssam * HAL initialization entry point. Not to confuse with device initialization 173171095Ssam * (note that HAL "contains" zero or more Xframe devices). 174171095Ssam * 175171095Ssam * Returns: XGE_HAL_OK - success; 176171095Ssam * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid. 177171095Ssam * 178171095Ssam * See also: xge_hal_device_initialize(), xge_hal_status_e{}, 179171095Ssam * xge_hal_uld_cbs_t{}. 180171095Ssam */ 181171095Ssamxge_hal_status_e 182171095Ssamxge_hal_driver_initialize(xge_hal_driver_config_t *config, 183173139Srwatson xge_hal_uld_cbs_t *uld_callbacks) 184171095Ssam{ 185171095Ssam xge_hal_status_e status; 186171095Ssam 187171095Ssam g_xge_hal_driver = &g_driver; 188171095Ssam 189171095Ssam xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF); 190171095Ssam xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF); 191171095Ssam 192171095Ssam#ifdef XGE_HAL_DEBUG_BAR0_OFFSET 193171095Ssam xge_hal_driver_bar0_offset_check(); 194171095Ssam#endif 195171095Ssam 196171095Ssam#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 197171095Ssam if (config->tracebuf_size == 0) 198173139Srwatson /* 199173139Srwatson * Trace buffer implementation is not lock protected. 200173139Srwatson * The only harm to expect is memcpy() to go beyond of 201173139Srwatson * allowed boundaries. To make it safe (driver-wise), 202173139Srwatson * we pre-allocate needed number of extra bytes. 203173139Srwatson */ 204173139Srwatson config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR + 205173139Srwatson XGE_OS_TRACE_MSGBUF_MAX; 206171095Ssam#endif 207171095Ssam 208171095Ssam status = __hal_driver_config_check(config); 209171095Ssam if (status != XGE_HAL_OK) 210173139Srwatson return status; 211171095Ssam 212171095Ssam xge_os_memzero(g_xge_hal_driver, sizeof(xge_hal_driver_t)); 213171095Ssam 214171095Ssam /* apply config */ 215171095Ssam xge_os_memcpy(&g_xge_hal_driver->config, config, 216173139Srwatson sizeof(xge_hal_driver_config_t)); 217171095Ssam 218171095Ssam /* apply ULD callbacks */ 219171095Ssam xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks, 220173139Srwatson sizeof(xge_hal_uld_cbs_t)); 221171095Ssam 222171095Ssam g_xge_hal_driver->is_initialized = 1; 223171095Ssam 224171095Ssam#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 225171095Ssam g_tracebuf.size = config->tracebuf_size; 226171095Ssam g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size); 227171095Ssam if (g_tracebuf.data == NULL) { 228173139Srwatson xge_os_printf("cannot allocate trace buffer!"); 229173139Srwatson return XGE_HAL_ERR_OUT_OF_MEMORY; 230171095Ssam } 231171095Ssam /* timestamps disabled by default */ 232171095Ssam g_tracebuf.timestamp = config->tracebuf_timestamp_en; 233171095Ssam if (g_tracebuf.timestamp) { 234173139Srwatson xge_os_timestamp(g_tracebuf.msg); 235173139Srwatson g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX - 236173139Srwatson xge_os_strlen(g_tracebuf.msg); 237171095Ssam } else 238173139Srwatson g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX; 239171095Ssam g_tracebuf.offset = 0; 240171095Ssam *g_tracebuf.msg = 0; 241171095Ssam xge_os_memzero(g_tracebuf.data, g_tracebuf.size); 242171095Ssam g_xge_os_tracebuf = &g_tracebuf; 243171095Ssam dmesg = g_tracebuf.data; 244171095Ssam *dmesg = 0; 245171095Ssam#endif 246171095Ssam return XGE_HAL_OK; 247171095Ssam} 248171095Ssam 249171095Ssam/** 250171095Ssam * xge_hal_driver_terminate - Terminate HAL. 251171095Ssam * 252171095Ssam * HAL termination entry point. 253171095Ssam * 254171095Ssam * See also: xge_hal_device_terminate(). 255171095Ssam */ 256171095Ssamvoid 257171095Ssamxge_hal_driver_terminate(void) 258171095Ssam{ 259171095Ssam g_xge_hal_driver->is_initialized = 0; 260171095Ssam 261171095Ssam#ifdef XGE_TRACE_INTO_CIRCULAR_ARR 262171095Ssam if (g_tracebuf.size) { 263173139Srwatson xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size); 264171095Ssam } 265171095Ssam#endif 266171095Ssam 267171095Ssam g_xge_hal_driver = NULL; 268171095Ssam 269171095Ssam#ifdef XGE_OS_MEMORY_CHECK 270171095Ssam { 271173139Srwatson int i, leaks=0; 272173139Srwatson xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt); 273173139Srwatson for (i=0; i<g_malloc_cnt; i++) { 274173139Srwatson if (g_malloc_arr[i].ptr != NULL) { 275173139Srwatson xge_os_printf("OSPAL: memory leak detected at " 276173139Srwatson "%s:%d:"XGE_OS_LLXFMT":%d", 277173139Srwatson g_malloc_arr[i].file, 278173139Srwatson g_malloc_arr[i].line, 279173139Srwatson (unsigned long long)(ulong_t) 280173139Srwatson g_malloc_arr[i].ptr, 281173139Srwatson g_malloc_arr[i].size); 282173139Srwatson leaks++; 283173139Srwatson } 284173139Srwatson } 285173139Srwatson if (leaks) { 286173139Srwatson xge_os_printf("OSPAL: %d memory leaks detected", leaks); 287173139Srwatson } else { 288173139Srwatson xge_os_printf("OSPAL: no memory leaks detected"); 289173139Srwatson } 290171095Ssam } 291171095Ssam#endif 292171095Ssam} 293