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