Lines Matching refs:rmpp_recv
73 static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv) in deref_rmpp_recv() argument
75 if (refcount_dec_and_test(&rmpp_recv->refcount)) in deref_rmpp_recv()
76 complete(&rmpp_recv->comp); in deref_rmpp_recv()
79 static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv) in destroy_rmpp_recv() argument
81 deref_rmpp_recv(rmpp_recv); in destroy_rmpp_recv()
82 wait_for_completion(&rmpp_recv->comp); in destroy_rmpp_recv()
83 rdma_destroy_ah(rmpp_recv->ah, RDMA_DESTROY_AH_SLEEPABLE); in destroy_rmpp_recv()
84 kfree(rmpp_recv); in destroy_rmpp_recv()
89 struct mad_rmpp_recv *rmpp_recv, *temp_rmpp_recv; in ib_cancel_rmpp_recvs() local
93 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) { in ib_cancel_rmpp_recvs()
94 cancel_delayed_work(&rmpp_recv->timeout_work); in ib_cancel_rmpp_recvs()
95 cancel_delayed_work(&rmpp_recv->cleanup_work); in ib_cancel_rmpp_recvs()
101 list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv, in ib_cancel_rmpp_recvs()
103 list_del(&rmpp_recv->list); in ib_cancel_rmpp_recvs()
104 if (rmpp_recv->state != RMPP_STATE_COMPLETE) in ib_cancel_rmpp_recvs()
105 ib_free_recv_mad(rmpp_recv->rmpp_wc); in ib_cancel_rmpp_recvs()
106 destroy_rmpp_recv(rmpp_recv); in ib_cancel_rmpp_recvs()
112 struct mad_rmpp_recv *rmpp_recv) in format_ack() argument
123 spin_lock_irqsave(&rmpp_recv->lock, flags); in format_ack()
124 rmpp_recv->last_ack = rmpp_recv->seg_num; in format_ack()
125 ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num); in format_ack()
126 ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin); in format_ack()
127 spin_unlock_irqrestore(&rmpp_recv->lock, flags); in format_ack()
130 static void ack_recv(struct mad_rmpp_recv *rmpp_recv, in ack_recv() argument
137 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, in ack_recv()
144 format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); in ack_recv()
145 msg->ah = rmpp_recv->ah; in ack_recv()
243 struct mad_rmpp_recv *rmpp_recv = in recv_timeout_handler() local
248 spin_lock_irqsave(&rmpp_recv->agent->lock, flags); in recv_timeout_handler()
249 if (rmpp_recv->state != RMPP_STATE_ACTIVE) { in recv_timeout_handler()
250 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); in recv_timeout_handler()
253 rmpp_recv->state = RMPP_STATE_TIMEOUT; in recv_timeout_handler()
254 list_del(&rmpp_recv->list); in recv_timeout_handler()
255 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); in recv_timeout_handler()
257 rmpp_wc = rmpp_recv->rmpp_wc; in recv_timeout_handler()
258 nack_recv(rmpp_recv->agent, rmpp_wc, IB_MGMT_RMPP_STATUS_T2L); in recv_timeout_handler()
259 destroy_rmpp_recv(rmpp_recv); in recv_timeout_handler()
265 struct mad_rmpp_recv *rmpp_recv = in recv_cleanup_handler() local
269 spin_lock_irqsave(&rmpp_recv->agent->lock, flags); in recv_cleanup_handler()
270 list_del(&rmpp_recv->list); in recv_cleanup_handler()
271 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); in recv_cleanup_handler()
272 destroy_rmpp_recv(rmpp_recv); in recv_cleanup_handler()
279 struct mad_rmpp_recv *rmpp_recv; in create_rmpp_recv() local
282 rmpp_recv = kmalloc(sizeof *rmpp_recv, GFP_KERNEL); in create_rmpp_recv()
283 if (!rmpp_recv) in create_rmpp_recv()
286 rmpp_recv->ah = ib_create_ah_from_wc(agent->agent.qp->pd, in create_rmpp_recv()
290 if (IS_ERR(rmpp_recv->ah)) in create_rmpp_recv()
293 rmpp_recv->agent = agent; in create_rmpp_recv()
294 init_completion(&rmpp_recv->comp); in create_rmpp_recv()
295 INIT_DELAYED_WORK(&rmpp_recv->timeout_work, recv_timeout_handler); in create_rmpp_recv()
296 INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler); in create_rmpp_recv()
297 spin_lock_init(&rmpp_recv->lock); in create_rmpp_recv()
298 rmpp_recv->state = RMPP_STATE_ACTIVE; in create_rmpp_recv()
299 refcount_set(&rmpp_recv->refcount, 1); in create_rmpp_recv()
301 rmpp_recv->rmpp_wc = mad_recv_wc; in create_rmpp_recv()
302 rmpp_recv->cur_seg_buf = &mad_recv_wc->recv_buf; in create_rmpp_recv()
303 rmpp_recv->newwin = 1; in create_rmpp_recv()
304 rmpp_recv->seg_num = 1; in create_rmpp_recv()
305 rmpp_recv->last_ack = 0; in create_rmpp_recv()
306 rmpp_recv->repwin = 1; in create_rmpp_recv()
309 rmpp_recv->tid = mad_hdr->tid; in create_rmpp_recv()
310 rmpp_recv->src_qp = mad_recv_wc->wc->src_qp; in create_rmpp_recv()
311 rmpp_recv->slid = mad_recv_wc->wc->slid; in create_rmpp_recv()
312 rmpp_recv->mgmt_class = mad_hdr->mgmt_class; in create_rmpp_recv()
313 rmpp_recv->class_version = mad_hdr->class_version; in create_rmpp_recv()
314 rmpp_recv->method = mad_hdr->method; in create_rmpp_recv()
315 rmpp_recv->base_version = mad_hdr->base_version; in create_rmpp_recv()
316 return rmpp_recv; in create_rmpp_recv()
318 error: kfree(rmpp_recv); in create_rmpp_recv()
326 struct mad_rmpp_recv *rmpp_recv; in find_rmpp_recv() local
329 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) { in find_rmpp_recv()
330 if (rmpp_recv->tid == mad_hdr->tid && in find_rmpp_recv()
331 rmpp_recv->src_qp == mad_recv_wc->wc->src_qp && in find_rmpp_recv()
332 rmpp_recv->slid == mad_recv_wc->wc->slid && in find_rmpp_recv()
333 rmpp_recv->mgmt_class == mad_hdr->mgmt_class && in find_rmpp_recv()
334 rmpp_recv->class_version == mad_hdr->class_version && in find_rmpp_recv()
335 rmpp_recv->method == mad_hdr->method) in find_rmpp_recv()
336 return rmpp_recv; in find_rmpp_recv()
345 struct mad_rmpp_recv *rmpp_recv; in acquire_rmpp_recv() local
349 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc); in acquire_rmpp_recv()
350 if (rmpp_recv) in acquire_rmpp_recv()
351 refcount_inc(&rmpp_recv->refcount); in acquire_rmpp_recv()
353 return rmpp_recv; in acquire_rmpp_recv()
358 struct mad_rmpp_recv *rmpp_recv) in insert_rmpp_recv() argument
362 cur_rmpp_recv = find_rmpp_recv(agent, rmpp_recv->rmpp_wc); in insert_rmpp_recv()
364 list_add_tail(&rmpp_recv->list, &agent->rmpp_list); in insert_rmpp_recv()
415 static void update_seg_num(struct mad_rmpp_recv *rmpp_recv, in update_seg_num() argument
418 struct list_head *rmpp_list = &rmpp_recv->rmpp_wc->rmpp_list; in update_seg_num()
420 while (new_buf && (get_seg_num(new_buf) == rmpp_recv->seg_num + 1)) { in update_seg_num()
421 rmpp_recv->cur_seg_buf = new_buf; in update_seg_num()
422 rmpp_recv->seg_num++; in update_seg_num()
427 static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv) in get_mad_len() argument
431 bool opa = rdma_cap_opa_mad(rmpp_recv->agent->qp_info->port_priv->device, in get_mad_len()
432 rmpp_recv->agent->qp_info->port_priv->port_num); in get_mad_len()
434 rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad; in get_mad_len()
437 if (opa && rmpp_recv->base_version == OPA_MGMT_BASE_VERSION) { in get_mad_len()
449 return hdr_size + rmpp_recv->seg_num * data_size - pad; in get_mad_len()
452 static struct ib_mad_recv_wc *complete_rmpp(struct mad_rmpp_recv *rmpp_recv) in complete_rmpp() argument
456 ack_recv(rmpp_recv, rmpp_recv->rmpp_wc); in complete_rmpp()
457 if (rmpp_recv->seg_num > 1) in complete_rmpp()
458 cancel_delayed_work(&rmpp_recv->timeout_work); in complete_rmpp()
460 rmpp_wc = rmpp_recv->rmpp_wc; in complete_rmpp()
461 rmpp_wc->mad_len = get_mad_len(rmpp_recv); in complete_rmpp()
463 queue_delayed_work(rmpp_recv->agent->qp_info->port_priv->wq, in complete_rmpp()
464 &rmpp_recv->cleanup_work, msecs_to_jiffies(10000)); in complete_rmpp()
472 struct mad_rmpp_recv *rmpp_recv; in continue_rmpp() local
478 rmpp_recv = acquire_rmpp_recv(agent, mad_recv_wc); in continue_rmpp()
479 if (!rmpp_recv) in continue_rmpp()
484 spin_lock_irqsave(&rmpp_recv->lock, flags); in continue_rmpp()
485 if ((rmpp_recv->state == RMPP_STATE_TIMEOUT) || in continue_rmpp()
486 (seg_num > rmpp_recv->newwin)) in continue_rmpp()
489 if ((seg_num <= rmpp_recv->last_ack) || in continue_rmpp()
490 (rmpp_recv->state == RMPP_STATE_COMPLETE)) { in continue_rmpp()
491 spin_unlock_irqrestore(&rmpp_recv->lock, flags); in continue_rmpp()
492 ack_recv(rmpp_recv, mad_recv_wc); in continue_rmpp()
496 prev_buf = find_seg_location(&rmpp_recv->rmpp_wc->rmpp_list, seg_num); in continue_rmpp()
502 if (rmpp_recv->cur_seg_buf == prev_buf) { in continue_rmpp()
503 update_seg_num(rmpp_recv, &mad_recv_wc->recv_buf); in continue_rmpp()
504 if (get_last_flag(rmpp_recv->cur_seg_buf)) { in continue_rmpp()
505 rmpp_recv->state = RMPP_STATE_COMPLETE; in continue_rmpp()
506 spin_unlock_irqrestore(&rmpp_recv->lock, flags); in continue_rmpp()
507 done_wc = complete_rmpp(rmpp_recv); in continue_rmpp()
509 } else if (rmpp_recv->seg_num == rmpp_recv->newwin) { in continue_rmpp()
510 rmpp_recv->newwin += window_size(agent); in continue_rmpp()
511 spin_unlock_irqrestore(&rmpp_recv->lock, flags); in continue_rmpp()
512 ack_recv(rmpp_recv, mad_recv_wc); in continue_rmpp()
516 spin_unlock_irqrestore(&rmpp_recv->lock, flags); in continue_rmpp()
518 deref_rmpp_recv(rmpp_recv); in continue_rmpp()
521 drop3: spin_unlock_irqrestore(&rmpp_recv->lock, flags); in continue_rmpp()
522 drop2: deref_rmpp_recv(rmpp_recv); in continue_rmpp()
531 struct mad_rmpp_recv *rmpp_recv; in start_rmpp() local
534 rmpp_recv = create_rmpp_recv(agent, mad_recv_wc); in start_rmpp()
535 if (!rmpp_recv) { in start_rmpp()
541 if (insert_rmpp_recv(agent, rmpp_recv)) { in start_rmpp()
544 destroy_rmpp_recv(rmpp_recv); in start_rmpp()
547 refcount_inc(&rmpp_recv->refcount); in start_rmpp()
550 rmpp_recv->state = RMPP_STATE_COMPLETE; in start_rmpp()
552 complete_rmpp(rmpp_recv); in start_rmpp()
557 &rmpp_recv->timeout_work, in start_rmpp()
559 rmpp_recv->newwin += window_size(agent); in start_rmpp()
560 ack_recv(rmpp_recv, mad_recv_wc); in start_rmpp()
563 deref_rmpp_recv(rmpp_recv); in start_rmpp()
641 struct mad_rmpp_recv *rmpp_recv; in process_ds_ack() local
643 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc); in process_ds_ack()
644 if (rmpp_recv && rmpp_recv->state == RMPP_STATE_COMPLETE) in process_ds_ack()
645 rmpp_recv->repwin = newwin; in process_ds_ack()
846 struct mad_rmpp_recv *rmpp_recv; in init_newwin() local
855 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) { in init_newwin()
856 if (rmpp_recv->tid != mad_hdr->tid || in init_newwin()
857 rmpp_recv->mgmt_class != mad_hdr->mgmt_class || in init_newwin()
858 rmpp_recv->class_version != mad_hdr->class_version || in init_newwin()
859 (rmpp_recv->method & IB_MGMT_METHOD_RESP)) in init_newwin()
865 if (rmpp_recv->slid == rdma_ah_get_dlid(&ah_attr)) { in init_newwin()
866 newwin = rmpp_recv->repwin; in init_newwin()