xgehal-driver.c revision 171095
150276Speter/*-
2166124Srafan * Copyright (c) 2002-2007 Neterion, Inc.
350276Speter * All rights reserved.
450276Speter *
550276Speter * Redistribution and use in source and binary forms, with or without
650276Speter * modification, are permitted provided that the following conditions
750276Speter * are met:
850276Speter * 1. Redistributions of source code must retain the above copyright
950276Speter *    notice, this list of conditions and the following disclaimer.
1050276Speter * 2. Redistributions in binary form must reproduce the above copyright
1150276Speter *    notice, this list of conditions and the following disclaimer in the
1250276Speter *    documentation and/or other materials provided with the distribution.
1350276Speter *
1450276Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1550276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1650276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1750276Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1850276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1950276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2050276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2150276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2250276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2350276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2450276Speter * SUCH DAMAGE.
2550276Speter *
2650276Speter * $FreeBSD: head/sys/dev/nxge/xgehal/xgehal-driver.c 171095 2007-06-29 22:47:18Z sam $
2750276Speter */
2850276Speter
2950276Speter/*
30166124Srafan *  FileName :    xgehal-driver.c
3150276Speter *
3250276Speter *  Description:  HAL driver object functionality
3350276Speter *
3450276Speter *  Created:      10 May 2004
35166124Srafan */
3650276Speter
3750276Speter#include <dev/nxge/include/xgehal-driver.h>
3850276Speter#include <dev/nxge/include/xgehal-device.h>
3950276Speter
4050276Speterstatic xge_hal_driver_t g_driver;
4150276Speterxge_hal_driver_t *g_xge_hal_driver = NULL;
4250276Speterchar *g_xge_hal_log = NULL;
4350276Speter
4450276Speter#ifdef XGE_OS_MEMORY_CHECK
4550276Speterxge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX];
4676726Speterint g_malloc_cnt = 0;
47166124Srafan#endif
4850276Speter
49166124Srafan/*
50166124Srafan * Runtime tracing support
51166124Srafan */
5250276Speterstatic unsigned long g_module_mask_default = 0;
5350276Speterunsigned long *g_module_mask = &g_module_mask_default;
54166124Srafanstatic int g_level_default = 0;
5550276Speterint *g_level = &g_level_default;
56166124Srafan
5750276Speter#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
5850276Speterstatic xge_os_tracebuf_t g_tracebuf;
5950276Speterchar *dmesg, *dmesg_start;
6050276Speter
6150276Speter/**
6250276Speter * xge_hal_driver_tracebuf_dump - Dump the trace buffer.
6350276Speter *
6450276Speter * Dump the trace buffer contents.
6550276Speter */
6676726Spetervoid
67166124Srafanxge_hal_driver_tracebuf_dump(void)
6850276Speter{
69166124Srafan	int i;
70166124Srafan	int off = 0;
71166124Srafan
72166124Srafan	if (g_xge_os_tracebuf == NULL) {
73166124Srafan		return;
74166124Srafan	}
7550276Speter
7650276Speter	xge_os_printf("################ Trace dump Begin ###############");
7750276Speter	if (g_xge_os_tracebuf->wrapped_once) {
78		for (i = 0; i < g_xge_os_tracebuf->size -
79				g_xge_os_tracebuf->offset; i += off) {
80			if (*(dmesg_start + i))
81				xge_os_printf(dmesg_start + i);
82			off = xge_os_strlen(dmesg_start + i) + 1;
83		}
84	}
85	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
86		if (*(dmesg + i))
87			xge_os_printf(dmesg + i);
88		off = xge_os_strlen(dmesg + i) + 1;
89	}
90	xge_os_printf("################ Trace dump End ###############");
91}
92
93xge_hal_status_e
94xge_hal_driver_tracebuf_read(int bufsize, char *retbuf, int *retsize)
95{
96	int i;
97	int off = 0, retbuf_off = 0;
98
99	*retsize = 0;
100	*retbuf = 0;
101
102	if (g_xge_os_tracebuf == NULL) {
103		return XGE_HAL_FAIL;
104	}
105
106	if (g_xge_os_tracebuf->wrapped_once) {
107		for (i = 0; i < g_xge_os_tracebuf->size -
108				g_xge_os_tracebuf->offset; i += off) {
109			if (*(dmesg_start + i)) {
110				xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg_start + i);
111				retbuf_off += xge_os_strlen(dmesg_start + i) + 1;
112				if (retbuf_off > bufsize)
113					return XGE_HAL_ERR_OUT_OF_MEMORY;
114			}
115			off = xge_os_strlen(dmesg_start + i) + 1;
116		}
117	}
118	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
119		if (*(dmesg + i)) {
120			xge_os_sprintf(retbuf + retbuf_off, "%s\n", dmesg + i);
121			retbuf_off += xge_os_strlen(dmesg + i) + 1;
122			if (retbuf_off > bufsize)
123				return XGE_HAL_ERR_OUT_OF_MEMORY;
124		}
125		off = xge_os_strlen(dmesg + i) + 1;
126	}
127
128	*retsize = retbuf_off;
129	*(retbuf + retbuf_off + 1) = 0;
130
131	return XGE_HAL_OK;
132}
133#endif
134xge_os_tracebuf_t *g_xge_os_tracebuf = NULL;
135
136#ifdef XGE_HAL_DEBUG_BAR0_OFFSET
137void
138xge_hal_driver_bar0_offset_check(void)
139{
140	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) ==
141		   0x108);
142	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) ==
143		   0x08E0);
144	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) ==
145		   0x09E8);
146	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) ==
147		   0x1108);
148	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) ==
149		   0x1170);
150	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) ==
151		   0x1930);
152	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) ==
153		   0x19B8);
154	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) ==
155		   0x2100);
156	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) ==
157		   0x2128);
158	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) ==
159		   0x2170);
160	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) ==
161		   0x2918);
162	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) ==
163		   0x1040);
164	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) ==
165		   0x1800);
166	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) ==
167		   0x2010);
168	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) ==
169		   0x2810);
170	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) ==
171		   0x3000);
172}
173#endif
174
175/**
176 * xge_hal_driver_initialize - Initialize HAL.
177 * @config: HAL configuration, see xge_hal_driver_config_t{}.
178 * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up.
179 *
180 * HAL initialization entry point. Not to confuse with device initialization
181 * (note that HAL "contains" zero or more Xframe devices).
182 *
183 * Returns: XGE_HAL_OK - success;
184 * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid.
185 *
186 * See also: xge_hal_device_initialize(), xge_hal_status_e{},
187 * xge_hal_uld_cbs_t{}.
188 */
189xge_hal_status_e
190xge_hal_driver_initialize(xge_hal_driver_config_t *config,
191			xge_hal_uld_cbs_t *uld_callbacks)
192{
193	xge_hal_status_e status;
194
195	g_xge_hal_driver = &g_driver;
196
197	xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF);
198	xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF);
199
200#ifdef XGE_HAL_DEBUG_BAR0_OFFSET
201	xge_hal_driver_bar0_offset_check();
202#endif
203
204#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
205	if (config->tracebuf_size == 0)
206		/*
207		 * Trace buffer implementation is not lock protected.
208		 * The only harm to expect is memcpy() to go beyond of
209		 * allowed boundaries. To make it safe (driver-wise),
210		 * we pre-allocate needed number of extra bytes.
211		 */
212		config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR +
213					XGE_OS_TRACE_MSGBUF_MAX;
214#endif
215
216	status = __hal_driver_config_check(config);
217	if (status != XGE_HAL_OK)
218		return status;
219
220	xge_os_memzero(g_xge_hal_driver,  sizeof(xge_hal_driver_t));
221
222	/* apply config */
223	xge_os_memcpy(&g_xge_hal_driver->config, config,
224				sizeof(xge_hal_driver_config_t));
225
226	/* apply ULD callbacks */
227	xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks,
228					sizeof(xge_hal_uld_cbs_t));
229
230	g_xge_hal_driver->is_initialized = 1;
231
232#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
233	g_tracebuf.size = config->tracebuf_size;
234	g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size);
235	if (g_tracebuf.data == NULL) {
236		xge_os_printf("cannot allocate trace buffer!");
237		return XGE_HAL_ERR_OUT_OF_MEMORY;
238	}
239	/* timestamps disabled by default */
240	g_tracebuf.timestamp = config->tracebuf_timestamp_en;
241	if (g_tracebuf.timestamp) {
242		xge_os_timestamp(g_tracebuf.msg);
243		g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX -
244					xge_os_strlen(g_tracebuf.msg);
245	} else
246		g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX;
247	g_tracebuf.offset = 0;
248	*g_tracebuf.msg = 0;
249	xge_os_memzero(g_tracebuf.data, g_tracebuf.size);
250	g_xge_os_tracebuf = &g_tracebuf;
251	dmesg = g_tracebuf.data;
252	*dmesg = 0;
253#endif
254	return XGE_HAL_OK;
255}
256
257/**
258 * xge_hal_driver_terminate - Terminate HAL.
259 *
260 * HAL termination entry point.
261 *
262 * See also: xge_hal_device_terminate().
263 */
264void
265xge_hal_driver_terminate(void)
266{
267	g_xge_hal_driver->is_initialized = 0;
268
269#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
270	if (g_tracebuf.size) {
271		xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size);
272	}
273#endif
274
275	g_xge_hal_driver = NULL;
276
277#ifdef XGE_OS_MEMORY_CHECK
278	{
279		int i, leaks=0;
280		xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt);
281		for (i=0; i<g_malloc_cnt; i++) {
282			if (g_malloc_arr[i].ptr != NULL) {
283				xge_os_printf("OSPAL: memory leak detected at "
284					"%s:%d:"XGE_OS_LLXFMT":%d",
285					g_malloc_arr[i].file,
286					g_malloc_arr[i].line,
287					(unsigned long long)(ulong_t)
288						g_malloc_arr[i].ptr,
289					g_malloc_arr[i].size);
290				leaks++;
291			}
292		}
293		if (leaks) {
294			xge_os_printf("OSPAL: %d memory leaks detected", leaks);
295		} else {
296			xge_os_printf("OSPAL: no memory leaks detected");
297		}
298	}
299#endif
300}
301