xref: /onnv-gate/usr/src/uts/common/io/xge/hal/xgehal/xgehal-driver.c (revision 6937:a5e2c8b5c817)
11256Syl150051 /*
21256Syl150051  * CDDL HEADER START
31256Syl150051  *
41256Syl150051  * The contents of this file are subject to the terms of the
51256Syl150051  * Common Development and Distribution License (the "License").
61256Syl150051  * You may not use this file except in compliance with the License.
71256Syl150051  *
81256Syl150051  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91256Syl150051  * or http://www.opensolaris.org/os/licensing.
101256Syl150051  * See the License for the specific language governing permissions
111256Syl150051  * and limitations under the License.
121256Syl150051  *
131256Syl150051  * When distributing Covered Code, include this CDDL HEADER in each
141256Syl150051  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151256Syl150051  * If applicable, add the following below this CDDL HEADER, with the
161256Syl150051  * fields enclosed by brackets "[]" replaced with your own identifying
171256Syl150051  * information: Portions Copyright [yyyy] [name of copyright owner]
181256Syl150051  *
191256Syl150051  * CDDL HEADER END
201256Syl150051  *
213115Syl150051  * Copyright (c) 2002-2006 Neterion, Inc.
221256Syl150051  */
231256Syl150051 
241256Syl150051 #include "xgehal-driver.h"
251256Syl150051 #include "xgehal-device.h"
261256Syl150051 
271256Syl150051 static xge_hal_driver_t g_driver;
281256Syl150051 xge_hal_driver_t *g_xge_hal_driver = NULL;
291256Syl150051 char *g_xge_hal_log = NULL;
301256Syl150051 
311256Syl150051 #ifdef XGE_OS_MEMORY_CHECK
321256Syl150051 xge_os_malloc_t g_malloc_arr[XGE_OS_MALLOC_CNT_MAX];
331256Syl150051 int g_malloc_cnt = 0;
341256Syl150051 #endif
351256Syl150051 
361256Syl150051 /*
371256Syl150051  * Runtime tracing support
381256Syl150051  */
39*6937Sxw161283 static unsigned long g_module_mask_default = 0;
40*6937Sxw161283 unsigned long *g_module_mask = &g_module_mask_default;
411256Syl150051 static int g_level_default = 0;
421256Syl150051 int *g_level = &g_level_default;
431256Syl150051 
441256Syl150051 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
451256Syl150051 static xge_os_tracebuf_t g_tracebuf;
461256Syl150051 char *dmesg, *dmesg_start;
471256Syl150051 
481256Syl150051 /**
491256Syl150051  * xge_hal_driver_tracebuf_dump - Dump the trace buffer.
501256Syl150051  *
511256Syl150051  * Dump the trace buffer contents.
521256Syl150051  */
531256Syl150051 void
xge_hal_driver_tracebuf_dump(void)541256Syl150051 xge_hal_driver_tracebuf_dump(void)
551256Syl150051 {
561256Syl150051 	int i;
57*6937Sxw161283 	int off = 0;
581256Syl150051 
591256Syl150051 	if (g_xge_os_tracebuf == NULL) {
601256Syl150051 		return;
611256Syl150051 	}
621256Syl150051 
631256Syl150051 	xge_os_printf("################ Trace dump Begin ###############");
641256Syl150051 	if (g_xge_os_tracebuf->wrapped_once) {
651256Syl150051 		for (i = 0; i < g_xge_os_tracebuf->size -
661256Syl150051 				g_xge_os_tracebuf->offset; i += off) {
671256Syl150051 			if (*(dmesg_start + i))
681256Syl150051 				xge_os_printf(dmesg_start + i);
691256Syl150051 			off = xge_os_strlen(dmesg_start + i) + 1;
701256Syl150051 		}
711256Syl150051 	}
721256Syl150051 	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
731256Syl150051 		if (*(dmesg + i))
741256Syl150051 			xge_os_printf(dmesg + i);
751256Syl150051 		off = xge_os_strlen(dmesg + i) + 1;
761256Syl150051 	}
771256Syl150051 	xge_os_printf("################ Trace dump End ###############");
781256Syl150051 }
79*6937Sxw161283 
80*6937Sxw161283 xge_hal_status_e
xge_hal_driver_tracebuf_read(int bufsize,char * retbuf,int * retsize)81*6937Sxw161283 xge_hal_driver_tracebuf_read(int bufsize, char *retbuf, int *retsize)
82*6937Sxw161283 {
83*6937Sxw161283 	int i;
84*6937Sxw161283 	int off = 0, retbuf_off = 0;
85*6937Sxw161283 
86*6937Sxw161283 	*retsize = 0;
87*6937Sxw161283 	*retbuf = 0;
88*6937Sxw161283 
89*6937Sxw161283 	if (g_xge_os_tracebuf == NULL) {
90*6937Sxw161283 		return XGE_HAL_FAIL;
91*6937Sxw161283 	}
92*6937Sxw161283 
93*6937Sxw161283 	if (g_xge_os_tracebuf->wrapped_once) {
94*6937Sxw161283 		for (i = 0; i < g_xge_os_tracebuf->size -
95*6937Sxw161283 				g_xge_os_tracebuf->offset; i += off) {
96*6937Sxw161283 			if (*(dmesg_start + i)) {
97*6937Sxw161283 				xge_os_snprintf((retbuf + retbuf_off), (bufsize - retbuf_off),
98*6937Sxw161283 				    "%s\n", dmesg_start + i);
99*6937Sxw161283 				retbuf_off += xge_os_strlen(dmesg_start + i) + 1;
100*6937Sxw161283 				if (retbuf_off > bufsize)
101*6937Sxw161283 					return XGE_HAL_ERR_OUT_OF_MEMORY;
102*6937Sxw161283 			}
103*6937Sxw161283 			off = xge_os_strlen(dmesg_start + i) + 1;
104*6937Sxw161283 		}
105*6937Sxw161283 	}
106*6937Sxw161283 	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
107*6937Sxw161283 		if (*(dmesg + i)) {
108*6937Sxw161283 			xge_os_snprintf((retbuf + retbuf_off), (bufsize - retbuf_off),
109*6937Sxw161283 			    "%s\n", dmesg + i);
110*6937Sxw161283 			retbuf_off += xge_os_strlen(dmesg + i) + 1;
111*6937Sxw161283 			if (retbuf_off > bufsize)
112*6937Sxw161283 				return XGE_HAL_ERR_OUT_OF_MEMORY;
113*6937Sxw161283 		}
114*6937Sxw161283 		off = xge_os_strlen(dmesg + i) + 1;
115*6937Sxw161283 	}
116*6937Sxw161283 
117*6937Sxw161283 	*retsize = retbuf_off;
118*6937Sxw161283 	*(retbuf + retbuf_off + 1) = 0;
119*6937Sxw161283 
120*6937Sxw161283 	return XGE_HAL_OK;
121*6937Sxw161283 }
1221256Syl150051 #endif
1231256Syl150051 xge_os_tracebuf_t *g_xge_os_tracebuf = NULL;
1241256Syl150051 
1251256Syl150051 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
1261256Syl150051 void
xge_hal_driver_bar0_offset_check(void)1271256Syl150051 xge_hal_driver_bar0_offset_check(void)
1281256Syl150051 {
1291256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, adapter_status) ==
1301256Syl150051 		   0x108);
1311256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_traffic_int) ==
1321256Syl150051 		   0x08E0);
1331256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, dtx_control) ==
1341256Syl150051 		   0x09E8);
1351256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, tx_fifo_partition_0) ==
1361256Syl150051 		   0x1108);
1371256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_enable) ==
1381256Syl150051 		   0x1170);
1391256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, prc_rxd0_n[0]) ==
1401256Syl150051 		   0x1930);
1411256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rti_command_mem) ==
1421256Syl150051 		   0x19B8);
1431256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_cfg) ==
1441256Syl150051 		   0x2100);
1451256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rmac_addr_cmd_mem) ==
1461256Syl150051 		   0x2128);
1471256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_link_util) ==
1481256Syl150051 		   0x2170);
1491256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_pause_thresh_q0q3) ==
1501256Syl150051 		   0x2918);
1511256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, pcc_err_reg) ==
1521256Syl150051 		   0x1040);
1531256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, rxdma_int_status) ==
1541256Syl150051 		   0x1800);
1551256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mac_tmac_err_reg) ==
1561256Syl150051 		   0x2010);
1571256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, mc_err_reg) ==
1581256Syl150051 		   0x2810);
1591256Syl150051 	xge_assert(xge_offsetof(xge_hal_pci_bar0_t, xgxs_int_status) ==
1601256Syl150051 		   0x3000);
1611256Syl150051 }
1621256Syl150051 #endif
1631256Syl150051 
1641256Syl150051 /**
1651256Syl150051  * xge_hal_driver_initialize - Initialize HAL.
1661256Syl150051  * @config: HAL configuration, see xge_hal_driver_config_t{}.
1671256Syl150051  * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up.
1681256Syl150051  *
1691256Syl150051  * HAL initialization entry point. Not to confuse with device initialization
1701256Syl150051  * (note that HAL "contains" zero or more Xframe devices).
1711256Syl150051  *
1721256Syl150051  * Returns: XGE_HAL_OK - success;
1731256Syl150051  * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid.
1741256Syl150051  *
1751256Syl150051  * See also: xge_hal_device_initialize(), xge_hal_status_e{},
1761256Syl150051  * xge_hal_uld_cbs_t{}.
1771256Syl150051  */
1781256Syl150051 xge_hal_status_e
xge_hal_driver_initialize(xge_hal_driver_config_t * config,xge_hal_uld_cbs_t * uld_callbacks)1791256Syl150051 xge_hal_driver_initialize(xge_hal_driver_config_t *config,
1801256Syl150051 			xge_hal_uld_cbs_t *uld_callbacks)
1811256Syl150051 {
1821256Syl150051 	xge_hal_status_e status;
1831256Syl150051 
1841256Syl150051 	g_xge_hal_driver = &g_driver;
1851256Syl150051 
1861256Syl150051 	xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF);
1871256Syl150051 	xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF);
1881256Syl150051 
1891256Syl150051 #ifdef XGE_HAL_DEBUG_BAR0_OFFSET
1901256Syl150051 	xge_hal_driver_bar0_offset_check();
1911256Syl150051 #endif
1921256Syl150051 
1931256Syl150051 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
1941256Syl150051 	if (config->tracebuf_size == 0)
195*6937Sxw161283 		/*
196*6937Sxw161283 		 * Trace buffer implementation is not lock protected.
197*6937Sxw161283 		 * The only harm to expect is memcpy() to go beyond of
198*6937Sxw161283 		 * allowed boundaries. To make it safe (driver-wise),
199*6937Sxw161283 		 * we pre-allocate needed number of extra bytes.
200*6937Sxw161283 		 */
201*6937Sxw161283 		config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR +
202*6937Sxw161283 					XGE_OS_TRACE_MSGBUF_MAX;
2031256Syl150051 #endif
2041256Syl150051 
2051256Syl150051 	status = __hal_driver_config_check(config);
2061256Syl150051 	if (status != XGE_HAL_OK)
2071256Syl150051 		return status;
2081256Syl150051 
2091256Syl150051 	xge_os_memzero(g_xge_hal_driver,  sizeof(xge_hal_driver_t));
2101256Syl150051 
2111256Syl150051 	/* apply config */
2121256Syl150051 	xge_os_memcpy(&g_xge_hal_driver->config, config,
2131256Syl150051 				sizeof(xge_hal_driver_config_t));
2141256Syl150051 
2151256Syl150051 	/* apply ULD callbacks */
2161256Syl150051 	xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks,
2171256Syl150051 					sizeof(xge_hal_uld_cbs_t));
2181256Syl150051 
2191256Syl150051 	g_xge_hal_driver->is_initialized = 1;
2201256Syl150051 
2211256Syl150051 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
2221256Syl150051 	g_tracebuf.size = config->tracebuf_size;
2231256Syl150051 	g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size);
2241256Syl150051 	if (g_tracebuf.data == NULL) {
2251256Syl150051 		xge_os_printf("cannot allocate trace buffer!");
2261256Syl150051 		return XGE_HAL_ERR_OUT_OF_MEMORY;
2271256Syl150051 	}
228*6937Sxw161283 	/* timestamps disabled by default */
229*6937Sxw161283 	g_tracebuf.timestamp = config->tracebuf_timestamp_en;
230*6937Sxw161283 	if (g_tracebuf.timestamp) {
231*6937Sxw161283 		xge_os_timestamp(g_tracebuf.msg);
232*6937Sxw161283 		g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX -
233*6937Sxw161283 					xge_os_strlen(g_tracebuf.msg);
234*6937Sxw161283 	} else
235*6937Sxw161283 		g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX;
2361256Syl150051 	g_tracebuf.offset = 0;
2371256Syl150051 	*g_tracebuf.msg = 0;
2381256Syl150051 	xge_os_memzero(g_tracebuf.data, g_tracebuf.size);
2391256Syl150051 	g_xge_os_tracebuf = &g_tracebuf;
2401256Syl150051 	dmesg = g_tracebuf.data;
2411256Syl150051 	*dmesg = 0;
2421256Syl150051 #endif
2431256Syl150051 	return XGE_HAL_OK;
2441256Syl150051 }
2451256Syl150051 
2461256Syl150051 /**
2471256Syl150051  * xge_hal_driver_terminate - Terminate HAL.
2481256Syl150051  *
2491256Syl150051  * HAL termination entry point.
2501256Syl150051  *
2511256Syl150051  * See also: xge_hal_device_terminate().
2521256Syl150051  */
2531256Syl150051 void
xge_hal_driver_terminate(void)2541256Syl150051 xge_hal_driver_terminate(void)
2551256Syl150051 {
2561256Syl150051 	g_xge_hal_driver->is_initialized = 0;
2571256Syl150051 
2581256Syl150051 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
2591256Syl150051 	if (g_tracebuf.size) {
2601256Syl150051 		xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size);
2611256Syl150051 	}
2621256Syl150051 #endif
2631256Syl150051 
2641256Syl150051 	g_xge_hal_driver = NULL;
2651256Syl150051 
2661256Syl150051 #ifdef XGE_OS_MEMORY_CHECK
2671256Syl150051 	{
2681256Syl150051 		int i, leaks=0;
2691256Syl150051 		xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt);
2701256Syl150051 		for (i=0; i<g_malloc_cnt; i++) {
2711256Syl150051 			if (g_malloc_arr[i].ptr != NULL) {
2721256Syl150051 				xge_os_printf("OSPAL: memory leak detected at "
2733115Syl150051 					"%s:%d:"XGE_OS_LLXFMT":%d",
2741256Syl150051 					g_malloc_arr[i].file,
2751256Syl150051 					g_malloc_arr[i].line,
2761256Syl150051 					(unsigned long long)(ulong_t)
2771256Syl150051 						g_malloc_arr[i].ptr,
2781256Syl150051 					g_malloc_arr[i].size);
2791256Syl150051 				leaks++;
2801256Syl150051 			}
2811256Syl150051 		}
2821256Syl150051 		if (leaks) {
2831256Syl150051 			xge_os_printf("OSPAL: %d memory leaks detected", leaks);
2841256Syl150051 		} else {
2851256Syl150051 			xge_os_printf("OSPAL: no memory leaks detected");
2861256Syl150051 		}
2871256Syl150051 	}
2881256Syl150051 #endif
2891256Syl150051 }
290