]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/nxge/xgehal/xgehal-driver.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / nxge / xgehal / xgehal-driver.c
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
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
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
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
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
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 }