diff options
Diffstat (limited to 'drivers/net/ethernet/ibm/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ethernet/ibm/ehea/ehea_main.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 583bcd32e54..c821cb65399 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
@@ -331,16 +331,40 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) | |||
331 | { | 331 | { |
332 | struct ehea_port *port = netdev_priv(dev); | 332 | struct ehea_port *port = netdev_priv(dev); |
333 | struct net_device_stats *stats = &port->stats; | 333 | struct net_device_stats *stats = &port->stats; |
334 | struct hcp_ehea_port_cb2 *cb2; | 334 | u64 rx_packets = 0, tx_packets = 0, rx_bytes = 0, tx_bytes = 0; |
335 | u64 hret, rx_packets, tx_packets, rx_bytes = 0, tx_bytes = 0; | ||
336 | int i; | 335 | int i; |
337 | 336 | ||
338 | memset(stats, 0, sizeof(*stats)); | 337 | for (i = 0; i < port->num_def_qps; i++) { |
338 | rx_packets += port->port_res[i].rx_packets; | ||
339 | rx_bytes += port->port_res[i].rx_bytes; | ||
340 | } | ||
341 | |||
342 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
343 | tx_packets += port->port_res[i].tx_packets; | ||
344 | tx_bytes += port->port_res[i].tx_bytes; | ||
345 | } | ||
346 | |||
347 | stats->tx_packets = tx_packets; | ||
348 | stats->rx_bytes = rx_bytes; | ||
349 | stats->tx_bytes = tx_bytes; | ||
350 | stats->rx_packets = rx_packets; | ||
351 | |||
352 | return &port->stats; | ||
353 | } | ||
354 | |||
355 | static void ehea_update_stats(struct work_struct *work) | ||
356 | { | ||
357 | struct ehea_port *port = | ||
358 | container_of(work, struct ehea_port, stats_work.work); | ||
359 | struct net_device *dev = port->netdev; | ||
360 | struct net_device_stats *stats = &port->stats; | ||
361 | struct hcp_ehea_port_cb2 *cb2; | ||
362 | u64 hret; | ||
339 | 363 | ||
340 | cb2 = (void *)get_zeroed_page(GFP_KERNEL); | 364 | cb2 = (void *)get_zeroed_page(GFP_KERNEL); |
341 | if (!cb2) { | 365 | if (!cb2) { |
342 | netdev_err(dev, "no mem for cb2\n"); | 366 | netdev_err(dev, "No mem for cb2. Some interface statistics were not updated\n"); |
343 | goto out; | 367 | goto resched; |
344 | } | 368 | } |
345 | 369 | ||
346 | hret = ehea_h_query_ehea_port(port->adapter->handle, | 370 | hret = ehea_h_query_ehea_port(port->adapter->handle, |
@@ -354,29 +378,13 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) | |||
354 | if (netif_msg_hw(port)) | 378 | if (netif_msg_hw(port)) |
355 | ehea_dump(cb2, sizeof(*cb2), "net_device_stats"); | 379 | ehea_dump(cb2, sizeof(*cb2), "net_device_stats"); |
356 | 380 | ||
357 | rx_packets = 0; | ||
358 | for (i = 0; i < port->num_def_qps; i++) { | ||
359 | rx_packets += port->port_res[i].rx_packets; | ||
360 | rx_bytes += port->port_res[i].rx_bytes; | ||
361 | } | ||
362 | |||
363 | tx_packets = 0; | ||
364 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
365 | tx_packets += port->port_res[i].tx_packets; | ||
366 | tx_bytes += port->port_res[i].tx_bytes; | ||
367 | } | ||
368 | |||
369 | stats->tx_packets = tx_packets; | ||
370 | stats->multicast = cb2->rxmcp; | 381 | stats->multicast = cb2->rxmcp; |
371 | stats->rx_errors = cb2->rxuerr; | 382 | stats->rx_errors = cb2->rxuerr; |
372 | stats->rx_bytes = rx_bytes; | ||
373 | stats->tx_bytes = tx_bytes; | ||
374 | stats->rx_packets = rx_packets; | ||
375 | 383 | ||
376 | out_herr: | 384 | out_herr: |
377 | free_page((unsigned long)cb2); | 385 | free_page((unsigned long)cb2); |
378 | out: | 386 | resched: |
379 | return stats; | 387 | schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000)); |
380 | } | 388 | } |
381 | 389 | ||
382 | static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) | 390 | static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) |
@@ -2651,6 +2659,7 @@ static int ehea_open(struct net_device *dev) | |||
2651 | } | 2659 | } |
2652 | 2660 | ||
2653 | mutex_unlock(&port->port_lock); | 2661 | mutex_unlock(&port->port_lock); |
2662 | schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000)); | ||
2654 | 2663 | ||
2655 | return ret; | 2664 | return ret; |
2656 | } | 2665 | } |
@@ -2690,6 +2699,7 @@ static int ehea_stop(struct net_device *dev) | |||
2690 | 2699 | ||
2691 | set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); | 2700 | set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); |
2692 | cancel_work_sync(&port->reset_task); | 2701 | cancel_work_sync(&port->reset_task); |
2702 | cancel_delayed_work_sync(&port->stats_work); | ||
2693 | mutex_lock(&port->port_lock); | 2703 | mutex_lock(&port->port_lock); |
2694 | netif_stop_queue(dev); | 2704 | netif_stop_queue(dev); |
2695 | port_napi_disable(port); | 2705 | port_napi_disable(port); |
@@ -3235,10 +3245,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
3235 | dev->features |= NETIF_F_LRO; | 3245 | dev->features |= NETIF_F_LRO; |
3236 | 3246 | ||
3237 | INIT_WORK(&port->reset_task, ehea_reset_port); | 3247 | INIT_WORK(&port->reset_task, ehea_reset_port); |
3248 | INIT_DELAYED_WORK(&port->stats_work, ehea_update_stats); | ||
3238 | 3249 | ||
3239 | init_waitqueue_head(&port->swqe_avail_wq); | 3250 | init_waitqueue_head(&port->swqe_avail_wq); |
3240 | init_waitqueue_head(&port->restart_wq); | 3251 | init_waitqueue_head(&port->restart_wq); |
3241 | 3252 | ||
3253 | memset(&port->stats, 0, sizeof(struct net_device_stats)); | ||
3242 | ret = register_netdev(dev); | 3254 | ret = register_netdev(dev); |
3243 | if (ret) { | 3255 | if (ret) { |
3244 | pr_err("register_netdev failed. ret=%d\n", ret); | 3256 | pr_err("register_netdev failed. ret=%d\n", ret); |
@@ -3278,6 +3290,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port) | |||
3278 | struct ehea_adapter *adapter = port->adapter; | 3290 | struct ehea_adapter *adapter = port->adapter; |
3279 | 3291 | ||
3280 | cancel_work_sync(&port->reset_task); | 3292 | cancel_work_sync(&port->reset_task); |
3293 | cancel_delayed_work_sync(&port->stats_work); | ||
3281 | unregister_netdev(port->netdev); | 3294 | unregister_netdev(port->netdev); |
3282 | ehea_unregister_port(port); | 3295 | ehea_unregister_port(port); |
3283 | kfree(port->mc_list); | 3296 | kfree(port->mc_list); |