예제 #1
0
/**
 * xge_hal_driver_tracebuf_dump - Dump the trace buffer.
 *
 * Dump the trace buffer contents.
 */
void
xge_hal_driver_tracebuf_dump(void)
{
	int i;
	int off = 0;

	if (g_xge_os_tracebuf == NULL) {
	    return;
	}

	xge_os_printf("################ Trace dump Begin ###############");
	if (g_xge_os_tracebuf->wrapped_once) {
	    for (i = 0; i < g_xge_os_tracebuf->size -
	            g_xge_os_tracebuf->offset; i += off) {
	        if (*(dmesg_start + i))
	            xge_os_printf(dmesg_start + i);
	        off = xge_os_strlen(dmesg_start + i) + 1;
	    }
	}
	for (i = 0; i < g_xge_os_tracebuf->offset; i += off) {
	    if (*(dmesg + i))
	        xge_os_printf(dmesg + i);
	    off = xge_os_strlen(dmesg + i) + 1;
	}
	xge_os_printf("################ Trace dump End ###############");
}
예제 #2
0
/**
 * xge_hal_driver_terminate - Terminate HAL.
 *
 * HAL termination entry point.
 *
 * See also: xge_hal_device_terminate().
 */
void
xge_hal_driver_terminate(void)
{
	g_xge_hal_driver->is_initialized = 0;

#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
	if (g_tracebuf.size) {
	    xge_os_free(NULL, g_tracebuf.data, g_tracebuf.size);
	}
#endif

	g_xge_hal_driver = NULL;

#ifdef XGE_OS_MEMORY_CHECK
	{
	    int i, leaks=0;
	    xge_os_printf("OSPAL: max g_malloc_cnt %d", g_malloc_cnt);
	    for (i=0; i<g_malloc_cnt; i++) {
	        if (g_malloc_arr[i].ptr != NULL) {
	            xge_os_printf("OSPAL: memory leak detected at "
	                "%s:%d:"XGE_OS_LLXFMT":%d",
	                g_malloc_arr[i].file,
	                g_malloc_arr[i].line,
	                (unsigned long long)(ulong_t)
	                    g_malloc_arr[i].ptr,
	                g_malloc_arr[i].size);
	            leaks++;
	        }
	    }
	    if (leaks) {
	        xge_os_printf("OSPAL: %d memory leaks detected", leaks);
	    } else {
	        xge_os_printf("OSPAL: no memory leaks detected");
	    }
	}
#endif
}
예제 #3
0
/**
 * xge_hal_driver_initialize - Initialize HAL.
 * @config: HAL configuration, see xge_hal_driver_config_t{}.
 * @uld_callbacks: Upper-layer driver callbacks, e.g. link-up.
 *
 * HAL initialization entry point. Not to confuse with device initialization
 * (note that HAL "contains" zero or more Xframe devices).
 *
 * Returns: XGE_HAL_OK - success;
 * XGE_HAL_ERR_BAD_DRIVER_CONFIG - Driver configuration params invalid.
 *
 * See also: xge_hal_device_initialize(), xge_hal_status_e{},
 * xge_hal_uld_cbs_t{}.
 */
xge_hal_status_e
xge_hal_driver_initialize(xge_hal_driver_config_t *config,
	        xge_hal_uld_cbs_t *uld_callbacks)
{
	xge_hal_status_e status;

	g_xge_hal_driver = &g_driver;

	xge_hal_driver_debug_module_mask_set(XGE_DEBUG_MODULE_MASK_DEF);
	xge_hal_driver_debug_level_set(XGE_DEBUG_LEVEL_DEF);

#ifdef XGE_HAL_DEBUG_BAR0_OFFSET
	xge_hal_driver_bar0_offset_check();
#endif

#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
	if (config->tracebuf_size == 0)
	    /*
	     * Trace buffer implementation is not lock protected.
	     * The only harm to expect is memcpy() to go beyond of
	     * allowed boundaries. To make it safe (driver-wise),
	     * we pre-allocate needed number of extra bytes.
	     */
	    config->tracebuf_size = XGE_HAL_DEF_CIRCULAR_ARR +
	                XGE_OS_TRACE_MSGBUF_MAX;
#endif

	status = __hal_driver_config_check(config);
	if (status != XGE_HAL_OK)
	    return status;

	xge_os_memzero(g_xge_hal_driver,  sizeof(xge_hal_driver_t));

	/* apply config */
	xge_os_memcpy(&g_xge_hal_driver->config, config,
	            sizeof(xge_hal_driver_config_t));

	/* apply ULD callbacks */
	xge_os_memcpy(&g_xge_hal_driver->uld_callbacks, uld_callbacks,
	                sizeof(xge_hal_uld_cbs_t));

	g_xge_hal_driver->is_initialized = 1;

#ifdef XGE_TRACE_INTO_CIRCULAR_ARR
	g_tracebuf.size = config->tracebuf_size;
	g_tracebuf.data = (char *)xge_os_malloc(NULL, g_tracebuf.size);
	if (g_tracebuf.data == NULL) {
	    xge_os_printf("cannot allocate trace buffer!");
	    return XGE_HAL_ERR_OUT_OF_MEMORY;
	}
	/* timestamps disabled by default */
	g_tracebuf.timestamp = config->tracebuf_timestamp_en;
	if (g_tracebuf.timestamp) {
	    xge_os_timestamp(g_tracebuf.msg);
	    g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX -
	                xge_os_strlen(g_tracebuf.msg);
	} else
	    g_tracebuf.msgbuf_max = XGE_OS_TRACE_MSGBUF_MAX;
	g_tracebuf.offset = 0;
	*g_tracebuf.msg = 0;
	xge_os_memzero(g_tracebuf.data, g_tracebuf.size);
	g_xge_os_tracebuf = &g_tracebuf;
	dmesg = g_tracebuf.data;
	*dmesg = 0;
#endif
	return XGE_HAL_OK;
}
예제 #4
0
__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
__hal_fifo_dtr_post_single(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
	        u64 ctrl_1)
{
	xge_hal_fifo_t            *fifo    = (xge_hal_fifo_t *)channelh;
	xge_hal_fifo_hw_pair_t    *hw_pair = fifo->hw_pair;
	xge_hal_fifo_txd_t        *txdp    = (xge_hal_fifo_txd_t *)dtrh;
	xge_hal_fifo_txdl_priv_t  *txdl_priv;
	u64           ctrl;

	txdp->control_1 |= XGE_HAL_TXD_LIST_OWN_XENA;

#ifdef XGE_DEBUG_ASSERT
	    /* make sure Xena overwrites the (illegal) t_code value on completion */
	    XGE_HAL_SET_TXD_T_CODE(txdp->control_1, XGE_HAL_TXD_T_CODE_UNUSED_5);
#endif

	txdl_priv = __hal_fifo_txdl_priv(dtrh);

#if defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
	/* sync the TxDL to device */
	xge_os_dma_sync(fifo->channel.pdev,
	              txdl_priv->dma_handle,
	          txdl_priv->dma_addr,
	          txdl_priv->dma_offset,
	          txdl_priv->frags << 5 /* sizeof(xge_hal_fifo_txd_t) */,
	          XGE_OS_DMA_DIR_TODEVICE);
#endif
	/* write the pointer first */
	xge_os_pio_mem_write64(fifo->channel.pdev,
	             fifo->channel.regh1,
	                     txdl_priv->dma_addr,
	                     &hw_pair->txdl_pointer);

	/* spec: 0x00 = 1 TxD in the list */
	ctrl = XGE_HAL_TX_FIFO_LAST_TXD_NUM(txdl_priv->frags - 1);
	ctrl |= ctrl_1;
	ctrl |= fifo->no_snoop_bits;

	if (txdp->control_1 & XGE_HAL_TXD_LSO_COF_CTRL(XGE_HAL_TXD_TCP_LSO)) {
	    ctrl |= XGE_HAL_TX_FIFO_SPECIAL_FUNC;
	}

	/*
	 * according to the XENA spec:
	 *
	 * It is important to note that pointers and list control words are
	 * always written in pairs: in the first write, the host must write a
	 * pointer, and in the second write, it must write the list control
	 * word. Any other access will result in an error. Also, all 16 bytes
	 * of the pointer/control structure must be written, including any
	 * reserved bytes.
	 */
	xge_os_wmb();

	/*
	 * we want touch work_arr in order with ownership bit set to HW
	 */
	__hal_channel_dtr_post(channelh, dtrh);

	xge_os_pio_mem_write64(fifo->channel.pdev, fifo->channel.regh1,
	        ctrl, &hw_pair->list_control);

	xge_debug_fifo(XGE_TRACE, "posted txdl 0x"XGE_OS_LLXFMT" ctrl 0x"XGE_OS_LLXFMT" "
	    "into 0x"XGE_OS_LLXFMT"", (unsigned long long)txdl_priv->dma_addr,
	    (unsigned long long)ctrl,
	    (unsigned long long)(ulong_t)&hw_pair->txdl_pointer);

#ifdef XGE_HAL_FIFO_DUMP_TXD
	xge_os_printf(""XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"XGE_OS_LLXFMT":"
	    XGE_OS_LLXFMT" dma "XGE_OS_LLXFMT,
	    txdp->control_1, txdp->control_2, txdp->buffer_pointer,
	    txdp->host_control, txdl_priv->dma_addr);
#endif

	fifo->channel.stats.total_posts++;
	fifo->channel.usage_cnt++;
	if (fifo->channel.stats.usage_max < fifo->channel.usage_cnt)
	    fifo->channel.stats.usage_max = fifo->channel.usage_cnt;
}