34 #include <linux/slab.h>
72 static inline void deref_rmpp_recv(
struct mad_rmpp_recv *rmpp_recv)
78 static void destroy_rmpp_recv(
struct mad_rmpp_recv *rmpp_recv)
80 deref_rmpp_recv(rmpp_recv);
97 spin_unlock_irqrestore(&agent->
lock, flags);
109 destroy_rmpp_recv(rmpp_recv);
130 spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
141 recv_wc->
wc->pkey_index, 1, hdr_len,
147 msg->
ah = rmpp_recv->
ah;
167 recv_wc->
wc->pkey_index, 1,
186 msg = alloc_response_msg(&agent->
agent, recv_wc);
219 msg = alloc_response_msg(&agent->
agent, recv_wc);
230 rmpp_mad->
rmpp_hdr.rmpp_status = rmpp_status;
232 rmpp_mad->
rmpp_hdr.paylen_newwin = 0;
250 spin_unlock_irqrestore(&rmpp_recv->
agent->lock, flags);
255 spin_unlock_irqrestore(&rmpp_recv->
agent->lock, flags);
259 destroy_rmpp_recv(rmpp_recv);
263 static void recv_cleanup_handler(
struct work_struct *work)
271 spin_unlock_irqrestore(&rmpp_recv->
agent->lock, flags);
275 spin_unlock_irqrestore(&rmpp_recv->
agent->lock, flags);
276 destroy_rmpp_recv(rmpp_recv);
293 agent->
agent.port_num);
294 if (IS_ERR(rmpp_recv->
ah))
297 rmpp_recv->
agent = agent;
298 init_completion(&rmpp_recv->
comp);
305 rmpp_recv->
rmpp_wc = mad_recv_wc;
312 mad_hdr = &mad_recv_wc->
recv_buf.mad->mad_hdr;
313 rmpp_recv->
tid = mad_hdr->
tid;
314 rmpp_recv->
src_qp = mad_recv_wc->
wc->src_qp;
315 rmpp_recv->
slid = mad_recv_wc->
wc->slid;
333 if (rmpp_recv->
tid == mad_hdr->
tid &&
334 rmpp_recv->
src_qp == mad_recv_wc->
wc->src_qp &&
335 rmpp_recv->
slid == mad_recv_wc->
wc->slid &&
352 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);
355 spin_unlock_irqrestore(&agent->
lock, flags);
365 cur_rmpp_recv = find_rmpp_recv(agent, rmpp_recv->
rmpp_wc);
369 return cur_rmpp_recv;
391 if (seg->
list.next == rmpp_list)
399 return max(agent->
qp_info->recv_queue.max_active >> 3, 1);
409 cur_seg_num = get_seg_num(seg_buf);
410 if (seg_num > cur_seg_num)
412 if (seg_num == cur_seg_num)
423 while (new_buf && (get_seg_num(new_buf) == rmpp_recv->
seg_num + 1)) {
426 new_buf = get_next_seg(rmpp_list, new_buf);
430 static inline int get_mad_len(
struct mad_rmpp_recv *rmpp_recv)
443 return hdr_size + rmpp_recv->
seg_num * data_size -
pad;
450 ack_recv(rmpp_recv, rmpp_recv->
rmpp_wc);
455 rmpp_wc->
mad_len = get_mad_len(rmpp_recv);
472 rmpp_recv = acquire_rmpp_recv(agent, mad_recv_wc);
476 seg_num = get_seg_num(&mad_recv_wc->
recv_buf);
480 (seg_num > rmpp_recv->
newwin))
483 if ((seg_num <= rmpp_recv->last_ack) ||
485 spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
486 ack_recv(rmpp_recv, mad_recv_wc);
490 prev_buf = find_seg_location(&rmpp_recv->
rmpp_wc->rmpp_list, seg_num);
497 update_seg_num(rmpp_recv, &mad_recv_wc->
recv_buf);
500 spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
501 done_wc = complete_rmpp(rmpp_recv);
504 rmpp_recv->
newwin += window_size(agent);
505 spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
506 ack_recv(rmpp_recv, mad_recv_wc);
510 spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
512 deref_rmpp_recv(rmpp_recv);
515 drop3: spin_unlock_irqrestore(&rmpp_recv->
lock, flags);
516 drop2: deref_rmpp_recv(rmpp_recv);
528 rmpp_recv = create_rmpp_recv(agent, mad_recv_wc);
535 if (insert_rmpp_recv(agent, rmpp_recv)) {
536 spin_unlock_irqrestore(&agent->
lock, flags);
538 destroy_rmpp_recv(rmpp_recv);
539 return continue_rmpp(agent, mad_recv_wc);
543 if (get_last_flag(&mad_recv_wc->
recv_buf)) {
545 spin_unlock_irqrestore(&agent->
lock, flags);
546 complete_rmpp(rmpp_recv);
548 spin_unlock_irqrestore(&agent->
lock, flags);
553 rmpp_recv->
newwin += window_size(agent);
554 ack_recv(rmpp_recv, mad_recv_wc);
557 deref_rmpp_recv(rmpp_recv);
567 rmpp_mad = mad_send_wr->
send_buf.mad;
571 if (mad_send_wr->
seg_num == 1) {
584 timeout = mad_send_wr->
send_buf.timeout_ms;
585 if (!timeout || timeout > 2000)
608 spin_unlock_irqrestore(&agent->
lock, flags);
611 wc.vendor_err = rmpp_status;
616 spin_unlock_irqrestore(&agent->
lock, flags);
627 if (wr->last_ack_seg->num == seg_num)
636 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);
647 int seg_num, newwin,
ret;
658 if (newwin < seg_num) {
668 process_ds_ack(agent, mad_recv_wc, newwin);
674 spin_unlock_irqrestore(&agent->
lock, flags);
675 ack_ds_ack(agent, mad_recv_wc);
683 if (seg_num > mad_send_wr->
send_buf.seg_count ||
684 seg_num > mad_send_wr->
newwin) {
685 spin_unlock_irqrestore(&agent->
lock, flags);
691 if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack)
694 if (seg_num > mad_send_wr->
last_ack) {
695 adjust_last_ack(mad_send_wr, seg_num);
698 mad_send_wr->
newwin = newwin;
701 if (!mad_send_wr->
send_buf.timeout_ms) {
705 spin_unlock_irqrestore(&agent->
lock, flags);
716 spin_unlock_irqrestore(&agent->
lock, flags);
717 ack_ds_ack(agent, mad_recv_wc);
719 }
else if (mad_send_wr->
refcount == 1 &&
723 ret = send_next_seg(mad_send_wr);
732 spin_unlock_irqrestore(&agent->
lock, flags);
754 return start_rmpp(agent, mad_recv_wc);
760 return continue_rmpp(agent, mad_recv_wc);
763 nack_recv(agent, mad_recv_wc, rmpp_status);
779 abort_send(agent, mad_recv_wc, rmpp_mad->
rmpp_hdr.rmpp_status);
794 abort_send(agent, mad_recv_wc, rmpp_mad->
rmpp_hdr.rmpp_status);
813 switch (rmpp_mad->
rmpp_hdr.rmpp_type) {
815 return process_rmpp_data(agent, mad_recv_wc);
817 process_rmpp_ack(agent, mad_recv_wc);
820 process_rmpp_stop(agent, mad_recv_wc);
823 process_rmpp_abort(agent, mad_recv_wc);
849 if (rmpp_recv->
tid != mad_hdr->
tid ||
858 if (rmpp_recv->
slid == ah_attr.dlid) {
859 newwin = rmpp_recv->
repwin;
863 spin_unlock_irqrestore(&agent->
lock, flags);
873 rmpp_mad = mad_send_wr->
send_buf.mad;
874 if (!(ib_get_rmpp_flags(&rmpp_mad->
rmpp_hdr) &
883 mad_send_wr->
newwin = init_newwin(mad_send_wr);
887 ret = send_next_seg(mad_send_wr);
899 rmpp_mad = mad_send_wr->
send_buf.mad;
900 if (!(ib_get_rmpp_flags(&rmpp_mad->
rmpp_hdr) &
924 ret = send_next_seg(mad_send_wr);
937 rmpp_mad = mad_send_wr->
send_buf.mad;
938 if (!(ib_get_rmpp_flags(&rmpp_mad->
rmpp_hdr) &
948 ret = send_next_seg(mad_send_wr);