Lines Matching full:link

5  *  Link Layer Control (LLC)
108 u8 num_rkeys; /* first rtoken byte of CONFIRM LINK msg */
110 /* rtoken is always for the current link */
111 u8 link_id; /* link id of the rtoken */
158 struct smc_link *link; member
162 static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc);
213 struct smc_link_group *lgr = qentry->link->lgr; in smc_llc_flow_start()
289 /* lnk is optional and used for early wakeup when link goes down, useful in
290 * cases where we wait for a response on the link after we sent a request
336 struct smc_link *link, in smc_llc_tx_handler() argument
344 * @link: Pointer to SMC link used for sending LLC control message.
355 static int smc_llc_add_pending_send(struct smc_link *link, in smc_llc_add_pending_send() argument
361 rc = smc_wr_tx_get_free_slot(link, smc_llc_tx_handler, wr_buf, NULL, in smc_llc_add_pending_send()
370 …per layer protocols use the same message size any more, must start to set link->wr_tx_sges[i].leng… in smc_llc_add_pending_send()
377 /* high-level API to send LLC confirm link */
378 int smc_llc_send_confirm_link(struct smc_link *link, in smc_llc_send_confirm_link() argument
386 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_confirm_link()
396 memcpy(confllc->sender_mac, link->smcibdev->mac[link->ibport - 1], in smc_llc_send_confirm_link()
398 memcpy(confllc->sender_gid, link->gid, SMC_GID_SIZE); in smc_llc_send_confirm_link()
399 hton24(confllc->sender_qp_num, link->roce_qp->qp_num); in smc_llc_send_confirm_link()
400 confllc->link_num = link->link_id; in smc_llc_send_confirm_link()
401 memcpy(confllc->link_uid, link->link_uid, SMC_LGR_ID_SIZE); in smc_llc_send_confirm_link()
404 rc = smc_wr_tx_send(link, pend); in smc_llc_send_confirm_link()
415 struct smc_link *link; in smc_llc_send_confirm_rkey() local
428 link = &send_link->lgr->lnk[i]; in smc_llc_send_confirm_rkey()
429 if (smc_link_active(link) && link != send_link) { in smc_llc_send_confirm_rkey()
430 rkeyllc->rtoken[rtok_ix].link_id = link->link_id; in smc_llc_send_confirm_rkey()
432 htonl(rmb_desc->mr_rx[link->link_idx]->rkey); in smc_llc_send_confirm_rkey()
435 rmb_desc->sgt[link->link_idx].sgl)); in smc_llc_send_confirm_rkey()
451 static int smc_llc_send_delete_rkey(struct smc_link *link, in smc_llc_send_delete_rkey() argument
459 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_delete_rkey()
467 rkeyllc->rkey[0] = htonl(rmb_desc->mr_rx[link->link_idx]->rkey); in smc_llc_send_delete_rkey()
469 rc = smc_wr_tx_send(link, pend); in smc_llc_send_delete_rkey()
473 /* send ADD LINK request or response */
474 int smc_llc_send_add_link(struct smc_link *link, u8 mac[], u8 gid[], in smc_llc_send_add_link() argument
483 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_add_link()
506 rc = smc_wr_tx_send(link, pend); in smc_llc_send_add_link()
510 /* send DELETE LINK request or response */
511 int smc_llc_send_delete_link(struct smc_link *link, u8 link_del_id, in smc_llc_send_delete_link() argument
520 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_delete_link()
538 rc = smc_wr_tx_send(link, pend); in smc_llc_send_delete_link()
542 /* send LLC test link request */
543 static int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16]) in smc_llc_send_test_link() argument
550 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_test_link()
559 rc = smc_wr_tx_send(link, pend); in smc_llc_send_test_link()
563 /* schedule an llc send on link, may wait for buffers */
564 static int smc_llc_send_message(struct smc_link *link, void *llcbuf) in smc_llc_send_message() argument
570 if (!smc_link_usable(link)) in smc_llc_send_message()
572 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_message()
576 return smc_wr_tx_send(link, pend); in smc_llc_send_message()
579 /* schedule an llc send on link, may wait for buffers,
583 static int smc_llc_send_message_wait(struct smc_link *link, void *llcbuf) in smc_llc_send_message_wait() argument
589 if (!smc_link_usable(link)) in smc_llc_send_message_wait()
591 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_send_message_wait()
595 return smc_wr_tx_send_wait(link, pend, SMC_LLC_WAIT_TIME); in smc_llc_send_message_wait()
663 static int smc_llc_add_link_cont(struct smc_link *link, in smc_llc_add_link_cont() argument
668 struct smc_link_group *lgr = link->lgr; in smc_llc_add_link_cont()
675 rc = smc_llc_add_pending_send(link, &wr_buf, &pend); in smc_llc_add_link_cont()
681 prim_lnk_idx = link->link_idx; in smc_llc_add_link_cont()
709 return smc_wr_tx_send(link, pend); in smc_llc_add_link_cont()
712 static int smc_llc_cli_rkey_exchange(struct smc_link *link, in smc_llc_cli_rkey_exchange() argument
716 struct smc_link_group *lgr = link->lgr; in smc_llc_cli_rkey_exchange()
738 smc_rtoken_set(lgr, link->link_idx, link_new->link_idx, in smc_llc_cli_rkey_exchange()
745 rc = smc_llc_add_link_cont(link, link_new, &num_rkeys_send, in smc_llc_cli_rkey_exchange()
755 /* prepare and send an add link reject response */
761 return smc_llc_send_message(qentry->link, &qentry->msg); in smc_llc_cli_add_link_reject()
764 static int smc_llc_cli_conf_link(struct smc_link *link, in smc_llc_cli_conf_link() argument
769 struct smc_link_group *lgr = link->lgr; in smc_llc_cli_conf_link()
773 /* receive CONFIRM LINK request over RoCE fabric */ in smc_llc_cli_conf_link()
776 rc = smc_llc_send_delete_link(link, link_new->link_id, in smc_llc_cli_conf_link()
784 smc_llc_send_message(link, &qentry->msg); in smc_llc_cli_conf_link()
793 smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, in smc_llc_cli_conf_link()
801 smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, in smc_llc_cli_conf_link()
806 /* send CONFIRM LINK response over RoCE fabric */ in smc_llc_cli_conf_link()
809 smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, in smc_llc_cli_conf_link()
822 static void smc_llc_save_add_link_info(struct smc_link *link, in smc_llc_save_add_link_info() argument
825 link->peer_qpn = ntoh24(add_llc->sender_qp_num); in smc_llc_save_add_link_info()
826 memcpy(link->peer_gid, add_llc->sender_gid, SMC_GID_SIZE); in smc_llc_save_add_link_info()
827 memcpy(link->peer_mac, add_llc->sender_mac, ETH_ALEN); in smc_llc_save_add_link_info()
828 link->peer_psn = ntoh24(add_llc->initial_psn); in smc_llc_save_add_link_info()
829 link->peer_mtu = add_llc->qp_mtu; in smc_llc_save_add_link_info()
832 /* as an SMC client, process an add link request */
833 int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry) in smc_llc_cli_add_link() argument
837 struct smc_link_group *lgr = smc_get_lgr(link); in smc_llc_cli_add_link()
846 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev); in smc_llc_cli_add_link()
847 if (!memcmp(llc->sender_gid, link->peer_gid, SMC_GID_SIZE) && in smc_llc_cli_add_link()
848 !memcmp(llc->sender_mac, link->peer_mac, ETH_ALEN)) { in smc_llc_cli_add_link()
855 ini.ib_dev = link->smcibdev; in smc_llc_cli_add_link()
856 ini.ib_port = link->ibport; in smc_llc_cli_add_link()
866 lnk_new->link_id = llc->link_num; /* SMC server assigns link id */ in smc_llc_cli_add_link()
877 rc = smc_llc_send_add_link(link, in smc_llc_cli_add_link()
882 rc = smc_llc_cli_rkey_exchange(link, lnk_new); in smc_llc_cli_add_link()
887 rc = smc_llc_cli_conf_link(link, &ini, lnk_new, lgr_new_t); in smc_llc_cli_add_link()
900 static void smc_llc_cli_add_link_invite(struct smc_link *link, in smc_llc_cli_add_link_invite() argument
903 struct smc_link_group *lgr = smc_get_lgr(link); in smc_llc_cli_add_link_invite()
911 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev); in smc_llc_cli_add_link_invite()
915 smc_llc_send_add_link(link, ini.ib_dev->mac[ini.ib_port - 1], in smc_llc_cli_add_link_invite()
947 smc_llc_cli_add_link_invite(qentry->link, qentry); in smc_llc_process_cli_add_link()
949 smc_llc_cli_add_link(qentry->link, qentry); in smc_llc_process_cli_add_link()
965 /* find the asymmetric link when 3 links are established */
972 /* determine asymmetric link */ in smc_llc_find_asym_link()
989 goto out; /* no asymmetric link */ in smc_llc_find_asym_link()
1018 return; /* no asymmetric link */ in smc_llc_delete_asym_link()
1044 static int smc_llc_srv_rkey_exchange(struct smc_link *link, in smc_llc_srv_rkey_exchange() argument
1048 struct smc_link_group *lgr = link->lgr; in smc_llc_srv_rkey_exchange()
1060 smc_llc_add_link_cont(link, link_new, &num_rkeys_send, in smc_llc_srv_rkey_exchange()
1062 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_TIME, in smc_llc_srv_rkey_exchange()
1072 smc_rtoken_set(lgr, link->link_idx, link_new->link_idx, in smc_llc_srv_rkey_exchange()
1085 static int smc_llc_srv_conf_link(struct smc_link *link, in smc_llc_srv_conf_link() argument
1089 struct smc_link_group *lgr = link->lgr; in smc_llc_srv_conf_link()
1093 /* send CONFIRM LINK request over the RoCE fabric */ in smc_llc_srv_conf_link()
1097 /* receive CONFIRM LINK response over the RoCE fabric */ in smc_llc_srv_conf_link()
1098 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_FIRST_TIME, 0); in smc_llc_srv_conf_link()
1101 /* send DELETE LINK */ in smc_llc_srv_conf_link()
1102 smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, in smc_llc_srv_conf_link()
1119 int smc_llc_srv_add_link(struct smc_link *link) in smc_llc_srv_add_link() argument
1122 struct smc_link_group *lgr = link->lgr; in smc_llc_srv_add_link()
1129 /* ignore client add link recommendation, start new flow */ in smc_llc_srv_add_link()
1131 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev); in smc_llc_srv_add_link()
1134 ini.ib_dev = link->smcibdev; in smc_llc_srv_add_link()
1135 ini.ib_port = link->ibport; in smc_llc_srv_add_link()
1145 rc = smc_llc_send_add_link(link, in smc_llc_srv_add_link()
1150 /* receive ADD LINK response over the RoCE fabric */ in smc_llc_srv_add_link()
1151 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_TIME, SMC_LLC_ADD_LINK); in smc_llc_srv_add_link()
1163 (!memcmp(add_llc->sender_gid, link->peer_gid, SMC_GID_SIZE) && in smc_llc_srv_add_link()
1164 !memcmp(add_llc->sender_mac, link->peer_mac, ETH_ALEN))) { in smc_llc_srv_add_link()
1179 rc = smc_llc_srv_rkey_exchange(link, link_new); in smc_llc_srv_add_link()
1182 rc = smc_llc_srv_conf_link(link, link_new, lgr_new_t); in smc_llc_srv_add_link()
1193 struct smc_link *link = lgr->llc_flow_lcl.qentry->link; in smc_llc_process_srv_add_link() local
1199 rc = smc_llc_srv_add_link(link); in smc_llc_process_srv_add_link()
1201 /* delete any asymmetric link */ in smc_llc_process_srv_add_link()
1208 void smc_llc_add_link_local(struct smc_link *link) in smc_llc_add_link_local() argument
1215 smc_llc_enqueue(link, (union smc_llc_msg *)&add_llc); in smc_llc_add_link_local()
1218 /* worker to process an add link message */
1225 /* link group is terminating */ in smc_llc_add_link_work()
1241 void smc_llc_srv_delete_link_local(struct smc_link *link, u8 del_link_id) in smc_llc_srv_delete_link_local() argument
1250 smc_llc_enqueue(link, (union smc_llc_msg *)&del_llc); in smc_llc_srv_delete_link_local()
1262 lnk = qentry->link; in smc_llc_process_cli_delete_link()
1270 /* delete single link */ in smc_llc_process_cli_delete_link()
1279 /* link was not found */ in smc_llc_process_cli_delete_link()
1297 /* expected deletion of asym link, don't change lgr state */ in smc_llc_process_cli_delete_link()
1310 /* try to send a DELETE LINK ALL request on any active link,
1343 lnk = qentry->link; in smc_llc_process_srv_delete_link()
1353 /* delete single link */ in smc_llc_process_srv_delete_link()
1362 goto out; /* asymmetric link already deleted */ in smc_llc_process_srv_delete_link()
1393 /* trigger setup of asymm alt link */ in smc_llc_process_srv_delete_link()
1407 /* link group is terminating */ in smc_llc_delete_link_work()
1425 struct smc_link *link; in smc_llc_rmt_conf_rkey() local
1432 link = qentry->link; in smc_llc_rmt_conf_rkey()
1435 /* first rkey entry is for receiving link */ in smc_llc_rmt_conf_rkey()
1436 rk_idx = smc_rtoken_add(link, in smc_llc_rmt_conf_rkey()
1453 smc_llc_send_message(link, &qentry->msg); in smc_llc_rmt_conf_rkey()
1462 struct smc_link *link; in smc_llc_rmt_delete_rkey() local
1468 link = qentry->link; in smc_llc_rmt_delete_rkey()
1472 if (smc_rtoken_delete(link, llc->rkey[i])) in smc_llc_rmt_delete_rkey()
1480 smc_llc_send_message(link, &qentry->msg); in smc_llc_rmt_delete_rkey()
1508 struct smc_link *link = qentry->link; in smc_llc_event_handler() local
1509 struct smc_link_group *lgr = link->lgr; in smc_llc_event_handler()
1511 if (!smc_link_usable(link)) in smc_llc_event_handler()
1517 smc_llc_send_message(link, llc); in smc_llc_event_handler()
1560 /* DEL LINK REQ during ADD LINK SEQ */ in smc_llc_event_handler()
1606 if (smc_link_usable(qentry->link)) in smc_llc_event_work()
1626 static void smc_llc_rx_response(struct smc_link *link, in smc_llc_rx_response() argument
1629 enum smc_llc_flowtype flowtype = link->lgr->llc_flow_lcl.type; in smc_llc_rx_response()
1630 struct smc_llc_flow *flow = &link->lgr->llc_flow_lcl; in smc_llc_rx_response()
1635 if (smc_link_active(link)) in smc_llc_rx_response()
1636 complete(&link->llc_testlink_resp); in smc_llc_rx_response()
1657 smc_llc_protocol_violation(link->lgr, llc_type); in smc_llc_rx_response()
1664 smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry); in smc_llc_rx_response()
1665 wake_up(&link->lgr->llc_msg_waiter); in smc_llc_rx_response()
1668 static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc) in smc_llc_enqueue() argument
1670 struct smc_link_group *lgr = link->lgr; in smc_llc_enqueue()
1677 qentry->link = link; in smc_llc_enqueue()
1683 smc_llc_rx_response(link, qentry); in smc_llc_enqueue()
1697 struct smc_link *link = (struct smc_link *)wc->qp->qp_context; in smc_llc_rx_handler() local
1705 smc_llc_enqueue(link, llc); in smc_llc_rx_handler()
1712 struct smc_link *link = container_of(to_delayed_work(work), in smc_llc_testlink_work() local
1719 if (!smc_link_active(link)) in smc_llc_testlink_work()
1721 expire_time = link->wr_rx_tstamp + link->llc_testlink_time; in smc_llc_testlink_work()
1726 reinit_completion(&link->llc_testlink_resp); in smc_llc_testlink_work()
1727 smc_llc_send_test_link(link, user_data); in smc_llc_testlink_work()
1728 /* receive TEST LINK response over RoCE fabric */ in smc_llc_testlink_work()
1729 rc = wait_for_completion_interruptible_timeout(&link->llc_testlink_resp, in smc_llc_testlink_work()
1731 if (!smc_link_active(link)) in smc_llc_testlink_work()
1732 return; /* link state changed */ in smc_llc_testlink_work()
1734 smcr_link_down_cond_sched(link); in smc_llc_testlink_work()
1737 next_interval = link->llc_testlink_time; in smc_llc_testlink_work()
1739 schedule_delayed_work(&link->llc_testlink_wrk, next_interval); in smc_llc_testlink_work()
1773 int smc_llc_link_init(struct smc_link *link) in smc_llc_link_init() argument
1775 init_completion(&link->llc_testlink_resp); in smc_llc_link_init()
1776 INIT_DELAYED_WORK(&link->llc_testlink_wrk, smc_llc_testlink_work); in smc_llc_link_init()
1780 void smc_llc_link_active(struct smc_link *link) in smc_llc_link_active() argument
1782 pr_warn_ratelimited("smc: SMC-R lg %*phN link added: id %*phN, " in smc_llc_link_active()
1784 SMC_LGR_ID_SIZE, &link->lgr->id, in smc_llc_link_active()
1785 SMC_LGR_ID_SIZE, &link->link_uid, in smc_llc_link_active()
1786 SMC_LGR_ID_SIZE, &link->peer_link_uid, in smc_llc_link_active()
1787 link->smcibdev->ibdev->name, link->ibport); in smc_llc_link_active()
1788 link->state = SMC_LNK_ACTIVE; in smc_llc_link_active()
1789 if (link->lgr->llc_testlink_time) { in smc_llc_link_active()
1790 link->llc_testlink_time = link->lgr->llc_testlink_time * HZ; in smc_llc_link_active()
1791 schedule_delayed_work(&link->llc_testlink_wrk, in smc_llc_link_active()
1792 link->llc_testlink_time); in smc_llc_link_active()
1797 void smc_llc_link_clear(struct smc_link *link, bool log) in smc_llc_link_clear() argument
1800 pr_warn_ratelimited("smc: SMC-R lg %*phN link removed: id %*phN" in smc_llc_link_clear()
1802 SMC_LGR_ID_SIZE, &link->lgr->id, in smc_llc_link_clear()
1803 SMC_LGR_ID_SIZE, &link->link_uid, in smc_llc_link_clear()
1804 SMC_LGR_ID_SIZE, &link->peer_link_uid, in smc_llc_link_clear()
1805 link->smcibdev->ibdev->name, link->ibport); in smc_llc_link_clear()
1806 complete(&link->llc_testlink_resp); in smc_llc_link_clear()
1807 cancel_delayed_work_sync(&link->llc_testlink_wrk); in smc_llc_link_clear()
1808 smc_wr_wakeup_reg_wait(link); in smc_llc_link_clear()
1809 smc_wr_wakeup_tx_wait(link); in smc_llc_link_clear()
1861 void smc_llc_link_set_uid(struct smc_link *link) in smc_llc_link_set_uid() argument
1865 link_uid = htonl(*((u32 *)link->lgr->id) + link->link_id); in smc_llc_link_set_uid()
1866 memcpy(link->link_uid, &link_uid, SMC_LGR_ID_SIZE); in smc_llc_link_set_uid()
1869 /* save peers link user id, used for debug purposes */
1872 memcpy(qentry->link->peer_link_uid, qentry->msg.confirm_link.link_uid, in smc_llc_save_peer_uid()
1876 /* evaluate confirm link request or response */
1881 qentry->link->link_id = qentry->msg.confirm_link.link_num; in smc_llc_eval_conf_link()
1882 smc_llc_link_set_uid(qentry->link); in smc_llc_eval_conf_link()