diff options
Diffstat (limited to 'drivers/infiniband/core/mad_rmpp.c')
-rw-r--r-- | drivers/infiniband/core/mad_rmpp.c | 148 |
1 files changed, 48 insertions, 100 deletions
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 3249e1d8c07b..bacfdd5bddad 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
@@ -111,14 +111,14 @@ static int data_offset(u8 mgmt_class) | |||
111 | return IB_MGMT_RMPP_HDR; | 111 | return IB_MGMT_RMPP_HDR; |
112 | } | 112 | } |
113 | 113 | ||
114 | static void format_ack(struct ib_rmpp_mad *ack, | 114 | static void format_ack(struct ib_mad_send_buf *msg, |
115 | struct ib_rmpp_mad *data, | 115 | struct ib_rmpp_mad *data, |
116 | struct mad_rmpp_recv *rmpp_recv) | 116 | struct mad_rmpp_recv *rmpp_recv) |
117 | { | 117 | { |
118 | struct ib_rmpp_mad *ack = msg->mad; | ||
118 | unsigned long flags; | 119 | unsigned long flags; |
119 | 120 | ||
120 | memcpy(&ack->mad_hdr, &data->mad_hdr, | 121 | memcpy(ack, &data->mad_hdr, msg->hdr_len); |
121 | data_offset(data->mad_hdr.mgmt_class)); | ||
122 | 122 | ||
123 | ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP; | 123 | ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP; |
124 | ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK; | 124 | ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK; |
@@ -135,16 +135,16 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, | |||
135 | struct ib_mad_recv_wc *recv_wc) | 135 | struct ib_mad_recv_wc *recv_wc) |
136 | { | 136 | { |
137 | struct ib_mad_send_buf *msg; | 137 | struct ib_mad_send_buf *msg; |
138 | int ret; | 138 | int ret, hdr_len; |
139 | 139 | ||
140 | hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); | ||
140 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, | 141 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, |
141 | recv_wc->wc->pkey_index, 1, IB_MGMT_RMPP_HDR, | 142 | recv_wc->wc->pkey_index, 1, hdr_len, |
142 | IB_MGMT_RMPP_DATA, GFP_KERNEL); | 143 | 0, GFP_KERNEL); |
143 | if (!msg) | 144 | if (!msg) |
144 | return; | 145 | return; |
145 | 146 | ||
146 | format_ack(msg->mad, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, | 147 | format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); |
147 | rmpp_recv); | ||
148 | msg->ah = rmpp_recv->ah; | 148 | msg->ah = rmpp_recv->ah; |
149 | ret = ib_post_send_mad(msg, NULL); | 149 | ret = ib_post_send_mad(msg, NULL); |
150 | if (ret) | 150 | if (ret) |
@@ -156,16 +156,17 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, | |||
156 | { | 156 | { |
157 | struct ib_mad_send_buf *msg; | 157 | struct ib_mad_send_buf *msg; |
158 | struct ib_ah *ah; | 158 | struct ib_ah *ah; |
159 | int hdr_len; | ||
159 | 160 | ||
160 | ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, | 161 | ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc, |
161 | recv_wc->recv_buf.grh, agent->port_num); | 162 | recv_wc->recv_buf.grh, agent->port_num); |
162 | if (IS_ERR(ah)) | 163 | if (IS_ERR(ah)) |
163 | return (void *) ah; | 164 | return (void *) ah; |
164 | 165 | ||
166 | hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); | ||
165 | msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, | 167 | msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, |
166 | recv_wc->wc->pkey_index, 1, | 168 | recv_wc->wc->pkey_index, 1, |
167 | IB_MGMT_RMPP_HDR, IB_MGMT_RMPP_DATA, | 169 | hdr_len, 0, GFP_KERNEL); |
168 | GFP_KERNEL); | ||
169 | if (IS_ERR(msg)) | 170 | if (IS_ERR(msg)) |
170 | ib_destroy_ah(ah); | 171 | ib_destroy_ah(ah); |
171 | else | 172 | else |
@@ -195,8 +196,7 @@ static void nack_recv(struct ib_mad_agent_private *agent, | |||
195 | return; | 196 | return; |
196 | 197 | ||
197 | rmpp_mad = msg->mad; | 198 | rmpp_mad = msg->mad; |
198 | memcpy(rmpp_mad, recv_wc->recv_buf.mad, | 199 | memcpy(rmpp_mad, recv_wc->recv_buf.mad, msg->hdr_len); |
199 | data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class)); | ||
200 | 200 | ||
201 | rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP; | 201 | rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP; |
202 | rmpp_mad->rmpp_hdr.rmpp_version = IB_MGMT_RMPP_VERSION; | 202 | rmpp_mad->rmpp_hdr.rmpp_version = IB_MGMT_RMPP_VERSION; |
@@ -433,44 +433,6 @@ static struct ib_mad_recv_wc * complete_rmpp(struct mad_rmpp_recv *rmpp_recv) | |||
433 | return rmpp_wc; | 433 | return rmpp_wc; |
434 | } | 434 | } |
435 | 435 | ||
436 | void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf) | ||
437 | { | ||
438 | struct ib_mad_recv_buf *seg_buf; | ||
439 | struct ib_rmpp_mad *rmpp_mad; | ||
440 | void *data; | ||
441 | int size, len, offset; | ||
442 | u8 flags; | ||
443 | |||
444 | len = mad_recv_wc->mad_len; | ||
445 | if (len <= sizeof(struct ib_mad)) { | ||
446 | memcpy(buf, mad_recv_wc->recv_buf.mad, len); | ||
447 | return; | ||
448 | } | ||
449 | |||
450 | offset = data_offset(mad_recv_wc->recv_buf.mad->mad_hdr.mgmt_class); | ||
451 | |||
452 | list_for_each_entry(seg_buf, &mad_recv_wc->rmpp_list, list) { | ||
453 | rmpp_mad = (struct ib_rmpp_mad *)seg_buf->mad; | ||
454 | flags = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr); | ||
455 | |||
456 | if (flags & IB_MGMT_RMPP_FLAG_FIRST) { | ||
457 | data = rmpp_mad; | ||
458 | size = sizeof(*rmpp_mad); | ||
459 | } else { | ||
460 | data = (void *) rmpp_mad + offset; | ||
461 | if (flags & IB_MGMT_RMPP_FLAG_LAST) | ||
462 | size = len; | ||
463 | else | ||
464 | size = sizeof(*rmpp_mad) - offset; | ||
465 | } | ||
466 | |||
467 | memcpy(buf, data, size); | ||
468 | len -= size; | ||
469 | buf += size; | ||
470 | } | ||
471 | } | ||
472 | EXPORT_SYMBOL(ib_coalesce_recv_mad); | ||
473 | |||
474 | static struct ib_mad_recv_wc * | 436 | static struct ib_mad_recv_wc * |
475 | continue_rmpp(struct ib_mad_agent_private *agent, | 437 | continue_rmpp(struct ib_mad_agent_private *agent, |
476 | struct ib_mad_recv_wc *mad_recv_wc) | 438 | struct ib_mad_recv_wc *mad_recv_wc) |
@@ -570,50 +532,33 @@ start_rmpp(struct ib_mad_agent_private *agent, | |||
570 | return mad_recv_wc; | 532 | return mad_recv_wc; |
571 | } | 533 | } |
572 | 534 | ||
573 | static inline u64 get_seg_addr(struct ib_mad_send_wr_private *mad_send_wr) | ||
574 | { | ||
575 | return mad_send_wr->sg_list[0].addr + mad_send_wr->data_offset + | ||
576 | (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset) * | ||
577 | (mad_send_wr->seg_num - 1); | ||
578 | } | ||
579 | |||
580 | static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) | 535 | static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) |
581 | { | 536 | { |
582 | struct ib_rmpp_mad *rmpp_mad; | 537 | struct ib_rmpp_mad *rmpp_mad; |
583 | int timeout; | 538 | int timeout; |
584 | u32 paylen; | 539 | u32 paylen = 0; |
585 | 540 | ||
586 | rmpp_mad = mad_send_wr->send_buf.mad; | 541 | rmpp_mad = mad_send_wr->send_buf.mad; |
587 | ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); | 542 | ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE); |
588 | rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num); | 543 | rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(++mad_send_wr->seg_num); |
589 | 544 | ||
590 | if (mad_send_wr->seg_num == 1) { | 545 | if (mad_send_wr->seg_num == 1) { |
591 | rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST; | 546 | rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST; |
592 | paylen = mad_send_wr->total_seg * IB_MGMT_RMPP_DATA - | 547 | paylen = mad_send_wr->send_buf.seg_count * IB_MGMT_RMPP_DATA - |
593 | mad_send_wr->pad; | 548 | mad_send_wr->pad; |
594 | rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen); | ||
595 | mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad); | ||
596 | } else { | ||
597 | mad_send_wr->send_wr.num_sge = 2; | ||
598 | mad_send_wr->sg_list[0].length = mad_send_wr->data_offset; | ||
599 | mad_send_wr->sg_list[1].addr = get_seg_addr(mad_send_wr); | ||
600 | mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) - | ||
601 | mad_send_wr->data_offset; | ||
602 | mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey; | ||
603 | rmpp_mad->rmpp_hdr.paylen_newwin = 0; | ||
604 | } | 549 | } |
605 | 550 | ||
606 | if (mad_send_wr->seg_num == mad_send_wr->total_seg) { | 551 | if (mad_send_wr->seg_num == mad_send_wr->send_buf.seg_count) { |
607 | rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST; | 552 | rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST; |
608 | paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad; | 553 | paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad; |
609 | rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen); | ||
610 | } | 554 | } |
555 | rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen); | ||
611 | 556 | ||
612 | /* 2 seconds for an ACK until we can find the packet lifetime */ | 557 | /* 2 seconds for an ACK until we can find the packet lifetime */ |
613 | timeout = mad_send_wr->send_buf.timeout_ms; | 558 | timeout = mad_send_wr->send_buf.timeout_ms; |
614 | if (!timeout || timeout > 2000) | 559 | if (!timeout || timeout > 2000) |
615 | mad_send_wr->timeout = msecs_to_jiffies(2000); | 560 | mad_send_wr->timeout = msecs_to_jiffies(2000); |
616 | mad_send_wr->seg_num++; | 561 | |
617 | return ib_send_mad(mad_send_wr); | 562 | return ib_send_mad(mad_send_wr); |
618 | } | 563 | } |
619 | 564 | ||
@@ -629,7 +574,7 @@ static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, | |||
629 | if (!mad_send_wr) | 574 | if (!mad_send_wr) |
630 | goto out; /* Unmatched send */ | 575 | goto out; /* Unmatched send */ |
631 | 576 | ||
632 | if ((mad_send_wr->last_ack == mad_send_wr->total_seg) || | 577 | if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) || |
633 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) | 578 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) |
634 | goto out; /* Send is already done */ | 579 | goto out; /* Send is already done */ |
635 | 580 | ||
@@ -645,6 +590,18 @@ out: | |||
645 | spin_unlock_irqrestore(&agent->lock, flags); | 590 | spin_unlock_irqrestore(&agent->lock, flags); |
646 | } | 591 | } |
647 | 592 | ||
593 | static inline void adjust_last_ack(struct ib_mad_send_wr_private *wr, | ||
594 | int seg_num) | ||
595 | { | ||
596 | struct list_head *list; | ||
597 | |||
598 | wr->last_ack = seg_num; | ||
599 | list = &wr->last_ack_seg->list; | ||
600 | list_for_each_entry(wr->last_ack_seg, list, list) | ||
601 | if (wr->last_ack_seg->num == seg_num) | ||
602 | break; | ||
603 | } | ||
604 | |||
648 | static void process_rmpp_ack(struct ib_mad_agent_private *agent, | 605 | static void process_rmpp_ack(struct ib_mad_agent_private *agent, |
649 | struct ib_mad_recv_wc *mad_recv_wc) | 606 | struct ib_mad_recv_wc *mad_recv_wc) |
650 | { | 607 | { |
@@ -675,11 +632,12 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
675 | if (!mad_send_wr) | 632 | if (!mad_send_wr) |
676 | goto out; /* Unmatched ACK */ | 633 | goto out; /* Unmatched ACK */ |
677 | 634 | ||
678 | if ((mad_send_wr->last_ack == mad_send_wr->total_seg) || | 635 | if ((mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) || |
679 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) | 636 | (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) |
680 | goto out; /* Send is already done */ | 637 | goto out; /* Send is already done */ |
681 | 638 | ||
682 | if (seg_num > mad_send_wr->total_seg || seg_num > mad_send_wr->newwin) { | 639 | if (seg_num > mad_send_wr->send_buf.seg_count || |
640 | seg_num > mad_send_wr->newwin) { | ||
683 | spin_unlock_irqrestore(&agent->lock, flags); | 641 | spin_unlock_irqrestore(&agent->lock, flags); |
684 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 642 | abort_send(agent, rmpp_mad->mad_hdr.tid, |
685 | IB_MGMT_RMPP_STATUS_S2B); | 643 | IB_MGMT_RMPP_STATUS_S2B); |
@@ -691,11 +649,11 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
691 | goto out; /* Old ACK */ | 649 | goto out; /* Old ACK */ |
692 | 650 | ||
693 | if (seg_num > mad_send_wr->last_ack) { | 651 | if (seg_num > mad_send_wr->last_ack) { |
694 | mad_send_wr->last_ack = seg_num; | 652 | adjust_last_ack(mad_send_wr, seg_num); |
695 | mad_send_wr->retries = mad_send_wr->send_buf.retries; | 653 | mad_send_wr->retries = mad_send_wr->send_buf.retries; |
696 | } | 654 | } |
697 | mad_send_wr->newwin = newwin; | 655 | mad_send_wr->newwin = newwin; |
698 | if (mad_send_wr->last_ack == mad_send_wr->total_seg) { | 656 | if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) { |
699 | /* If no response is expected, the ACK completes the send */ | 657 | /* If no response is expected, the ACK completes the send */ |
700 | if (!mad_send_wr->send_buf.timeout_ms) { | 658 | if (!mad_send_wr->send_buf.timeout_ms) { |
701 | struct ib_mad_send_wc wc; | 659 | struct ib_mad_send_wc wc; |
@@ -714,7 +672,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
714 | mad_send_wr->send_buf.timeout_ms); | 672 | mad_send_wr->send_buf.timeout_ms); |
715 | } else if (mad_send_wr->refcount == 1 && | 673 | } else if (mad_send_wr->refcount == 1 && |
716 | mad_send_wr->seg_num < mad_send_wr->newwin && | 674 | mad_send_wr->seg_num < mad_send_wr->newwin && |
717 | mad_send_wr->seg_num <= mad_send_wr->total_seg) { | 675 | mad_send_wr->seg_num < mad_send_wr->send_buf.seg_count) { |
718 | /* Send failure will just result in a timeout/retry */ | 676 | /* Send failure will just result in a timeout/retry */ |
719 | ret = send_next_seg(mad_send_wr); | 677 | ret = send_next_seg(mad_send_wr); |
720 | if (ret) | 678 | if (ret) |
@@ -838,31 +796,19 @@ out: | |||
838 | int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr) | 796 | int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr) |
839 | { | 797 | { |
840 | struct ib_rmpp_mad *rmpp_mad; | 798 | struct ib_rmpp_mad *rmpp_mad; |
841 | int i, total_len, ret; | 799 | int ret; |
842 | 800 | ||
843 | rmpp_mad = mad_send_wr->send_buf.mad; | 801 | rmpp_mad = mad_send_wr->send_buf.mad; |
844 | if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | 802 | if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & |
845 | IB_MGMT_RMPP_FLAG_ACTIVE)) | 803 | IB_MGMT_RMPP_FLAG_ACTIVE)) |
846 | return IB_RMPP_RESULT_UNHANDLED; | 804 | return IB_RMPP_RESULT_UNHANDLED; |
847 | 805 | ||
848 | if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) | 806 | if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { |
807 | mad_send_wr->seg_num = 1; | ||
849 | return IB_RMPP_RESULT_INTERNAL; | 808 | return IB_RMPP_RESULT_INTERNAL; |
809 | } | ||
850 | 810 | ||
851 | if (mad_send_wr->send_wr.num_sge > 1) | ||
852 | return -EINVAL; /* TODO: support num_sge > 1 */ | ||
853 | |||
854 | mad_send_wr->seg_num = 1; | ||
855 | mad_send_wr->newwin = 1; | 811 | mad_send_wr->newwin = 1; |
856 | mad_send_wr->data_offset = data_offset(rmpp_mad->mad_hdr.mgmt_class); | ||
857 | |||
858 | total_len = 0; | ||
859 | for (i = 0; i < mad_send_wr->send_wr.num_sge; i++) | ||
860 | total_len += mad_send_wr->send_wr.sg_list[i].length; | ||
861 | |||
862 | mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) / | ||
863 | (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset); | ||
864 | mad_send_wr->pad = total_len - IB_MGMT_RMPP_HDR - | ||
865 | be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); | ||
866 | 812 | ||
867 | /* We need to wait for the final ACK even if there isn't a response */ | 813 | /* We need to wait for the final ACK even if there isn't a response */ |
868 | mad_send_wr->refcount += (mad_send_wr->timeout == 0); | 814 | mad_send_wr->refcount += (mad_send_wr->timeout == 0); |
@@ -893,14 +839,14 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr, | |||
893 | if (!mad_send_wr->timeout) | 839 | if (!mad_send_wr->timeout) |
894 | return IB_RMPP_RESULT_PROCESSED; /* Response received */ | 840 | return IB_RMPP_RESULT_PROCESSED; /* Response received */ |
895 | 841 | ||
896 | if (mad_send_wr->last_ack == mad_send_wr->total_seg) { | 842 | if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) { |
897 | mad_send_wr->timeout = | 843 | mad_send_wr->timeout = |
898 | msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); | 844 | msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); |
899 | return IB_RMPP_RESULT_PROCESSED; /* Send done */ | 845 | return IB_RMPP_RESULT_PROCESSED; /* Send done */ |
900 | } | 846 | } |
901 | 847 | ||
902 | if (mad_send_wr->seg_num > mad_send_wr->newwin || | 848 | if (mad_send_wr->seg_num == mad_send_wr->newwin || |
903 | mad_send_wr->seg_num > mad_send_wr->total_seg) | 849 | mad_send_wr->seg_num == mad_send_wr->send_buf.seg_count) |
904 | return IB_RMPP_RESULT_PROCESSED; /* Wait for ACK */ | 850 | return IB_RMPP_RESULT_PROCESSED; /* Wait for ACK */ |
905 | 851 | ||
906 | ret = send_next_seg(mad_send_wr); | 852 | ret = send_next_seg(mad_send_wr); |
@@ -921,10 +867,12 @@ int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr) | |||
921 | IB_MGMT_RMPP_FLAG_ACTIVE)) | 867 | IB_MGMT_RMPP_FLAG_ACTIVE)) |
922 | return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ | 868 | return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */ |
923 | 869 | ||
924 | if (mad_send_wr->last_ack == mad_send_wr->total_seg) | 870 | if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) |
925 | return IB_RMPP_RESULT_PROCESSED; | 871 | return IB_RMPP_RESULT_PROCESSED; |
926 | 872 | ||
927 | mad_send_wr->seg_num = mad_send_wr->last_ack + 1; | 873 | mad_send_wr->seg_num = mad_send_wr->last_ack; |
874 | mad_send_wr->cur_seg = mad_send_wr->last_ack_seg; | ||
875 | |||
928 | ret = send_next_seg(mad_send_wr); | 876 | ret = send_next_seg(mad_send_wr); |
929 | if (ret) | 877 | if (ret) |
930 | return IB_RMPP_RESULT_PROCESSED; | 878 | return IB_RMPP_RESULT_PROCESSED; |