net/smc: respond to test link messages
Add TEST LINK message responses, which also serves as preparation for support of sockopt TCP_KEEPALIVE. Signed-off-by: Karsten Graul <kgraul@linux.vnet.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
be6d467b99
commit
313164da55
|
@ -41,8 +41,15 @@ struct smc_llc_msg_confirm_link { /* type 0x01 */
|
||||||
u8 reserved[9];
|
u8 reserved[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct smc_llc_msg_test_link { /* type 0x07 */
|
||||||
|
struct smc_llc_hdr hd;
|
||||||
|
u8 user_data[16];
|
||||||
|
u8 reserved[24];
|
||||||
|
};
|
||||||
|
|
||||||
union smc_llc_msg {
|
union smc_llc_msg {
|
||||||
struct smc_llc_msg_confirm_link confirm_link;
|
struct smc_llc_msg_confirm_link confirm_link;
|
||||||
|
struct smc_llc_msg_test_link test_link;
|
||||||
struct {
|
struct {
|
||||||
struct smc_llc_hdr hdr;
|
struct smc_llc_hdr hdr;
|
||||||
u8 data[SMC_LLC_DATA_LEN];
|
u8 data[SMC_LLC_DATA_LEN];
|
||||||
|
@ -130,6 +137,30 @@ int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[],
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send LLC test link request or response */
|
||||||
|
int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16],
|
||||||
|
enum smc_llc_reqresp reqresp)
|
||||||
|
{
|
||||||
|
struct smc_llc_msg_test_link *testllc;
|
||||||
|
struct smc_wr_tx_pend_priv *pend;
|
||||||
|
struct smc_wr_buf *wr_buf;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
testllc = (struct smc_llc_msg_test_link *)wr_buf;
|
||||||
|
memset(testllc, 0, sizeof(*testllc));
|
||||||
|
testllc->hd.common.type = SMC_LLC_TEST_LINK;
|
||||||
|
testllc->hd.length = sizeof(struct smc_llc_msg_test_link);
|
||||||
|
if (reqresp == SMC_LLC_RESP)
|
||||||
|
testllc->hd.flags |= SMC_LLC_FLAG_RESP;
|
||||||
|
memcpy(testllc->user_data, user_data, sizeof(testllc->user_data));
|
||||||
|
/* send llc message */
|
||||||
|
rc = smc_wr_tx_send(link, pend);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************* receive ***********************************/
|
/********************************* receive ***********************************/
|
||||||
|
|
||||||
static void smc_llc_rx_confirm_link(struct smc_link *link,
|
static void smc_llc_rx_confirm_link(struct smc_link *link,
|
||||||
|
@ -149,6 +180,16 @@ static void smc_llc_rx_confirm_link(struct smc_link *link,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smc_llc_rx_test_link(struct smc_link *link,
|
||||||
|
struct smc_llc_msg_test_link *llc)
|
||||||
|
{
|
||||||
|
if (llc->hd.flags & SMC_LLC_FLAG_RESP) {
|
||||||
|
/* unused as long as we don't send this type of msg */
|
||||||
|
} else {
|
||||||
|
smc_llc_send_test_link(link, llc->user_data, SMC_LLC_RESP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
|
static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
|
||||||
{
|
{
|
||||||
struct smc_link *link = (struct smc_link *)wc->qp->qp_context;
|
struct smc_link *link = (struct smc_link *)wc->qp->qp_context;
|
||||||
|
@ -158,8 +199,15 @@ static void smc_llc_rx_handler(struct ib_wc *wc, void *buf)
|
||||||
return; /* short message */
|
return; /* short message */
|
||||||
if (llc->raw.hdr.length != sizeof(*llc))
|
if (llc->raw.hdr.length != sizeof(*llc))
|
||||||
return; /* invalid message */
|
return; /* invalid message */
|
||||||
if (llc->raw.hdr.common.type == SMC_LLC_CONFIRM_LINK)
|
|
||||||
|
switch (llc->raw.hdr.common.type) {
|
||||||
|
case SMC_LLC_TEST_LINK:
|
||||||
|
smc_llc_rx_test_link(link, &llc->test_link);
|
||||||
|
break;
|
||||||
|
case SMC_LLC_CONFIRM_LINK:
|
||||||
smc_llc_rx_confirm_link(link, &llc->confirm_link);
|
smc_llc_rx_confirm_link(link, &llc->confirm_link);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************** init, exit, misc ******************************/
|
/***************************** init, exit, misc ******************************/
|
||||||
|
@ -169,6 +217,10 @@ static struct smc_wr_rx_handler smc_llc_rx_handlers[] = {
|
||||||
.handler = smc_llc_rx_handler,
|
.handler = smc_llc_rx_handler,
|
||||||
.type = SMC_LLC_CONFIRM_LINK
|
.type = SMC_LLC_CONFIRM_LINK
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.handler = smc_llc_rx_handler,
|
||||||
|
.type = SMC_LLC_TEST_LINK
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.handler = NULL,
|
.handler = NULL,
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,14 @@ enum smc_llc_reqresp {
|
||||||
|
|
||||||
enum smc_llc_msg_type {
|
enum smc_llc_msg_type {
|
||||||
SMC_LLC_CONFIRM_LINK = 0x01,
|
SMC_LLC_CONFIRM_LINK = 0x01,
|
||||||
|
SMC_LLC_TEST_LINK = 0x07,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* transmit */
|
/* transmit */
|
||||||
int smc_llc_send_confirm_link(struct smc_link *lnk, u8 mac[], union ib_gid *gid,
|
int smc_llc_send_confirm_link(struct smc_link *lnk, u8 mac[], union ib_gid *gid,
|
||||||
enum smc_llc_reqresp reqresp);
|
enum smc_llc_reqresp reqresp);
|
||||||
|
int smc_llc_send_test_link(struct smc_link *lnk, u8 user_data[16],
|
||||||
|
enum smc_llc_reqresp reqresp);
|
||||||
int smc_llc_init(void) __init;
|
int smc_llc_init(void) __init;
|
||||||
|
|
||||||
#endif /* SMC_LLC_H */
|
#endif /* SMC_LLC_H */
|
||||||
|
|
Loading…
Reference in New Issue