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