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 int g_module_mask_default = 0;
40 unsigned int *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;
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 #endif
80 xge_os_tracebuf_t *g_xge_os_tracebuf = NULL;
81 
82 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
83 void
84 xge_hal_driver_bar0_offset_check(void)
85 {
86 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) ==
87 		   0x108);
88 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) ==
89 		   0x08E0);
90 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) ==
91 		   0x09E8);
92 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) ==
93 		   0x1108);
94 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) ==
95 		   0x1170);
96 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) ==
97 		   0x1930);
98 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) ==
99 		   0x19B8);
100 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) ==
101 		   0x2100);
102 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) ==
103 		   0x2128);
104 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) ==
105 		   0x2170);
106 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) ==
107 		   0x2918);
108 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) ==
109 		   0x1040);
110 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) ==
111 		   0x1800);
112 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) ==
113 		   0x2010);
114 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) ==
115 		   0x2810);
116 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) ==
117 		   0x3000);
118 }
119 #endif
120 
121 /**
122  * xge_hal_driver_initialize - Initialize HAL.
123  * @config: HAL configuration, see xge_hal_driver_config_t{}.
124  * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up.
125  *
126  * HAL initialization entry point. Not to confuse with device initialization
127  * (note that HAL "contains" zero or more Xframe devices).
128  *
129  * Returns: XGE_HAL_OK - success;
130  * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid.
131  *
132  * See also: xge_hal_device_initialize(), xge_hal_status_e{},
133  * xge_hal_uld_cbs_t{}.
134  */
135 xge_hal_status_e
136 xge_hal_driver_initialize(xge_hal_driver_config_t *config,
137 			xge_hal_uld_cbs_t *uld_callbacks)
138 {
139 	xge_hal_status_e status;
140 
141 	g_xge_hal_driver = &g_driver;
142 
143 	xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF);
144 	xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF);
145 
146 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
147 	xge_hal_driver_bar0_offset_check();
148 #endif
149 
150 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
151 	if (config->tracebuf_size == 0)
152 		config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR;
153 #endif
154 
155 	status = __hal_driver_config_check(config);
156 	if (status != XGE_HAL_OK)
157 		return status;
158 
159 	xge_os_memzero(g_xge_hal_driver,  sizeof(xge_hal_driver_t));
160 
161 	/* apply config */
162 	xge_os_memcpy(&g_xge_hal_driver->config, config,
163 				sizeof(xge_hal_driver_config_t));
164 
165 	/* apply ULD callbacks */
166 	xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks,
167 					sizeof(xge_hal_uld_cbs_t));
168 
169 	g_xge_hal_driver->is_initialized = 1;
170 
171 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
172 	g_tracebuf.size = config->tracebuf_size;
173 	g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size);
174 	if (g_tracebuf.data == NULL) {
175 		xge_os_printf("cannot allocate trace buffer!");
176 		return XGE_HAL_ERR_OUT_OF_MEMORY;
177 	}
178 	g_tracebuf.offset = 0;
179 	*g_tracebuf.msg = 0;
180 	xge_os_memzero(g_tracebuf.data, g_tracebuf.size);
181 	g_xge_os_tracebuf = &g_tracebuf;
182 	dmesg = g_tracebuf.data;
183 	*dmesg = 0;
184 #endif
185 	return XGE_HAL_OK;
186 }
187 
188 /**
189  * xge_hal_driver_terminate - Terminate HAL.
190  *
191  * HAL termination entry point.
192  *
193  * See also: xge_hal_device_terminate().
194  */
195 void
196 xge_hal_driver_terminate(void)
197 {
198 	g_xge_hal_driver->is_initialized = 0;
199 
200 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
201 	if (g_tracebuf.size) {
202 		xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size);
203 	}
204 #endif
205 
206 	g_xge_hal_driver = NULL;
207 
208 #ifdef XGE_OS_MEMORY_CHECK
209 	{
210 		int i, leaks=0;
211 		xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt);
212 		for (i=0; i<g_malloc_cnt; i++) {
213 			if (g_malloc_arr[i].ptr != NULL) {
214 				xge_os_printf("OSPAL: memory leak detected at "
215 					"%s:%d:"XGE_OS_LLXFMT":%d",
216 					g_malloc_arr[i].file,
217 					g_malloc_arr[i].line,
218 					(unsigned long long)(ulong_t)
219 						g_malloc_arr[i].ptr,
220 					g_malloc_arr[i].size);
221 				leaks++;
222 			}
223 		}
224 		if (leaks) {
225 			xge_os_printf("OSPAL: %d memory leaks detected", leaks);
226 		} else {
227 			xge_os_printf("OSPAL: no memory leaks detected");
228 		}
229 	}
230 #endif
231 }
232