diff options
-rw-r--r-- | drivers/net/ehea/ehea.h | 3 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 95 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_phyp.c | 6 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_phyp.h | 6 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_qmr.c | 184 | ||||
-rw-r--r-- | drivers/net/ehea/ehea_qmr.h | 7 |
6 files changed, 187 insertions, 114 deletions
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 1fefb2dddc12..f8899339baa0 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ehea" | 41 | #define DRV_NAME "ehea" |
42 | #define DRV_VERSION "EHEA_0053" | 42 | #define DRV_VERSION "EHEA_0054" |
43 | 43 | ||
44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | 44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ |
45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
@@ -309,6 +309,7 @@ struct ehea_cq { | |||
309 | * Memory Region | 309 | * Memory Region |
310 | */ | 310 | */ |
311 | struct ehea_mr { | 311 | struct ehea_mr { |
312 | struct ehea_adapter *adapter; | ||
312 | u64 handle; | 313 | u64 handle; |
313 | u64 vaddr; | 314 | u64 vaddr; |
314 | u32 lkey; | 315 | u32 lkey; |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index db0d79ebae81..8bceb4e6bb82 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -546,19 +546,19 @@ static int ehea_poll(struct net_device *dev, int *budget) | |||
546 | cqe = ehea_poll_rq1(pr->qp, &wqe_index); | 546 | cqe = ehea_poll_rq1(pr->qp, &wqe_index); |
547 | cqe_skb = ehea_poll_cq(pr->send_cq); | 547 | cqe_skb = ehea_poll_cq(pr->send_cq); |
548 | 548 | ||
549 | if (!cqe && !cqe_skb) | 549 | if (!cqe && !cqe_skb) |
550 | return 0; | 550 | return 0; |
551 | 551 | ||
552 | if (!netif_rx_reschedule(dev, dev->quota)) | 552 | if (!netif_rx_reschedule(dev, dev->quota)) |
553 | return 0; | 553 | return 0; |
554 | } | 554 | } |
555 | 555 | ||
556 | cqe = ehea_proc_rwqes(dev, pr, budget); | 556 | cqe = ehea_proc_rwqes(dev, pr, budget); |
557 | cqe_skb = ehea_proc_cqes(pr, 300); | 557 | cqe_skb = ehea_proc_cqes(pr, 300); |
558 | 558 | ||
559 | if (cqe || cqe_skb) | 559 | if (cqe || cqe_skb) |
560 | pr->poll_counter++; | 560 | pr->poll_counter++; |
561 | 561 | ||
562 | return 1; | 562 | return 1; |
563 | } | 563 | } |
564 | 564 | ||
@@ -1011,7 +1011,7 @@ static int ehea_configure_port(struct ehea_port *port) | |||
1011 | else | 1011 | else |
1012 | cb0->default_qpn_arr[i] = | 1012 | cb0->default_qpn_arr[i] = |
1013 | port->port_res[0].qp->init_attr.qp_nr; | 1013 | port->port_res[0].qp->init_attr.qp_nr; |
1014 | 1014 | ||
1015 | if (netif_msg_ifup(port)) | 1015 | if (netif_msg_ifup(port)) |
1016 | ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); | 1016 | ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); |
1017 | 1017 | ||
@@ -1033,52 +1033,35 @@ out: | |||
1033 | return ret; | 1033 | return ret; |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | static int ehea_gen_smrs(struct ehea_port_res *pr) | 1036 | int ehea_gen_smrs(struct ehea_port_res *pr) |
1037 | { | 1037 | { |
1038 | u64 hret; | 1038 | int ret; |
1039 | struct ehea_adapter *adapter = pr->port->adapter; | 1039 | struct ehea_adapter *adapter = pr->port->adapter; |
1040 | 1040 | ||
1041 | hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, | 1041 | ret = ehea_gen_smr(adapter, &adapter->mr, &pr->send_mr); |
1042 | adapter->mr.vaddr, EHEA_MR_ACC_CTRL, | 1042 | if (ret) |
1043 | adapter->pd, &pr->send_mr); | ||
1044 | if (hret != H_SUCCESS) | ||
1045 | goto out; | 1043 | goto out; |
1046 | 1044 | ||
1047 | hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, | 1045 | ret = ehea_gen_smr(adapter, &adapter->mr, &pr->recv_mr); |
1048 | adapter->mr.vaddr, EHEA_MR_ACC_CTRL, | 1046 | if (ret) |
1049 | adapter->pd, &pr->recv_mr); | 1047 | goto out_free; |
1050 | if (hret != H_SUCCESS) | ||
1051 | goto out_freeres; | ||
1052 | 1048 | ||
1053 | return 0; | 1049 | return 0; |
1054 | 1050 | ||
1055 | out_freeres: | 1051 | out_free: |
1056 | hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); | 1052 | ehea_rem_mr(&pr->send_mr); |
1057 | if (hret != H_SUCCESS) | ||
1058 | ehea_error("failed freeing SMR"); | ||
1059 | out: | 1053 | out: |
1054 | ehea_error("Generating SMRS failed\n"); | ||
1060 | return -EIO; | 1055 | return -EIO; |
1061 | } | 1056 | } |
1062 | 1057 | ||
1063 | static int ehea_rem_smrs(struct ehea_port_res *pr) | 1058 | int ehea_rem_smrs(struct ehea_port_res *pr) |
1064 | { | 1059 | { |
1065 | struct ehea_adapter *adapter = pr->port->adapter; | 1060 | if ((ehea_rem_mr(&pr->send_mr)) |
1066 | int ret = 0; | 1061 | || (ehea_rem_mr(&pr->recv_mr))) |
1067 | u64 hret; | 1062 | return -EIO; |
1068 | 1063 | else | |
1069 | hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); | 1064 | return 0; |
1070 | if (hret != H_SUCCESS) { | ||
1071 | ret = -EIO; | ||
1072 | ehea_error("failed freeing send SMR for pr=%p", pr); | ||
1073 | } | ||
1074 | |||
1075 | hret = ehea_h_free_resource(adapter->handle, pr->recv_mr.handle); | ||
1076 | if (hret != H_SUCCESS) { | ||
1077 | ret = -EIO; | ||
1078 | ehea_error("failed freeing recv SMR for pr=%p", pr); | ||
1079 | } | ||
1080 | |||
1081 | return ret; | ||
1082 | } | 1065 | } |
1083 | 1066 | ||
1084 | static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) | 1067 | static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) |
@@ -2243,7 +2226,7 @@ static int ehea_down(struct net_device *dev) | |||
2243 | ehea_free_interrupts(dev); | 2226 | ehea_free_interrupts(dev); |
2244 | 2227 | ||
2245 | for (i = 0; i < port->num_def_qps; i++) | 2228 | for (i = 0; i < port->num_def_qps; i++) |
2246 | while (test_bit(__LINK_STATE_RX_SCHED, | 2229 | while (test_bit(__LINK_STATE_RX_SCHED, |
2247 | &port->port_res[i].d_netdev->state)) | 2230 | &port->port_res[i].d_netdev->state)) |
2248 | msleep(1); | 2231 | msleep(1); |
2249 | 2232 | ||
@@ -2418,7 +2401,7 @@ static struct device *ehea_register_port(struct ehea_port *port, | |||
2418 | ehea_error("failed to register attributes, ret=%d", ret); | 2401 | ehea_error("failed to register attributes, ret=%d", ret); |
2419 | goto out_unreg_of_dev; | 2402 | goto out_unreg_of_dev; |
2420 | } | 2403 | } |
2421 | 2404 | ||
2422 | return &port->ofdev.dev; | 2405 | return &port->ofdev.dev; |
2423 | 2406 | ||
2424 | out_unreg_of_dev: | 2407 | out_unreg_of_dev: |
@@ -2517,7 +2500,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
2517 | } | 2500 | } |
2518 | 2501 | ||
2519 | ret = ehea_get_jumboframe_status(port, &jumbo); | 2502 | ret = ehea_get_jumboframe_status(port, &jumbo); |
2520 | if (ret) | 2503 | if (ret) |
2521 | ehea_error("failed determining jumbo frame status for %s", | 2504 | ehea_error("failed determining jumbo frame status for %s", |
2522 | port->netdev->name); | 2505 | port->netdev->name); |
2523 | 2506 | ||
@@ -2560,7 +2543,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) | |||
2560 | 2543 | ||
2561 | lhea_dn = adapter->ebus_dev->ofdev.node; | 2544 | lhea_dn = adapter->ebus_dev->ofdev.node; |
2562 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { | 2545 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { |
2563 | 2546 | ||
2564 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", | 2547 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", |
2565 | NULL); | 2548 | NULL); |
2566 | if (!dn_log_port_id) { | 2549 | if (!dn_log_port_id) { |
@@ -2574,7 +2557,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) | |||
2574 | eth_dn); | 2557 | eth_dn); |
2575 | if (adapter->port[i]) | 2558 | if (adapter->port[i]) |
2576 | ehea_info("%s -> logical port id #%d", | 2559 | ehea_info("%s -> logical port id #%d", |
2577 | adapter->port[i]->netdev->name, | 2560 | adapter->port[i]->netdev->name, |
2578 | *dn_log_port_id); | 2561 | *dn_log_port_id); |
2579 | i++; | 2562 | i++; |
2580 | }; | 2563 | }; |
@@ -2590,8 +2573,8 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) | |||
2590 | return -EINVAL; | 2573 | return -EINVAL; |
2591 | } | 2574 | } |
2592 | 2575 | ||
2593 | static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, | 2576 | static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, |
2594 | u32 logical_port_id) | 2577 | u32 logical_port_id) |
2595 | { | 2578 | { |
2596 | struct device_node *lhea_dn; | 2579 | struct device_node *lhea_dn; |
2597 | struct device_node *eth_dn = NULL; | 2580 | struct device_node *eth_dn = NULL; |
@@ -2599,7 +2582,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, | |||
2599 | 2582 | ||
2600 | lhea_dn = adapter->ebus_dev->ofdev.node; | 2583 | lhea_dn = adapter->ebus_dev->ofdev.node; |
2601 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { | 2584 | while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { |
2602 | 2585 | ||
2603 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", | 2586 | dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", |
2604 | NULL); | 2587 | NULL); |
2605 | if (dn_log_port_id) | 2588 | if (dn_log_port_id) |
@@ -2631,14 +2614,14 @@ static ssize_t ehea_probe_port(struct device *dev, | |||
2631 | port->netdev->name); | 2614 | port->netdev->name); |
2632 | return -EINVAL; | 2615 | return -EINVAL; |
2633 | } | 2616 | } |
2634 | 2617 | ||
2635 | eth_dn = ehea_get_eth_dn(adapter, logical_port_id); | 2618 | eth_dn = ehea_get_eth_dn(adapter, logical_port_id); |
2636 | 2619 | ||
2637 | if (!eth_dn) { | 2620 | if (!eth_dn) { |
2638 | ehea_info("no logical port with id %d found", logical_port_id); | 2621 | ehea_info("no logical port with id %d found", logical_port_id); |
2639 | return -EINVAL; | 2622 | return -EINVAL; |
2640 | } | 2623 | } |
2641 | 2624 | ||
2642 | port = ehea_setup_single_port(adapter, logical_port_id, eth_dn); | 2625 | port = ehea_setup_single_port(adapter, logical_port_id, eth_dn); |
2643 | 2626 | ||
2644 | of_node_put(eth_dn); | 2627 | of_node_put(eth_dn); |
@@ -2652,8 +2635,8 @@ static ssize_t ehea_probe_port(struct device *dev, | |||
2652 | 2635 | ||
2653 | ehea_info("added %s (logical port id=%d)", port->netdev->name, | 2636 | ehea_info("added %s (logical port id=%d)", port->netdev->name, |
2654 | logical_port_id); | 2637 | logical_port_id); |
2655 | } else | 2638 | } else |
2656 | return -EIO; | 2639 | return -EIO; |
2657 | 2640 | ||
2658 | return (ssize_t) count; | 2641 | return (ssize_t) count; |
2659 | } | 2642 | } |
@@ -2748,7 +2731,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, | |||
2748 | 2731 | ||
2749 | dev->ofdev.dev.driver_data = adapter; | 2732 | dev->ofdev.dev.driver_data = adapter; |
2750 | 2733 | ||
2751 | ret = ehea_reg_mr_adapter(adapter); | 2734 | ret = ehea_reg_kernel_mr(adapter, &adapter->mr); |
2752 | if (ret) { | 2735 | if (ret) { |
2753 | dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n"); | 2736 | dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n"); |
2754 | goto out_free_ad; | 2737 | goto out_free_ad; |
@@ -2813,7 +2796,7 @@ out_kill_eq: | |||
2813 | ehea_destroy_eq(adapter->neq); | 2796 | ehea_destroy_eq(adapter->neq); |
2814 | 2797 | ||
2815 | out_free_res: | 2798 | out_free_res: |
2816 | ehea_h_free_resource(adapter->handle, adapter->mr.handle); | 2799 | ehea_rem_mr(&adapter->mr); |
2817 | 2800 | ||
2818 | out_free_ad: | 2801 | out_free_ad: |
2819 | kfree(adapter); | 2802 | kfree(adapter); |
@@ -2824,7 +2807,6 @@ out: | |||
2824 | static int __devexit ehea_remove(struct ibmebus_dev *dev) | 2807 | static int __devexit ehea_remove(struct ibmebus_dev *dev) |
2825 | { | 2808 | { |
2826 | struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; | 2809 | struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; |
2827 | u64 hret; | ||
2828 | int i; | 2810 | int i; |
2829 | 2811 | ||
2830 | for (i = 0; i < EHEA_MAX_PORTS; i++) | 2812 | for (i = 0; i < EHEA_MAX_PORTS; i++) |
@@ -2841,12 +2823,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) | |||
2841 | tasklet_kill(&adapter->neq_tasklet); | 2823 | tasklet_kill(&adapter->neq_tasklet); |
2842 | 2824 | ||
2843 | ehea_destroy_eq(adapter->neq); | 2825 | ehea_destroy_eq(adapter->neq); |
2844 | 2826 | ehea_rem_mr(&adapter->mr); | |
2845 | hret = ehea_h_free_resource(adapter->handle, adapter->mr.handle); | ||
2846 | if (hret) { | ||
2847 | dev_err(&dev->ofdev.dev, "free_resource_mr failed"); | ||
2848 | return -EIO; | ||
2849 | } | ||
2850 | kfree(adapter); | 2827 | kfree(adapter); |
2851 | return 0; | 2828 | return 0; |
2852 | } | 2829 | } |
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index bc3c00547264..95c4a7f9cc88 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c | |||
@@ -478,12 +478,14 @@ u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) | |||
478 | 0, 0, 0, 0, 0, 0); /* R7-R12 */ | 478 | 0, 0, 0, 0, 0, 0); /* R7-R12 */ |
479 | } | 479 | } |
480 | 480 | ||
481 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) | 481 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle, |
482 | u64 force_bit) | ||
482 | { | 483 | { |
483 | return ehea_plpar_hcall_norets(H_FREE_RESOURCE, | 484 | return ehea_plpar_hcall_norets(H_FREE_RESOURCE, |
484 | adapter_handle, /* R4 */ | 485 | adapter_handle, /* R4 */ |
485 | res_handle, /* R5 */ | 486 | res_handle, /* R5 */ |
486 | 0, 0, 0, 0, 0); /* R6-R10 */ | 487 | force_bit, |
488 | 0, 0, 0, 0); /* R7-R10 */ | ||
487 | } | 489 | } |
488 | 490 | ||
489 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, | 491 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, |
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h index 90acddb068a1..d17a45a7e717 100644 --- a/drivers/net/ehea/ehea_phyp.h +++ b/drivers/net/ehea/ehea_phyp.h | |||
@@ -414,7 +414,11 @@ u64 ehea_h_register_rpage(const u64 adapter_handle, | |||
414 | 414 | ||
415 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle); | 415 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle); |
416 | 416 | ||
417 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle); | 417 | #define FORCE_FREE 1 |
418 | #define NORMAL_FREE 0 | ||
419 | |||
420 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle, | ||
421 | u64 force_bit); | ||
418 | 422 | ||
419 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, | 423 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, |
420 | const u64 length, const u32 access_ctrl, | 424 | const u64 length, const u32 access_ctrl, |
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 96ff3b679996..f24a8862977d 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -197,7 +197,7 @@ out_kill_hwq: | |||
197 | hw_queue_dtor(&cq->hw_queue); | 197 | hw_queue_dtor(&cq->hw_queue); |
198 | 198 | ||
199 | out_freeres: | 199 | out_freeres: |
200 | ehea_h_free_resource(adapter->handle, cq->fw_handle); | 200 | ehea_h_free_resource(adapter->handle, cq->fw_handle, FORCE_FREE); |
201 | 201 | ||
202 | out_freemem: | 202 | out_freemem: |
203 | kfree(cq); | 203 | kfree(cq); |
@@ -206,25 +206,38 @@ out_nomem: | |||
206 | return NULL; | 206 | return NULL; |
207 | } | 207 | } |
208 | 208 | ||
209 | int ehea_destroy_cq(struct ehea_cq *cq) | 209 | u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force) |
210 | { | 210 | { |
211 | u64 adapter_handle, hret; | 211 | u64 hret; |
212 | u64 adapter_handle = cq->adapter->handle; | ||
213 | |||
214 | /* deregister all previous registered pages */ | ||
215 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force); | ||
216 | if (hret != H_SUCCESS) | ||
217 | return hret; | ||
218 | |||
219 | hw_queue_dtor(&cq->hw_queue); | ||
220 | kfree(cq); | ||
221 | |||
222 | return hret; | ||
223 | } | ||
212 | 224 | ||
225 | int ehea_destroy_cq(struct ehea_cq *cq) | ||
226 | { | ||
227 | u64 hret; | ||
213 | if (!cq) | 228 | if (!cq) |
214 | return 0; | 229 | return 0; |
215 | 230 | ||
216 | adapter_handle = cq->adapter->handle; | 231 | if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) { |
232 | ehea_error_data(cq->adapter, cq->fw_handle); | ||
233 | hret = ehea_destroy_cq_res(cq, FORCE_FREE); | ||
234 | } | ||
217 | 235 | ||
218 | /* deregister all previous registered pages */ | ||
219 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); | ||
220 | if (hret != H_SUCCESS) { | 236 | if (hret != H_SUCCESS) { |
221 | ehea_error("destroy CQ failed"); | 237 | ehea_error("destroy CQ failed"); |
222 | return -EIO; | 238 | return -EIO; |
223 | } | 239 | } |
224 | 240 | ||
225 | hw_queue_dtor(&cq->hw_queue); | ||
226 | kfree(cq); | ||
227 | |||
228 | return 0; | 241 | return 0; |
229 | } | 242 | } |
230 | 243 | ||
@@ -297,7 +310,7 @@ out_kill_hwq: | |||
297 | hw_queue_dtor(&eq->hw_queue); | 310 | hw_queue_dtor(&eq->hw_queue); |
298 | 311 | ||
299 | out_freeres: | 312 | out_freeres: |
300 | ehea_h_free_resource(adapter->handle, eq->fw_handle); | 313 | ehea_h_free_resource(adapter->handle, eq->fw_handle, FORCE_FREE); |
301 | 314 | ||
302 | out_freemem: | 315 | out_freemem: |
303 | kfree(eq); | 316 | kfree(eq); |
@@ -316,27 +329,41 @@ struct ehea_eqe *ehea_poll_eq(struct ehea_eq *eq) | |||
316 | return eqe; | 329 | return eqe; |
317 | } | 330 | } |
318 | 331 | ||
319 | int ehea_destroy_eq(struct ehea_eq *eq) | 332 | u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force) |
320 | { | 333 | { |
321 | u64 hret; | 334 | u64 hret; |
322 | unsigned long flags; | 335 | unsigned long flags; |
323 | 336 | ||
324 | if (!eq) | ||
325 | return 0; | ||
326 | |||
327 | spin_lock_irqsave(&eq->spinlock, flags); | 337 | spin_lock_irqsave(&eq->spinlock, flags); |
328 | 338 | ||
329 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle); | 339 | hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle, force); |
330 | spin_unlock_irqrestore(&eq->spinlock, flags); | 340 | spin_unlock_irqrestore(&eq->spinlock, flags); |
331 | 341 | ||
332 | if (hret != H_SUCCESS) { | 342 | if (hret != H_SUCCESS) |
333 | ehea_error("destroy_eq failed"); | 343 | return hret; |
334 | return -EIO; | ||
335 | } | ||
336 | 344 | ||
337 | hw_queue_dtor(&eq->hw_queue); | 345 | hw_queue_dtor(&eq->hw_queue); |
338 | kfree(eq); | 346 | kfree(eq); |
339 | 347 | ||
348 | return hret; | ||
349 | } | ||
350 | |||
351 | int ehea_destroy_eq(struct ehea_eq *eq) | ||
352 | { | ||
353 | u64 hret; | ||
354 | if (!eq) | ||
355 | return 0; | ||
356 | |||
357 | if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) { | ||
358 | ehea_error_data(eq->adapter, eq->fw_handle); | ||
359 | hret = ehea_destroy_eq_res(eq, FORCE_FREE); | ||
360 | } | ||
361 | |||
362 | if (hret != H_SUCCESS) { | ||
363 | ehea_error("destroy EQ failed"); | ||
364 | return -EIO; | ||
365 | } | ||
366 | |||
340 | return 0; | 367 | return 0; |
341 | } | 368 | } |
342 | 369 | ||
@@ -471,41 +498,56 @@ out_kill_hwsq: | |||
471 | 498 | ||
472 | out_freeres: | 499 | out_freeres: |
473 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); | 500 | ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); |
474 | ehea_h_free_resource(adapter->handle, qp->fw_handle); | 501 | ehea_h_free_resource(adapter->handle, qp->fw_handle, FORCE_FREE); |
475 | 502 | ||
476 | out_freemem: | 503 | out_freemem: |
477 | kfree(qp); | 504 | kfree(qp); |
478 | return NULL; | 505 | return NULL; |
479 | } | 506 | } |
480 | 507 | ||
481 | int ehea_destroy_qp(struct ehea_qp *qp) | 508 | u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) |
482 | { | 509 | { |
483 | u64 hret; | 510 | u64 hret; |
484 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; | 511 | struct ehea_qp_init_attr *qp_attr = &qp->init_attr; |
485 | 512 | ||
486 | if (!qp) | ||
487 | return 0; | ||
488 | 513 | ||
489 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); | 514 | ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); |
490 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle); | 515 | hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); |
491 | if (hret != H_SUCCESS) { | 516 | if (hret != H_SUCCESS) |
492 | ehea_error("destroy_qp failed"); | 517 | return hret; |
493 | return -EIO; | ||
494 | } | ||
495 | 518 | ||
496 | hw_queue_dtor(&qp->hw_squeue); | 519 | hw_queue_dtor(&qp->hw_squeue); |
497 | hw_queue_dtor(&qp->hw_rqueue1); | 520 | hw_queue_dtor(&qp->hw_rqueue1); |
498 | 521 | ||
499 | if (qp_attr->rq_count > 1) | 522 | if (qp_attr->rq_count > 1) |
500 | hw_queue_dtor(&qp->hw_rqueue2); | 523 | hw_queue_dtor(&qp->hw_rqueue2); |
501 | if (qp_attr->rq_count > 2) | 524 | if (qp_attr->rq_count > 2) |
502 | hw_queue_dtor(&qp->hw_rqueue3); | 525 | hw_queue_dtor(&qp->hw_rqueue3); |
503 | kfree(qp); | 526 | kfree(qp); |
504 | 527 | ||
505 | return 0; | 528 | return hret; |
506 | } | 529 | } |
507 | 530 | ||
508 | int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | 531 | int ehea_destroy_qp(struct ehea_qp *qp) |
532 | { | ||
533 | u64 hret; | ||
534 | if (!qp) | ||
535 | return 0; | ||
536 | |||
537 | if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { | ||
538 | ehea_error_data(qp->adapter, qp->fw_handle); | ||
539 | hret = ehea_destroy_qp_res(qp, FORCE_FREE); | ||
540 | } | ||
541 | |||
542 | if (hret != H_SUCCESS) { | ||
543 | ehea_error("destroy QP failed"); | ||
544 | return -EIO; | ||
545 | } | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) | ||
509 | { | 551 | { |
510 | int i, k, ret; | 552 | int i, k, ret; |
511 | u64 hret, pt_abs, start, end, nr_pages; | 553 | u64 hret, pt_abs, start, end, nr_pages; |
@@ -526,14 +568,14 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
526 | 568 | ||
527 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, | 569 | hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, |
528 | acc_ctrl, adapter->pd, | 570 | acc_ctrl, adapter->pd, |
529 | &adapter->mr.handle, &adapter->mr.lkey); | 571 | &mr->handle, &mr->lkey); |
530 | if (hret != H_SUCCESS) { | 572 | if (hret != H_SUCCESS) { |
531 | ehea_error("alloc_resource_mr failed"); | 573 | ehea_error("alloc_resource_mr failed"); |
532 | ret = -EIO; | 574 | ret = -EIO; |
533 | goto out; | 575 | goto out; |
534 | } | 576 | } |
535 | 577 | ||
536 | adapter->mr.vaddr = KERNELBASE; | 578 | mr->vaddr = KERNELBASE; |
537 | k = 0; | 579 | k = 0; |
538 | 580 | ||
539 | while (nr_pages > 0) { | 581 | while (nr_pages > 0) { |
@@ -545,7 +587,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
545 | EHEA_PAGESIZE))); | 587 | EHEA_PAGESIZE))); |
546 | 588 | ||
547 | hret = ehea_h_register_rpage_mr(adapter->handle, | 589 | hret = ehea_h_register_rpage_mr(adapter->handle, |
548 | adapter->mr.handle, 0, | 590 | mr->handle, 0, |
549 | 0, (u64)pt_abs, | 591 | 0, (u64)pt_abs, |
550 | num_pages); | 592 | num_pages); |
551 | nr_pages -= num_pages; | 593 | nr_pages -= num_pages; |
@@ -554,34 +596,68 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
554 | (k * EHEA_PAGESIZE))); | 596 | (k * EHEA_PAGESIZE))); |
555 | 597 | ||
556 | hret = ehea_h_register_rpage_mr(adapter->handle, | 598 | hret = ehea_h_register_rpage_mr(adapter->handle, |
557 | adapter->mr.handle, 0, | 599 | mr->handle, 0, |
558 | 0, abs_adr,1); | 600 | 0, abs_adr,1); |
559 | nr_pages--; | 601 | nr_pages--; |
560 | } | 602 | } |
561 | 603 | ||
562 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { | 604 | if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { |
563 | ehea_h_free_resource(adapter->handle, | 605 | ehea_h_free_resource(adapter->handle, |
564 | adapter->mr.handle); | 606 | mr->handle, FORCE_FREE); |
565 | ehea_error("register_rpage_mr failed: hret = %lX", | 607 | ehea_error("register_rpage_mr failed"); |
566 | hret); | ||
567 | ret = -EIO; | 608 | ret = -EIO; |
568 | goto out; | 609 | goto out; |
569 | } | 610 | } |
570 | } | 611 | } |
571 | 612 | ||
572 | if (hret != H_SUCCESS) { | 613 | if (hret != H_SUCCESS) { |
573 | ehea_h_free_resource(adapter->handle, adapter->mr.handle); | 614 | ehea_h_free_resource(adapter->handle, mr->handle, |
574 | ehea_error("register_rpage failed for last page: hret = %lX", | 615 | FORCE_FREE); |
575 | hret); | 616 | ehea_error("register_rpage failed for last page"); |
576 | ret = -EIO; | 617 | ret = -EIO; |
577 | goto out; | 618 | goto out; |
578 | } | 619 | } |
620 | |||
621 | mr->adapter = adapter; | ||
579 | ret = 0; | 622 | ret = 0; |
580 | out: | 623 | out: |
581 | kfree(pt); | 624 | kfree(pt); |
582 | return ret; | 625 | return ret; |
583 | } | 626 | } |
584 | 627 | ||
628 | int ehea_rem_mr(struct ehea_mr *mr) | ||
629 | { | ||
630 | u64 hret; | ||
631 | |||
632 | if (!mr || !mr->adapter) | ||
633 | return -EINVAL; | ||
634 | |||
635 | hret = ehea_h_free_resource(mr->adapter->handle, mr->handle, | ||
636 | FORCE_FREE); | ||
637 | if (hret != H_SUCCESS) { | ||
638 | ehea_error("destroy MR failed"); | ||
639 | return -EIO; | ||
640 | } | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr, | ||
646 | struct ehea_mr *shared_mr) | ||
647 | { | ||
648 | u64 hret; | ||
649 | |||
650 | hret = ehea_h_register_smr(adapter->handle, old_mr->handle, | ||
651 | old_mr->vaddr, EHEA_MR_ACC_CTRL, | ||
652 | adapter->pd, shared_mr); | ||
653 | if (hret != H_SUCCESS) | ||
654 | return -EIO; | ||
655 | |||
656 | shared_mr->adapter = adapter; | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
585 | void print_error_data(u64 *data) | 661 | void print_error_data(u64 *data) |
586 | { | 662 | { |
587 | int length; | 663 | int length; |
@@ -597,6 +673,14 @@ void print_error_data(u64 *data) | |||
597 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " | 673 | ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " |
598 | "port=%lX", resource, data[6], data[12], data[22]); | 674 | "port=%lX", resource, data[6], data[12], data[22]); |
599 | 675 | ||
676 | if (type == 0x4) /* Completion Queue */ | ||
677 | ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, | ||
678 | data[6]); | ||
679 | |||
680 | if (type == 0x3) /* Event Queue */ | ||
681 | ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, | ||
682 | data[6]); | ||
683 | |||
600 | ehea_dump(data, length, "error data"); | 684 | ehea_dump(data, length, "error data"); |
601 | } | 685 | } |
602 | 686 | ||
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index 99d6b70a087f..24603312eb84 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h | |||
@@ -361,7 +361,12 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter * adapter, u32 pd, | |||
361 | 361 | ||
362 | int ehea_destroy_qp(struct ehea_qp *qp); | 362 | int ehea_destroy_qp(struct ehea_qp *qp); |
363 | 363 | ||
364 | int ehea_reg_mr_adapter(struct ehea_adapter *adapter); | 364 | int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr); |
365 | |||
366 | int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr, | ||
367 | struct ehea_mr *shared_mr); | ||
368 | |||
369 | int ehea_rem_mr(struct ehea_mr *mr); | ||
365 | 370 | ||
366 | void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); | 371 | void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); |
367 | 372 | ||