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