diff options
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.c | 320 | ||||
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.h | 1 |
2 files changed, 180 insertions, 141 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 5f11b4dc95d2..30e1699649b8 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c | |||
@@ -110,6 +110,11 @@ static int ibmvnic_poll(struct napi_struct *napi, int data); | |||
110 | static void send_map_query(struct ibmvnic_adapter *adapter); | 110 | static void send_map_query(struct ibmvnic_adapter *adapter); |
111 | static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8); | 111 | static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8); |
112 | static void send_request_unmap(struct ibmvnic_adapter *, u8); | 112 | static void send_request_unmap(struct ibmvnic_adapter *, u8); |
113 | static void send_login(struct ibmvnic_adapter *adapter); | ||
114 | static void send_cap_queries(struct ibmvnic_adapter *adapter); | ||
115 | static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter); | ||
116 | static int ibmvnic_init(struct ibmvnic_adapter *); | ||
117 | static void ibmvnic_release_crq_queue(struct ibmvnic_adapter *); | ||
113 | 118 | ||
114 | struct ibmvnic_stat { | 119 | struct ibmvnic_stat { |
115 | char name[ETH_GSTRING_LEN]; | 120 | char name[ETH_GSTRING_LEN]; |
@@ -368,6 +373,38 @@ static void free_rx_pool(struct ibmvnic_adapter *adapter, | |||
368 | pool->rx_buff = NULL; | 373 | pool->rx_buff = NULL; |
369 | } | 374 | } |
370 | 375 | ||
376 | static int ibmvnic_login(struct net_device *netdev) | ||
377 | { | ||
378 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
379 | unsigned long timeout = msecs_to_jiffies(30000); | ||
380 | struct device *dev = &adapter->vdev->dev; | ||
381 | |||
382 | do { | ||
383 | if (adapter->renegotiate) { | ||
384 | adapter->renegotiate = false; | ||
385 | release_sub_crqs_no_irqs(adapter); | ||
386 | |||
387 | reinit_completion(&adapter->init_done); | ||
388 | send_cap_queries(adapter); | ||
389 | if (!wait_for_completion_timeout(&adapter->init_done, | ||
390 | timeout)) { | ||
391 | dev_err(dev, "Capabilities query timeout\n"); | ||
392 | return -1; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | reinit_completion(&adapter->init_done); | ||
397 | send_login(adapter); | ||
398 | if (!wait_for_completion_timeout(&adapter->init_done, | ||
399 | timeout)) { | ||
400 | dev_err(dev, "Login timeout\n"); | ||
401 | return -1; | ||
402 | } | ||
403 | } while (adapter->renegotiate); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
371 | static int ibmvnic_open(struct net_device *netdev) | 408 | static int ibmvnic_open(struct net_device *netdev) |
372 | { | 409 | { |
373 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 410 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
@@ -377,8 +414,31 @@ static int ibmvnic_open(struct net_device *netdev) | |||
377 | int rxadd_subcrqs; | 414 | int rxadd_subcrqs; |
378 | u64 *size_array; | 415 | u64 *size_array; |
379 | int tx_subcrqs; | 416 | int tx_subcrqs; |
417 | int rc = 0; | ||
380 | int i, j; | 418 | int i, j; |
381 | 419 | ||
420 | if (adapter->is_closed) { | ||
421 | rc = ibmvnic_init(adapter); | ||
422 | if (rc) | ||
423 | return rc; | ||
424 | } | ||
425 | |||
426 | rc = ibmvnic_login(netdev); | ||
427 | if (rc) | ||
428 | return rc; | ||
429 | |||
430 | rc = netif_set_real_num_tx_queues(netdev, adapter->req_tx_queues); | ||
431 | if (rc) { | ||
432 | dev_err(dev, "failed to set the number of tx queues\n"); | ||
433 | return -1; | ||
434 | } | ||
435 | |||
436 | rc = init_sub_crq_irqs(adapter); | ||
437 | if (rc) { | ||
438 | dev_err(dev, "failed to initialize sub crq irqs\n"); | ||
439 | return -1; | ||
440 | } | ||
441 | |||
382 | rxadd_subcrqs = | 442 | rxadd_subcrqs = |
383 | be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); | 443 | be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); |
384 | tx_subcrqs = | 444 | tx_subcrqs = |
@@ -473,6 +533,7 @@ static int ibmvnic_open(struct net_device *netdev) | |||
473 | ibmvnic_send_crq(adapter, &crq); | 533 | ibmvnic_send_crq(adapter, &crq); |
474 | 534 | ||
475 | netif_tx_start_all_queues(netdev); | 535 | netif_tx_start_all_queues(netdev); |
536 | adapter->is_closed = false; | ||
476 | 537 | ||
477 | return 0; | 538 | return 0; |
478 | 539 | ||
@@ -508,24 +569,16 @@ rx_pool_arr_alloc_failed: | |||
508 | for (i = 0; i < adapter->req_rx_queues; i++) | 569 | for (i = 0; i < adapter->req_rx_queues; i++) |
509 | napi_disable(&adapter->napi[i]); | 570 | napi_disable(&adapter->napi[i]); |
510 | alloc_napi_failed: | 571 | alloc_napi_failed: |
572 | release_sub_crqs(adapter); | ||
511 | return -ENOMEM; | 573 | return -ENOMEM; |
512 | } | 574 | } |
513 | 575 | ||
514 | static int ibmvnic_close(struct net_device *netdev) | 576 | static void ibmvnic_release_resources(struct ibmvnic_adapter *adapter) |
515 | { | 577 | { |
516 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
517 | struct device *dev = &adapter->vdev->dev; | 578 | struct device *dev = &adapter->vdev->dev; |
518 | union ibmvnic_crq crq; | 579 | int tx_scrqs, rx_scrqs; |
519 | int i; | 580 | int i; |
520 | 581 | ||
521 | adapter->closing = true; | ||
522 | |||
523 | for (i = 0; i < adapter->req_rx_queues; i++) | ||
524 | napi_disable(&adapter->napi[i]); | ||
525 | |||
526 | if (!adapter->failover) | ||
527 | netif_tx_stop_all_queues(netdev); | ||
528 | |||
529 | if (adapter->bounce_buffer) { | 582 | if (adapter->bounce_buffer) { |
530 | if (!dma_mapping_error(dev, adapter->bounce_buffer_dma)) { | 583 | if (!dma_mapping_error(dev, adapter->bounce_buffer_dma)) { |
531 | dma_unmap_single(&adapter->vdev->dev, | 584 | dma_unmap_single(&adapter->vdev->dev, |
@@ -538,33 +591,70 @@ static int ibmvnic_close(struct net_device *netdev) | |||
538 | adapter->bounce_buffer = NULL; | 591 | adapter->bounce_buffer = NULL; |
539 | } | 592 | } |
540 | 593 | ||
541 | memset(&crq, 0, sizeof(crq)); | 594 | tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); |
542 | crq.logical_link_state.first = IBMVNIC_CRQ_CMD; | 595 | for (i = 0; i < tx_scrqs; i++) { |
543 | crq.logical_link_state.cmd = LOGICAL_LINK_STATE; | 596 | struct ibmvnic_tx_pool *tx_pool = &adapter->tx_pool[i]; |
544 | crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_DN; | ||
545 | ibmvnic_send_crq(adapter, &crq); | ||
546 | 597 | ||
547 | for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); | 598 | kfree(tx_pool->tx_buff); |
548 | i++) { | 599 | free_long_term_buff(adapter, &tx_pool->long_term_buff); |
549 | kfree(adapter->tx_pool[i].tx_buff); | 600 | kfree(tx_pool->free_map); |
550 | free_long_term_buff(adapter, | ||
551 | &adapter->tx_pool[i].long_term_buff); | ||
552 | kfree(adapter->tx_pool[i].free_map); | ||
553 | } | 601 | } |
554 | kfree(adapter->tx_pool); | 602 | kfree(adapter->tx_pool); |
555 | adapter->tx_pool = NULL; | 603 | adapter->tx_pool = NULL; |
556 | 604 | ||
557 | for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); | 605 | rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); |
558 | i++) { | 606 | for (i = 0; i < rx_scrqs; i++) { |
559 | free_rx_pool(adapter, &adapter->rx_pool[i]); | 607 | struct ibmvnic_rx_pool *rx_pool = &adapter->rx_pool[i]; |
560 | free_long_term_buff(adapter, | 608 | |
561 | &adapter->rx_pool[i].long_term_buff); | 609 | free_rx_pool(adapter, rx_pool); |
610 | free_long_term_buff(adapter, &rx_pool->long_term_buff); | ||
562 | } | 611 | } |
563 | kfree(adapter->rx_pool); | 612 | kfree(adapter->rx_pool); |
564 | adapter->rx_pool = NULL; | 613 | adapter->rx_pool = NULL; |
565 | 614 | ||
566 | adapter->closing = false; | 615 | release_sub_crqs(adapter); |
616 | ibmvnic_release_crq_queue(adapter); | ||
567 | 617 | ||
618 | if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) | ||
619 | debugfs_remove_recursive(adapter->debugfs_dir); | ||
620 | |||
621 | if (adapter->stats_token) | ||
622 | dma_unmap_single(dev, adapter->stats_token, | ||
623 | sizeof(struct ibmvnic_statistics), | ||
624 | DMA_FROM_DEVICE); | ||
625 | |||
626 | if (adapter->ras_comps) | ||
627 | dma_free_coherent(dev, adapter->ras_comp_num * | ||
628 | sizeof(struct ibmvnic_fw_component), | ||
629 | adapter->ras_comps, adapter->ras_comps_tok); | ||
630 | |||
631 | kfree(adapter->ras_comp_int); | ||
632 | } | ||
633 | |||
634 | static int ibmvnic_close(struct net_device *netdev) | ||
635 | { | ||
636 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
637 | union ibmvnic_crq crq; | ||
638 | int i; | ||
639 | |||
640 | adapter->closing = true; | ||
641 | |||
642 | for (i = 0; i < adapter->req_rx_queues; i++) | ||
643 | napi_disable(&adapter->napi[i]); | ||
644 | |||
645 | if (!adapter->failover) | ||
646 | netif_tx_stop_all_queues(netdev); | ||
647 | |||
648 | memset(&crq, 0, sizeof(crq)); | ||
649 | crq.logical_link_state.first = IBMVNIC_CRQ_CMD; | ||
650 | crq.logical_link_state.cmd = LOGICAL_LINK_STATE; | ||
651 | crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_DN; | ||
652 | ibmvnic_send_crq(adapter, &crq); | ||
653 | |||
654 | ibmvnic_release_resources(adapter); | ||
655 | |||
656 | adapter->is_closed = true; | ||
657 | adapter->closing = false; | ||
568 | return 0; | 658 | return 0; |
569 | } | 659 | } |
570 | 660 | ||
@@ -3419,8 +3509,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, | |||
3419 | dma_unmap_single(dev, adapter->ip_offload_ctrl_tok, | 3509 | dma_unmap_single(dev, adapter->ip_offload_ctrl_tok, |
3420 | sizeof(adapter->ip_offload_ctrl), | 3510 | sizeof(adapter->ip_offload_ctrl), |
3421 | DMA_TO_DEVICE); | 3511 | DMA_TO_DEVICE); |
3422 | /* We're done with the queries, perform the login */ | 3512 | complete(&adapter->init_done); |
3423 | send_login(adapter); | ||
3424 | break; | 3513 | break; |
3425 | case REQUEST_RAS_COMP_NUM_RSP: | 3514 | case REQUEST_RAS_COMP_NUM_RSP: |
3426 | netdev_dbg(netdev, "Got Request RAS Comp Num Response\n"); | 3515 | netdev_dbg(netdev, "Got Request RAS Comp Num Response\n"); |
@@ -3700,26 +3789,6 @@ static void handle_crq_init_rsp(struct work_struct *work) | |||
3700 | goto task_failed; | 3789 | goto task_failed; |
3701 | } | 3790 | } |
3702 | 3791 | ||
3703 | do { | ||
3704 | if (adapter->renegotiate) { | ||
3705 | adapter->renegotiate = false; | ||
3706 | release_sub_crqs_no_irqs(adapter); | ||
3707 | |||
3708 | reinit_completion(&adapter->init_done); | ||
3709 | send_cap_queries(adapter); | ||
3710 | if (!wait_for_completion_timeout(&adapter->init_done, | ||
3711 | timeout)) { | ||
3712 | dev_err(dev, "Passive init timeout\n"); | ||
3713 | goto task_failed; | ||
3714 | } | ||
3715 | } | ||
3716 | } while (adapter->renegotiate); | ||
3717 | rc = init_sub_crq_irqs(adapter); | ||
3718 | |||
3719 | if (rc) | ||
3720 | goto task_failed; | ||
3721 | |||
3722 | netdev->real_num_tx_queues = adapter->req_tx_queues; | ||
3723 | netdev->mtu = adapter->req_mtu - ETH_HLEN; | 3792 | netdev->mtu = adapter->req_mtu - ETH_HLEN; |
3724 | 3793 | ||
3725 | if (adapter->failover) { | 3794 | if (adapter->failover) { |
@@ -3751,14 +3820,65 @@ task_failed: | |||
3751 | dev_err(dev, "Passive initialization was not successful\n"); | 3820 | dev_err(dev, "Passive initialization was not successful\n"); |
3752 | } | 3821 | } |
3753 | 3822 | ||
3754 | static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) | 3823 | static int ibmvnic_init(struct ibmvnic_adapter *adapter) |
3755 | { | 3824 | { |
3825 | struct device *dev = &adapter->vdev->dev; | ||
3756 | unsigned long timeout = msecs_to_jiffies(30000); | 3826 | unsigned long timeout = msecs_to_jiffies(30000); |
3827 | struct dentry *ent; | ||
3828 | char buf[17]; /* debugfs name buf */ | ||
3829 | int rc; | ||
3830 | |||
3831 | rc = ibmvnic_init_crq_queue(adapter); | ||
3832 | if (rc) { | ||
3833 | dev_err(dev, "Couldn't initialize crq. rc=%d\n", rc); | ||
3834 | return rc; | ||
3835 | } | ||
3836 | |||
3837 | adapter->stats_token = dma_map_single(dev, &adapter->stats, | ||
3838 | sizeof(struct ibmvnic_statistics), | ||
3839 | DMA_FROM_DEVICE); | ||
3840 | if (dma_mapping_error(dev, adapter->stats_token)) { | ||
3841 | ibmvnic_release_crq_queue(adapter); | ||
3842 | dev_err(dev, "Couldn't map stats buffer\n"); | ||
3843 | return -ENOMEM; | ||
3844 | } | ||
3845 | |||
3846 | snprintf(buf, sizeof(buf), "ibmvnic_%x", adapter->vdev->unit_address); | ||
3847 | ent = debugfs_create_dir(buf, NULL); | ||
3848 | if (!ent || IS_ERR(ent)) { | ||
3849 | dev_info(dev, "debugfs create directory failed\n"); | ||
3850 | adapter->debugfs_dir = NULL; | ||
3851 | } else { | ||
3852 | adapter->debugfs_dir = ent; | ||
3853 | ent = debugfs_create_file("dump", S_IRUGO, | ||
3854 | adapter->debugfs_dir, | ||
3855 | adapter->netdev, &ibmvnic_dump_ops); | ||
3856 | if (!ent || IS_ERR(ent)) { | ||
3857 | dev_info(dev, "debugfs create dump file failed\n"); | ||
3858 | adapter->debugfs_dump = NULL; | ||
3859 | } else { | ||
3860 | adapter->debugfs_dump = ent; | ||
3861 | } | ||
3862 | } | ||
3863 | |||
3864 | init_completion(&adapter->init_done); | ||
3865 | ibmvnic_send_crq_init(adapter); | ||
3866 | if (!wait_for_completion_timeout(&adapter->init_done, timeout)) { | ||
3867 | dev_err(dev, "Initialization sequence timed out\n"); | ||
3868 | if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) | ||
3869 | debugfs_remove_recursive(adapter->debugfs_dir); | ||
3870 | ibmvnic_release_crq_queue(adapter); | ||
3871 | return -1; | ||
3872 | } | ||
3873 | |||
3874 | return 0; | ||
3875 | } | ||
3876 | |||
3877 | static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) | ||
3878 | { | ||
3757 | struct ibmvnic_adapter *adapter; | 3879 | struct ibmvnic_adapter *adapter; |
3758 | struct net_device *netdev; | 3880 | struct net_device *netdev; |
3759 | unsigned char *mac_addr_p; | 3881 | unsigned char *mac_addr_p; |
3760 | struct dentry *ent; | ||
3761 | char buf[17]; /* debugfs name buf */ | ||
3762 | int rc; | 3882 | int rc; |
3763 | 3883 | ||
3764 | dev_dbg(&dev->dev, "entering ibmvnic_probe for UA 0x%x\n", | 3884 | dev_dbg(&dev->dev, "entering ibmvnic_probe for UA 0x%x\n", |
@@ -3796,118 +3916,36 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
3796 | 3916 | ||
3797 | spin_lock_init(&adapter->stats_lock); | 3917 | spin_lock_init(&adapter->stats_lock); |
3798 | 3918 | ||
3799 | rc = ibmvnic_init_crq_queue(adapter); | ||
3800 | if (rc) { | ||
3801 | dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n", rc); | ||
3802 | goto free_netdev; | ||
3803 | } | ||
3804 | |||
3805 | INIT_LIST_HEAD(&adapter->errors); | 3919 | INIT_LIST_HEAD(&adapter->errors); |
3806 | INIT_LIST_HEAD(&adapter->inflight); | 3920 | INIT_LIST_HEAD(&adapter->inflight); |
3807 | spin_lock_init(&adapter->error_list_lock); | 3921 | spin_lock_init(&adapter->error_list_lock); |
3808 | spin_lock_init(&adapter->inflight_lock); | 3922 | spin_lock_init(&adapter->inflight_lock); |
3809 | 3923 | ||
3810 | adapter->stats_token = dma_map_single(&dev->dev, &adapter->stats, | 3924 | rc = ibmvnic_init(adapter); |
3811 | sizeof(struct ibmvnic_statistics), | ||
3812 | DMA_FROM_DEVICE); | ||
3813 | if (dma_mapping_error(&dev->dev, adapter->stats_token)) { | ||
3814 | if (!firmware_has_feature(FW_FEATURE_CMO)) | ||
3815 | dev_err(&dev->dev, "Couldn't map stats buffer\n"); | ||
3816 | rc = -ENOMEM; | ||
3817 | goto free_crq; | ||
3818 | } | ||
3819 | |||
3820 | snprintf(buf, sizeof(buf), "ibmvnic_%x", dev->unit_address); | ||
3821 | ent = debugfs_create_dir(buf, NULL); | ||
3822 | if (!ent || IS_ERR(ent)) { | ||
3823 | dev_info(&dev->dev, "debugfs create directory failed\n"); | ||
3824 | adapter->debugfs_dir = NULL; | ||
3825 | } else { | ||
3826 | adapter->debugfs_dir = ent; | ||
3827 | ent = debugfs_create_file("dump", S_IRUGO, adapter->debugfs_dir, | ||
3828 | netdev, &ibmvnic_dump_ops); | ||
3829 | if (!ent || IS_ERR(ent)) { | ||
3830 | dev_info(&dev->dev, | ||
3831 | "debugfs create dump file failed\n"); | ||
3832 | adapter->debugfs_dump = NULL; | ||
3833 | } else { | ||
3834 | adapter->debugfs_dump = ent; | ||
3835 | } | ||
3836 | } | ||
3837 | |||
3838 | init_completion(&adapter->init_done); | ||
3839 | ibmvnic_send_crq_init(adapter); | ||
3840 | if (!wait_for_completion_timeout(&adapter->init_done, timeout)) | ||
3841 | return 0; | ||
3842 | |||
3843 | do { | ||
3844 | if (adapter->renegotiate) { | ||
3845 | adapter->renegotiate = false; | ||
3846 | release_sub_crqs_no_irqs(adapter); | ||
3847 | |||
3848 | reinit_completion(&adapter->init_done); | ||
3849 | send_cap_queries(adapter); | ||
3850 | if (!wait_for_completion_timeout(&adapter->init_done, | ||
3851 | timeout)) | ||
3852 | return 0; | ||
3853 | } | ||
3854 | } while (adapter->renegotiate); | ||
3855 | |||
3856 | rc = init_sub_crq_irqs(adapter); | ||
3857 | if (rc) { | 3925 | if (rc) { |
3858 | dev_err(&dev->dev, "failed to initialize sub crq irqs\n"); | 3926 | free_netdev(netdev); |
3859 | goto free_debugfs; | 3927 | return rc; |
3860 | } | 3928 | } |
3861 | 3929 | ||
3862 | netdev->real_num_tx_queues = adapter->req_tx_queues; | ||
3863 | netdev->mtu = adapter->req_mtu - ETH_HLEN; | 3930 | netdev->mtu = adapter->req_mtu - ETH_HLEN; |
3931 | adapter->is_closed = false; | ||
3864 | 3932 | ||
3865 | rc = register_netdev(netdev); | 3933 | rc = register_netdev(netdev); |
3866 | if (rc) { | 3934 | if (rc) { |
3867 | dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc); | 3935 | dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc); |
3868 | goto free_sub_crqs; | 3936 | free_netdev(netdev); |
3937 | return rc; | ||
3869 | } | 3938 | } |
3870 | dev_info(&dev->dev, "ibmvnic registered\n"); | 3939 | dev_info(&dev->dev, "ibmvnic registered\n"); |
3871 | 3940 | ||
3872 | return 0; | 3941 | return 0; |
3873 | |||
3874 | free_sub_crqs: | ||
3875 | release_sub_crqs(adapter); | ||
3876 | free_debugfs: | ||
3877 | if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) | ||
3878 | debugfs_remove_recursive(adapter->debugfs_dir); | ||
3879 | free_crq: | ||
3880 | ibmvnic_release_crq_queue(adapter); | ||
3881 | free_netdev: | ||
3882 | free_netdev(netdev); | ||
3883 | return rc; | ||
3884 | } | 3942 | } |
3885 | 3943 | ||
3886 | static int ibmvnic_remove(struct vio_dev *dev) | 3944 | static int ibmvnic_remove(struct vio_dev *dev) |
3887 | { | 3945 | { |
3888 | struct net_device *netdev = dev_get_drvdata(&dev->dev); | 3946 | struct net_device *netdev = dev_get_drvdata(&dev->dev); |
3889 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
3890 | 3947 | ||
3891 | unregister_netdev(netdev); | 3948 | unregister_netdev(netdev); |
3892 | |||
3893 | release_sub_crqs(adapter); | ||
3894 | |||
3895 | ibmvnic_release_crq_queue(adapter); | ||
3896 | |||
3897 | if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) | ||
3898 | debugfs_remove_recursive(adapter->debugfs_dir); | ||
3899 | |||
3900 | dma_unmap_single(&dev->dev, adapter->stats_token, | ||
3901 | sizeof(struct ibmvnic_statistics), DMA_FROM_DEVICE); | ||
3902 | |||
3903 | if (adapter->ras_comps) | ||
3904 | dma_free_coherent(&dev->dev, | ||
3905 | adapter->ras_comp_num * | ||
3906 | sizeof(struct ibmvnic_fw_component), | ||
3907 | adapter->ras_comps, adapter->ras_comps_tok); | ||
3908 | |||
3909 | kfree(adapter->ras_comp_int); | ||
3910 | |||
3911 | free_netdev(netdev); | 3949 | free_netdev(netdev); |
3912 | dev_set_drvdata(&dev->dev, NULL); | 3950 | dev_set_drvdata(&dev->dev, NULL); |
3913 | 3951 | ||
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 1993b42666f7..10ad259208cb 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h | |||
@@ -1052,4 +1052,5 @@ struct ibmvnic_adapter { | |||
1052 | struct work_struct ibmvnic_xport; | 1052 | struct work_struct ibmvnic_xport; |
1053 | struct tasklet_struct tasklet; | 1053 | struct tasklet_struct tasklet; |
1054 | bool failover; | 1054 | bool failover; |
1055 | bool is_closed; | ||
1055 | }; | 1056 | }; |