/** * 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 ###############"); }
/** * 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 }
/** * 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; }
__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; }