diff options
author | Amit Kumar Salecha <amit.salecha@qlogic.com> | 2010-06-21 23:19:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-23 16:16:30 -0400 |
commit | 8a15ad1fb14d67450742cf975a76e744b3189f4d (patch) | |
tree | d64402cdeec98e3838d8c73924db199a294ba845 /drivers/net/qlcnic/qlcnic_main.c | |
parent | 42f65cbad4168958dff8a307bfe4b528409951d3 (diff) |
qlcnic: release device resources during interface down
Previously we were allocating device resources during probe and
release them during remove.
Now alloc during interface up and release in interface down.
This helps in device performance, as it doesn't need to keep
track of inactive resources.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 9658b1849386..38d8fe08b7ff 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -346,7 +346,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) | |||
346 | if (!is_valid_ether_addr(addr->sa_data)) | 346 | if (!is_valid_ether_addr(addr->sa_data)) |
347 | return -EINVAL; | 347 | return -EINVAL; |
348 | 348 | ||
349 | if (netif_running(netdev)) { | 349 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { |
350 | netif_device_detach(netdev); | 350 | netif_device_detach(netdev); |
351 | qlcnic_napi_disable(adapter); | 351 | qlcnic_napi_disable(adapter); |
352 | } | 352 | } |
@@ -355,7 +355,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) | |||
355 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 355 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
356 | qlcnic_set_multi(adapter->netdev); | 356 | qlcnic_set_multi(adapter->netdev); |
357 | 357 | ||
358 | if (netif_running(netdev)) { | 358 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { |
359 | netif_device_attach(netdev); | 359 | netif_device_attach(netdev); |
360 | qlcnic_napi_enable(adapter); | 360 | qlcnic_napi_enable(adapter); |
361 | } | 361 | } |
@@ -877,9 +877,23 @@ qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter) | |||
877 | static int | 877 | static int |
878 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | 878 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) |
879 | { | 879 | { |
880 | int ring; | ||
881 | struct qlcnic_host_rds_ring *rds_ring; | ||
882 | |||
880 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 883 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) |
881 | return -EIO; | 884 | return -EIO; |
882 | 885 | ||
886 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) | ||
887 | return 0; | ||
888 | |||
889 | if (qlcnic_fw_create_ctx(adapter)) | ||
890 | return -EIO; | ||
891 | |||
892 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
893 | rds_ring = &adapter->recv_ctx.rds_rings[ring]; | ||
894 | qlcnic_post_rx_buffers(adapter, ring, rds_ring); | ||
895 | } | ||
896 | |||
883 | qlcnic_set_multi(netdev); | 897 | qlcnic_set_multi(netdev); |
884 | qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); | 898 | qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); |
885 | 899 | ||
@@ -936,6 +950,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
936 | 950 | ||
937 | qlcnic_napi_disable(adapter); | 951 | qlcnic_napi_disable(adapter); |
938 | 952 | ||
953 | qlcnic_fw_destroy_ctx(adapter); | ||
954 | |||
955 | qlcnic_reset_rx_buffers_list(adapter); | ||
939 | qlcnic_release_tx_buffers(adapter); | 956 | qlcnic_release_tx_buffers(adapter); |
940 | spin_unlock(&adapter->tx_clean_lock); | 957 | spin_unlock(&adapter->tx_clean_lock); |
941 | } | 958 | } |
@@ -957,13 +974,11 @@ qlcnic_attach(struct qlcnic_adapter *adapter) | |||
957 | { | 974 | { |
958 | struct net_device *netdev = adapter->netdev; | 975 | struct net_device *netdev = adapter->netdev; |
959 | struct pci_dev *pdev = adapter->pdev; | 976 | struct pci_dev *pdev = adapter->pdev; |
960 | int err, ring; | 977 | int err; |
961 | struct qlcnic_host_rds_ring *rds_ring; | ||
962 | 978 | ||
963 | if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) | 979 | if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) |
964 | return 0; | 980 | return 0; |
965 | 981 | ||
966 | |||
967 | err = qlcnic_napi_add(adapter, netdev); | 982 | err = qlcnic_napi_add(adapter, netdev); |
968 | if (err) | 983 | if (err) |
969 | return err; | 984 | return err; |
@@ -971,7 +986,7 @@ qlcnic_attach(struct qlcnic_adapter *adapter) | |||
971 | err = qlcnic_alloc_sw_resources(adapter); | 986 | err = qlcnic_alloc_sw_resources(adapter); |
972 | if (err) { | 987 | if (err) { |
973 | dev_err(&pdev->dev, "Error in setting sw resources\n"); | 988 | dev_err(&pdev->dev, "Error in setting sw resources\n"); |
974 | return err; | 989 | goto err_out_napi_del; |
975 | } | 990 | } |
976 | 991 | ||
977 | err = qlcnic_alloc_hw_resources(adapter); | 992 | err = qlcnic_alloc_hw_resources(adapter); |
@@ -980,16 +995,10 @@ qlcnic_attach(struct qlcnic_adapter *adapter) | |||
980 | goto err_out_free_sw; | 995 | goto err_out_free_sw; |
981 | } | 996 | } |
982 | 997 | ||
983 | |||
984 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
985 | rds_ring = &adapter->recv_ctx.rds_rings[ring]; | ||
986 | qlcnic_post_rx_buffers(adapter, ring, rds_ring); | ||
987 | } | ||
988 | |||
989 | err = qlcnic_request_irq(adapter); | 998 | err = qlcnic_request_irq(adapter); |
990 | if (err) { | 999 | if (err) { |
991 | dev_err(&pdev->dev, "failed to setup interrupt\n"); | 1000 | dev_err(&pdev->dev, "failed to setup interrupt\n"); |
992 | goto err_out_free_rxbuf; | 1001 | goto err_out_free_hw; |
993 | } | 1002 | } |
994 | 1003 | ||
995 | qlcnic_init_coalesce_defaults(adapter); | 1004 | qlcnic_init_coalesce_defaults(adapter); |
@@ -999,11 +1008,12 @@ qlcnic_attach(struct qlcnic_adapter *adapter) | |||
999 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; | 1008 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; |
1000 | return 0; | 1009 | return 0; |
1001 | 1010 | ||
1002 | err_out_free_rxbuf: | 1011 | err_out_free_hw: |
1003 | qlcnic_release_rx_buffers(adapter); | ||
1004 | qlcnic_free_hw_resources(adapter); | 1012 | qlcnic_free_hw_resources(adapter); |
1005 | err_out_free_sw: | 1013 | err_out_free_sw: |
1006 | qlcnic_free_sw_resources(adapter); | 1014 | qlcnic_free_sw_resources(adapter); |
1015 | err_out_napi_del: | ||
1016 | qlcnic_napi_del(adapter); | ||
1007 | return err; | 1017 | return err; |
1008 | } | 1018 | } |
1009 | 1019 | ||
@@ -1038,6 +1048,8 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) | |||
1038 | } | 1048 | } |
1039 | } | 1049 | } |
1040 | 1050 | ||
1051 | qlcnic_fw_destroy_ctx(adapter); | ||
1052 | |||
1041 | qlcnic_detach(adapter); | 1053 | qlcnic_detach(adapter); |
1042 | 1054 | ||
1043 | adapter->diag_test = 0; | 1055 | adapter->diag_test = 0; |
@@ -1056,6 +1068,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) | |||
1056 | { | 1068 | { |
1057 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1069 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1058 | struct qlcnic_host_sds_ring *sds_ring; | 1070 | struct qlcnic_host_sds_ring *sds_ring; |
1071 | struct qlcnic_host_rds_ring *rds_ring; | ||
1059 | int ring; | 1072 | int ring; |
1060 | int ret; | 1073 | int ret; |
1061 | 1074 | ||
@@ -1075,6 +1088,17 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) | |||
1075 | return ret; | 1088 | return ret; |
1076 | } | 1089 | } |
1077 | 1090 | ||
1091 | ret = qlcnic_fw_create_ctx(adapter); | ||
1092 | if (ret) { | ||
1093 | qlcnic_detach(adapter); | ||
1094 | return ret; | ||
1095 | } | ||
1096 | |||
1097 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | ||
1098 | rds_ring = &adapter->recv_ctx.rds_rings[ring]; | ||
1099 | qlcnic_post_rx_buffers(adapter, ring, rds_ring); | ||
1100 | } | ||
1101 | |||
1078 | if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { | 1102 | if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { |
1079 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 1103 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
1080 | sds_ring = &adapter->recv_ctx.sds_rings[ring]; | 1104 | sds_ring = &adapter->recv_ctx.sds_rings[ring]; |
@@ -2636,7 +2660,7 @@ qlcnic_store_bridged_mode(struct device *dev, | |||
2636 | if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)) | 2660 | if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG)) |
2637 | goto err_out; | 2661 | goto err_out; |
2638 | 2662 | ||
2639 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 2663 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) |
2640 | goto err_out; | 2664 | goto err_out; |
2641 | 2665 | ||
2642 | if (strict_strtoul(buf, 2, &new)) | 2666 | if (strict_strtoul(buf, 2, &new)) |
@@ -2944,7 +2968,7 @@ recheck: | |||
2944 | if (!adapter) | 2968 | if (!adapter) |
2945 | goto done; | 2969 | goto done; |
2946 | 2970 | ||
2947 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 2971 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) |
2948 | goto done; | 2972 | goto done; |
2949 | 2973 | ||
2950 | qlcnic_config_indev_addr(dev, event); | 2974 | qlcnic_config_indev_addr(dev, event); |
@@ -2980,7 +3004,7 @@ recheck: | |||
2980 | if (!adapter) | 3004 | if (!adapter) |
2981 | goto done; | 3005 | goto done; |
2982 | 3006 | ||
2983 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 3007 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) |
2984 | goto done; | 3008 | goto done; |
2985 | 3009 | ||
2986 | switch (event) { | 3010 | switch (event) { |