xref: /trueos/sys/dev/nxge/xgehal/xgehal-driver.c (revision 3d1bc41492fc5c3ebbd8cfa47e5bf4ed877a713a)
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