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 
22 /*
23  *  Copyright (c) 2002-2005 Neterion, Inc.
24  *  All right Reserved.
25  *
26  *  FileName :    xgehal-driver.c
27  *
28  *  Description:  HAL driver object functionality
29  *
30  *  Created:      10 May 2004
31  */
32 
33 #include "xgehal-driver.h"
34 #include "xgehal-device.h"
35 
36 static xge_hal_driver_t g_driver;
37 xge_hal_driver_t *g_xge_hal_driver = NULL;
38 char *g_xge_hal_log = NULL;
39 
40 #ifdef XGE_OS_MEMORY_CHECK
41 xge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX];
42 int g_malloc_cnt = 0;
43 #endif
44 
45 /*
46  * Runtime tracing support
47  */
48 static unsigned int g_module_mask_default = 0;
49 unsigned int *g_module_mask = &g_module_mask_default;
50 static int g_level_default = 0;
51 int *g_level = &g_level_default;
52 
53 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
54 static xge_os_tracebuf_t g_tracebuf;
55 char *dmesg, *dmesg_start;
56 
57 /**
58  * xge_hal_driver_tracebuf_dump - Dump the trace buffer.
59  *
60  * Dump the trace buffer contents.
61  */
62 void
63 xge_hal_driver_tracebuf_dump(void)
64 {
65 	int i;
66 	int off;
67 
68 	if (g_xge_os_tracebuf == NULL) {
69 		return;
70 	}
71 
72 	xge_os_printf("################ Trace dump Begin ###############");
73 	if (g_xge_os_tracebuf->wrapped_once) {
74 		for (i = 0; i < g_xge_os_tracebuf->size -
75 				g_xge_os_tracebuf->offset; i += off) {
76 			if (*(dmesg_start + i))
77 				xge_os_printf(dmesg_start + i);
78 			off = xge_os_strlen(dmesg_start + i) + 1;
79 		}
80 	}
81 	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
82 		if (*(dmesg + i))
83 			xge_os_printf(dmesg + i);
84 		off = xge_os_strlen(dmesg + i) + 1;
85 	}
86 	xge_os_printf("################ Trace dump End ###############");
87 }
88 #endif
89 xge_os_tracebuf_t *g_xge_os_tracebuf = NULL;
90 
91 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
92 void
93 xge_hal_driver_bar0_offset_check(void)
94 {
95 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) ==
96 		   0x108);
97 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) ==
98 		   0x08E0);
99 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) ==
100 		   0x09E8);
101 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) ==
102 		   0x1108);
103 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) ==
104 		   0x1170);
105 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) ==
106 		   0x1930);
107 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) ==
108 		   0x19B8);
109 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) ==
110 		   0x2100);
111 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) ==
112 		   0x2128);
113 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) ==
114 		   0x2170);
115 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) ==
116 		   0x2918);
117 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) ==
118 		   0x1040);
119 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) ==
120 		   0x1800);
121 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) ==
122 		   0x2010);
123 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) ==
124 		   0x2810);
125 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) ==
126 		   0x3000);
127 }
128 #endif
129 
130 /**
131  * xge_hal_driver_initialize - Initialize HAL.
132  * @config: HAL configuration, see xge_hal_driver_config_t{}.
133  * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up.
134  *
135  * HAL initialization entry point. Not to confuse with device initialization
136  * (note that HAL "contains" zero or more Xframe devices).
137  *
138  * Returns: XGE_HAL_OK - success;
139  * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid.
140  *
141  * See also: xge_hal_device_initialize(), xge_hal_status_e{},
142  * xge_hal_uld_cbs_t{}.
143  */
144 xge_hal_status_e
145 xge_hal_driver_initialize(xge_hal_driver_config_t *config,
146 			xge_hal_uld_cbs_t *uld_callbacks)
147 {
148 	xge_hal_status_e status;
149 
150 	g_xge_hal_driver = &g_driver;
151 
152 	xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF);
153 	xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF);
154 
155 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
156 	xge_hal_driver_bar0_offset_check();
157 #endif
158 
159 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
160 	if (config->tracebuf_size == 0)
161 		config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR;
162 #endif
163 
164 	status = __hal_driver_config_check(config);
165 	if (status != XGE_HAL_OK)
166 		return status;
167 
168 	xge_os_memzero(g_xge_hal_driver,  sizeof(xge_hal_driver_t));
169 
170 	/* apply config */
171 	xge_os_memcpy(&g_xge_hal_driver->config, config,
172 				sizeof(xge_hal_driver_config_t));
173 
174 	/* apply ULD callbacks */
175 	xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks,
176 					sizeof(xge_hal_uld_cbs_t));
177 
178 	g_xge_hal_driver->is_initialized = 1;
179 
180 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
181 	g_tracebuf.size = config->tracebuf_size;
182 	g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size);
183 	if (g_tracebuf.data == NULL) {
184 		xge_os_printf("cannot allocate trace buffer!");
185 		return XGE_HAL_ERR_OUT_OF_MEMORY;
186 	}
187 	g_tracebuf.offset = 0;
188 	*g_tracebuf.msg = 0;
189 	xge_os_memzero(g_tracebuf.data, g_tracebuf.size);
190 	g_xge_os_tracebuf = &g_tracebuf;
191 	dmesg = g_tracebuf.data;
192 	*dmesg = 0;
193 #endif
194 	return XGE_HAL_OK;
195 }
196 
197 /**
198  * xge_hal_driver_terminate - Terminate HAL.
199  *
200  * HAL termination entry point.
201  *
202  * See also: xge_hal_device_terminate().
203  */
204 void
205 xge_hal_driver_terminate(void)
206 {
207 	g_xge_hal_driver->is_initialized = 0;
208 
209 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
210 	if (g_tracebuf.size) {
211 		xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size);
212 	}
213 #endif
214 
215 	g_xge_hal_driver = NULL;
216 
217 #ifdef XGE_OS_MEMORY_CHECK
218 	{
219 		int i, leaks=0;
220 		xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt);
221 		for (i=0; i<g_malloc_cnt; i++) {
222 			if (g_malloc_arr[i].ptr != NULL) {
223 				xge_os_printf("OSPAL: memory leak detected at "
224 					"%s:%d:%llx:%d",
225 					g_malloc_arr[i].file,
226 					g_malloc_arr[i].line,
227 					(unsigned long long)(ulong_t)
228 						g_malloc_arr[i].ptr,
229 					g_malloc_arr[i].size);
230 				leaks++;
231 			}
232 		}
233 		if (leaks) {
234 			xge_os_printf("OSPAL: %d memory leaks detected", leaks);
235 		} else {
236 			xge_os_printf("OSPAL: no memory leaks detected");
237 		}
238 	}
239 #endif
240 }
241