Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/ena/ena.c
Show First 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | |||||
static int ena_request_mgmnt_irq(struct ena_adapter *); | static int ena_request_mgmnt_irq(struct ena_adapter *); | ||||
static int ena_request_io_irq(struct ena_adapter *); | static int ena_request_io_irq(struct ena_adapter *); | ||||
static void ena_free_mgmnt_irq(struct ena_adapter *); | static void ena_free_mgmnt_irq(struct ena_adapter *); | ||||
static void ena_free_io_irq(struct ena_adapter *); | static void ena_free_io_irq(struct ena_adapter *); | ||||
static void ena_free_irqs(struct ena_adapter*); | static void ena_free_irqs(struct ena_adapter*); | ||||
static void ena_disable_msix(struct ena_adapter *); | static void ena_disable_msix(struct ena_adapter *); | ||||
static void ena_unmask_all_io_irqs(struct ena_adapter *); | static void ena_unmask_all_io_irqs(struct ena_adapter *); | ||||
static int ena_rss_configure(struct ena_adapter *); | static int ena_rss_configure(struct ena_adapter *); | ||||
static void ena_update_hw_stats(void *, int); | |||||
static int ena_up_complete(struct ena_adapter *); | static int ena_up_complete(struct ena_adapter *); | ||||
static int ena_up(struct ena_adapter *); | static int ena_up(struct ena_adapter *); | ||||
static void ena_down(struct ena_adapter *); | static void ena_down(struct ena_adapter *); | ||||
static uint64_t ena_get_counter(if_t, ift_counter); | static uint64_t ena_get_counter(if_t, ift_counter); | ||||
static int ena_media_change(if_t); | static int ena_media_change(if_t); | ||||
static void ena_media_status(if_t, struct ifmediareq *); | static void ena_media_status(if_t, struct ifmediareq *); | ||||
static void ena_init(void *); | static void ena_init(void *); | ||||
static int ena_ioctl(if_t, u_long, caddr_t); | static int ena_ioctl(if_t, u_long, caddr_t); | ||||
▲ Show 20 Lines • Show All 1,901 Lines • ▼ Show 20 Lines | static int ena_rss_configure(struct ena_adapter *adapter) | ||||
/* Configure hash inputs (if supported) */ | /* Configure hash inputs (if supported) */ | ||||
rc = ena_com_set_hash_ctrl(ena_dev); | rc = ena_com_set_hash_ctrl(ena_dev); | ||||
if (unlikely(rc && (rc != EPERM))) | if (unlikely(rc && (rc != EPERM))) | ||||
return rc; | return rc; | ||||
return 0; | return 0; | ||||
} | } | ||||
static void | |||||
ena_update_hw_stats(void *arg, int pending) | |||||
{ | |||||
struct ena_adapter *adapter = arg; | |||||
int rc; | |||||
for (;;) { | |||||
if (!adapter->up) | |||||
return; | |||||
rc = ena_update_stats_counters(adapter); | |||||
if (rc) | |||||
ena_trace(ENA_WARNING, | |||||
"Error updating stats counters, rc = %d", rc); | |||||
pause("ena update hw stats", hz); | |||||
} | |||||
} | |||||
static int | static int | ||||
ena_up_complete(struct ena_adapter *adapter) | ena_up_complete(struct ena_adapter *adapter) | ||||
{ | { | ||||
int rc; | int rc; | ||||
if (adapter->rss_support) { | if (adapter->rss_support) { | ||||
rc = ena_rss_configure(adapter); | rc = ena_rss_configure(adapter); | ||||
if (rc) | if (rc) | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | if (!adapter->up) { | ||||
ena_update_hwassist(adapter); | ena_update_hwassist(adapter); | ||||
if_setdrvflagbits(adapter->ifp, IFF_DRV_RUNNING, | if_setdrvflagbits(adapter->ifp, IFF_DRV_RUNNING, | ||||
IFF_DRV_OACTIVE); | IFF_DRV_OACTIVE); | ||||
callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S, | callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S, | ||||
ena_timer_service, (void *)adapter, 0); | ena_timer_service, (void *)adapter, 0); | ||||
taskqueue_enqueue(adapter->stats_tq, &adapter->stats_task); | |||||
adapter->up = true; | adapter->up = true; | ||||
} | } | ||||
return (0); | return (0); | ||||
err_up_complete: | err_up_complete: | ||||
ena_destroy_all_io_queues(adapter); | ena_destroy_all_io_queues(adapter); | ||||
err_io_que: | err_io_que: | ||||
Show All 36 Lines | ena_update_stats_counters(struct ena_adapter *adapter) | ||||
return (0); | return (0); | ||||
} | } | ||||
static uint64_t | static uint64_t | ||||
ena_get_counter(if_t ifp, ift_counter cnt) | ena_get_counter(if_t ifp, ift_counter cnt) | ||||
{ | { | ||||
struct ena_adapter *adapter; | struct ena_adapter *adapter; | ||||
struct ena_hw_stats *stats; | struct ena_hw_stats *stats; | ||||
int rc; | |||||
adapter = if_getsoftc(ifp); | adapter = if_getsoftc(ifp); | ||||
/* | |||||
* Update only when asking for first counter and interface is up. | |||||
* Usually asks for all statistics in sequence. | |||||
*/ | |||||
if (adapter->up) { | |||||
if (cnt == 0) { | |||||
rc = ena_update_stats_counters(adapter); | |||||
if (rc) { | |||||
ena_trace(ENA_WARNING, | |||||
"Error updating stats counters, rc = %d", | |||||
rc); | |||||
} | |||||
} | |||||
} | |||||
stats = &adapter->hw_stats; | stats = &adapter->hw_stats; | ||||
switch (cnt) { | switch (cnt) { | ||||
case IFCOUNTER_IPACKETS: | case IFCOUNTER_IPACKETS: | ||||
return (stats->rx_packets); | return (stats->rx_packets); | ||||
case IFCOUNTER_OPACKETS: | case IFCOUNTER_OPACKETS: | ||||
return (stats->tx_packets); | return (stats->tx_packets); | ||||
case IFCOUNTER_IBYTES: | case IFCOUNTER_IBYTES: | ||||
▲ Show 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | if (adapter->up) { | ||||
device_printf(adapter->pdev, "device is going DOWN\n"); | device_printf(adapter->pdev, "device is going DOWN\n"); | ||||
callout_drain(&adapter->timer_service); | callout_drain(&adapter->timer_service); | ||||
adapter->up = false; | adapter->up = false; | ||||
if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, | if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, | ||||
IFF_DRV_RUNNING); | IFF_DRV_RUNNING); | ||||
/* Drain task responsible for updating hw stats */ | |||||
while (taskqueue_cancel(adapter->stats_tq, &adapter->stats_task, NULL)) | |||||
taskqueue_drain(adapter->stats_tq, &adapter->stats_task); | |||||
ena_free_io_irq(adapter); | ena_free_io_irq(adapter); | ||||
ena_destroy_all_io_queues(adapter); | ena_destroy_all_io_queues(adapter); | ||||
ena_free_all_tx_bufs(adapter); | ena_free_all_tx_bufs(adapter); | ||||
ena_free_all_rx_bufs(adapter); | ena_free_all_rx_bufs(adapter); | ||||
ena_free_all_tx_resources(adapter); | ena_free_all_tx_resources(adapter); | ||||
ena_free_all_rx_resources(adapter); | ena_free_all_rx_resources(adapter); | ||||
▲ Show 20 Lines • Show All 1,099 Lines • ▼ Show 20 Lines | ena_attach(device_t pdev) | ||||
if (adapter->reset_tq == NULL) { | if (adapter->reset_tq == NULL) { | ||||
device_printf(adapter->pdev, | device_printf(adapter->pdev, | ||||
"Unable to create reset task queue\n"); | "Unable to create reset task queue\n"); | ||||
goto err_reset_tq; | goto err_reset_tq; | ||||
} | } | ||||
taskqueue_start_threads(&adapter->reset_tq, 1, PI_NET, | taskqueue_start_threads(&adapter->reset_tq, 1, PI_NET, | ||||
"%s rstq", device_get_nameunit(adapter->pdev)); | "%s rstq", device_get_nameunit(adapter->pdev)); | ||||
/* Initialize task queue responsible for updating hw stats */ | |||||
TASK_INIT(&adapter->stats_task, 0, ena_update_hw_stats, adapter); | |||||
adapter->stats_tq = taskqueue_create_fast("ena_stats_update", | |||||
M_WAITOK | M_ZERO, taskqueue_thread_enqueue, &adapter->stats_tq); | |||||
if (adapter->stats_tq == NULL) { | |||||
device_printf(adapter->pdev, | |||||
"Unable to create taskqueue for updating hw stats\n"); | |||||
goto err_stats_tq; | |||||
} | |||||
taskqueue_start_threads(&adapter->stats_tq, 1, PI_REALTIME, | |||||
"%s stats tq", device_get_nameunit(adapter->pdev)); | |||||
/* Initialize statistics */ | /* Initialize statistics */ | ||||
ena_alloc_counters((counter_u64_t *)&adapter->dev_stats, | ena_alloc_counters((counter_u64_t *)&adapter->dev_stats, | ||||
sizeof(struct ena_stats_dev)); | sizeof(struct ena_stats_dev)); | ||||
ena_update_stats_counters(adapter); | ena_update_stats_counters(adapter); | ||||
ena_sysctl_add_nodes(adapter); | ena_sysctl_add_nodes(adapter); | ||||
/* Tell the stack that the interface is not active */ | /* Tell the stack that the interface is not active */ | ||||
if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); | if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); | ||||
adapter->running = true; | adapter->running = true; | ||||
return (0); | return (0); | ||||
err_stats_tq: | |||||
taskqueue_free(adapter->reset_tq); | |||||
err_reset_tq: | err_reset_tq: | ||||
ena_free_mgmnt_irq(adapter); | ena_free_mgmnt_irq(adapter); | ||||
ena_disable_msix(adapter); | ena_disable_msix(adapter); | ||||
err_ifp_free: | err_ifp_free: | ||||
if_detach(adapter->ifp); | if_detach(adapter->ifp); | ||||
if_free(adapter->ifp); | if_free(adapter->ifp); | ||||
err_com_free: | err_com_free: | ||||
ena_free_all_io_rings_resources(adapter); | ena_free_all_io_rings_resources(adapter); | ||||
Show All 38 Lines | ena_detach(device_t pdev) | ||||
callout_drain(&adapter->timer_service); | callout_drain(&adapter->timer_service); | ||||
while (taskqueue_cancel(adapter->reset_tq, &adapter->reset_task, NULL)) | while (taskqueue_cancel(adapter->reset_tq, &adapter->reset_task, NULL)) | ||||
taskqueue_drain(adapter->reset_tq, &adapter->reset_task); | taskqueue_drain(adapter->reset_tq, &adapter->reset_task); | ||||
taskqueue_free(adapter->reset_tq); | taskqueue_free(adapter->reset_tq); | ||||
sx_xlock(&adapter->ioctl_sx); | sx_xlock(&adapter->ioctl_sx); | ||||
ena_down(adapter); | ena_down(adapter); | ||||
sx_unlock(&adapter->ioctl_sx); | sx_unlock(&adapter->ioctl_sx); | ||||
taskqueue_free(adapter->stats_tq); | |||||
if (adapter->ifp != NULL) { | if (adapter->ifp != NULL) { | ||||
ether_ifdetach(adapter->ifp); | ether_ifdetach(adapter->ifp); | ||||
if_free(adapter->ifp); | if_free(adapter->ifp); | ||||
} | } | ||||
ena_free_all_io_rings_resources(adapter); | ena_free_all_io_rings_resources(adapter); | ||||
▲ Show 20 Lines • Show All 119 Lines • Show Last 20 Lines |