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
32 static xge_hal_driver_t g_driver;
33 xge_hal_driver_t *g_xge_hal_driver = NULL;
34 char *g_xge_hal_log = NULL;
35
36 #ifdef XGE_OS_MEMORY_CHECK
37 xge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX];
38 int g_malloc_cnt = 0;
39 #endif
40
41 /*
42 * Runtime tracing support
43 */
44 static unsigned long g_module_mask_default = 0;
45 unsigned long *g_module_mask = &g_module_mask_default;
46 static int g_level_default = 0;
47 int *g_level = &g_level_default;
48
49 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
50 static xge_os_tracebuf_t g_tracebuf;
51 char *dmesg, *dmesg_start;
52
53 /**
54 * xge_hal_driver_tracebuf_dump - Dump the trace buffer.
55 *
56 * Dump the trace buffer contents.
57 */
58 void
xge_hal_driver_tracebuf_dump(void)59 xge_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
85 xge_hal_status_e
xge_hal_driver_tracebuf_read(int bufsize,char * retbuf,int * retsize)86 xge_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
126 xge_os_tracebuf_t *g_xge_os_tracebuf = NULL;
127
128 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
129 void
xge_hal_driver_bar0_offset_check(void)130 xge_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 */
181 xge_hal_status_e
xge_hal_driver_initialize(xge_hal_driver_config_t * config,xge_hal_uld_cbs_t * uld_callbacks)182 xge_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 */
256 void
xge_hal_driver_terminate(void)257 xge_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