CPL processing for Inline TLS client. Exchange messages with hardware to setup connection. Signed-off-by: Atul Gupta <atul.gupta@xxxxxxxxxxx> --- drivers/crypto/chelsio/chtls/chtls.h | 12 +- drivers/crypto/chelsio/chtls/chtls_cm.c | 308 +++++++++++++++++++++++----- drivers/crypto/chelsio/chtls/chtls_cm.h | 3 + drivers/crypto/chelsio/chtls/chtls_hw.c | 1 + drivers/crypto/chelsio/chtls/chtls_io.c | 41 ++-- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 18 ++ 6 files changed, 305 insertions(+), 78 deletions(-) diff --git a/drivers/crypto/chelsio/chtls/chtls.h b/drivers/crypto/chelsio/chtls/chtls.h index 9742613..0a9a688 100644 --- a/drivers/crypto/chelsio/chtls/chtls.h +++ b/drivers/crypto/chelsio/chtls/chtls.h @@ -44,6 +44,7 @@ #define SCMD_CIPH_MODE_AES_GCM 2 /* Any MFS size should work and come from openssl */ #define TLS_MFS 16384 +#define INVALID_TID 0xffffffffU #define RSS_HDR sizeof(struct rss_header) #define TLS_WR_CPL_LEN \ @@ -221,7 +222,8 @@ struct chtls_sock { u32 smac_idx; u8 port_id; u8 tos; - u16 resv2; + u8 hsk_done; + u8 resv2; u32 delack_mode; u32 delack_seq; u32 snd_win; @@ -229,6 +231,8 @@ struct chtls_sock { void *passive_reap_next; /* placeholder for passive */ struct chtls_hws tlshws; + struct delayed_work hsk_work; +#define TLS_CLIENT_WQ_CLR 0x1 struct synq { struct sk_buff *next; struct sk_buff *prev; @@ -457,9 +461,11 @@ static inline void __chtls_sock_get(const char *fn, static inline void send_or_defer(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb, int through_l2t) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; - if (through_l2t) { + if (unlikely(sk->sk_state == TCP_SYN_SENT)) { + __skb_queue_tail(&csk->ooq, skb); + } else if (through_l2t) { /* send through L2T */ cxgb4_l2t_send(csk->egress_dev, skb, csk->l2t_entry); } else { diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c index b11c991..9117629 100644 --- a/drivers/crypto/chelsio/chtls/chtls_cm.c +++ b/drivers/crypto/chelsio/chtls/chtls_cm.c @@ -52,6 +52,59 @@ /* TCP_CLOSING */ TCP_CLOSING, }; +void chtls_sock_release(struct kref *ref) +{ + struct chtls_sock *csk = + container_of(ref, struct chtls_sock, kref); + + kfree(csk); +} + +static int chtls_send_tls_rxmod(struct sock *sk) +{ + struct cpl_rx_data_ack *req; + struct chtls_sock *csk; + struct sk_buff *skb; + + csk = sk->sk_user_data; + skb = alloc_skb(sizeof(*req), GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + req = (struct cpl_rx_data_ack *)__skb_put(skb, sizeof(*req)); + memset(req, 0, sizeof(*req)); + INIT_TP_WR_CPL(req, CPL_RX_DATA_ACK, csk->tid); + OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, csk->tid)); + req->credit_dack = htonl(RX_MODULATE_RX_F); + skb_set_queue_mapping(skb, (csk->txq_idx << 1) | CPL_PRIORITY_ACK); + cxgb4_ofld_send(csk->egress_dev, skb); + + if (!(csk->hsk_done & TLS_CLIENT_WQ_CLR)) + schedule_delayed_work(&csk->hsk_work, TLS_SRV_HELLO_RD_TM); + + return 0; +} + +static void handshake_work(struct work_struct *work) +{ + struct chtls_sock *csk = + container_of(work, struct chtls_sock, hsk_work.work); + struct sock *sk = csk->sk; + + lock_sock(sk); + if (!(sk->sk_state == TCP_CLOSE || + sk->sk_state == TCP_TIME_WAIT || + csk->hsk_done != TLS_CLIENT_WQ_CLR)) { + if (chtls_send_tls_rxmod(sk)) + schedule_delayed_work(&csk->hsk_work, + TLS_SRV_HELLO_RD_TM); + } else { + kref_put(&csk->kref, chtls_sock_release); + sock_put(sk); + } + release_sock(sk); +} + static struct chtls_sock *chtls_sock_create(struct chtls_dev *cdev) { struct chtls_sock *csk = kzalloc(sizeof(*csk), GFP_ATOMIC); @@ -77,17 +130,10 @@ static struct chtls_sock *chtls_sock_create(struct chtls_dev *cdev) csk->tlshws.rxkey = -1; csk->tlshws.mfs = TLS_MFS; skb_queue_head_init(&csk->tlshws.sk_recv_queue); + INIT_DELAYED_WORK(&csk->hsk_work, handshake_work); return csk; } -static void chtls_sock_release(struct kref *ref) -{ - struct chtls_sock *csk = - container_of(ref, struct chtls_sock, kref); - - kfree(csk); -} - static int bh_insert_handle(struct chtls_dev *cdev, struct sock *sk, int tid) { @@ -99,6 +145,13 @@ static int bh_insert_handle(struct chtls_dev *cdev, struct sock *sk, return id; } +static void bh_remove_handle(struct chtls_dev *cdev, int tid) +{ + spin_lock_bh(&cdev->idr_lock); + idr_remove(&cdev->hwtid_idr, tid); + spin_unlock_bh(&cdev->idr_lock); +} + static int sk_insert_tid(struct chtls_dev *cdev, struct sock *sk, unsigned int tid) { @@ -180,7 +233,7 @@ static void assign_rxopt(struct sock *sk, unsigned int opt) tp->rx_opt.rcv_wscale = 0; if (tp->rx_opt.tstamp_ok) { tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED; - tp->rx_opt.mss_clamp -= TCPOLEN_TSTAMP_ALIGNED; + tp->mss_cache -= TCPOLEN_TSTAMP_ALIGNED; } else if (csk->opt2 & TSTAMPS_EN_F) { csk->opt2 &= ~TSTAMPS_EN_F; csk->mtu_idx = TCPOPT_MSS_G(opt); @@ -249,10 +302,21 @@ static void chtls_send_abort(struct sock *sk, int mode, struct sk_buff *skb) struct cpl_abort_req *req; struct chtls_sock *csk; struct tcp_sock *tp; + bool use_negadv_tid; + unsigned int tid; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; tp = tcp_sk(sk); + if (sk->sk_state == TCP_SYN_SENT && + csk->neg_adv_tid != INVALID_TID) { + tid = csk->neg_adv_tid; + csk->idr = sk_insert_tid(csk->cdev, sk, tid); + use_negadv_tid = true; + } else { + tid = csk->tid; + } + if (!skb) skb = alloc_ctrl_skb(csk->txdata_skb_cache, sizeof(*req)); @@ -262,8 +326,13 @@ static void chtls_send_abort(struct sock *sk, int mode, struct sk_buff *skb) req->rsvd0 = htonl(tp->snd_nxt); req->rsvd1 = !csk_flag_nochk(csk, CSK_TX_DATA_SENT); req->cmd = mode; - t4_set_arp_err_handler(skb, csk->cdev, abort_arp_failure); - send_or_defer(sk, tp, skb, mode == CPL_ABORT_SEND_RST); + if (unlikely(use_negadv_tid)) { + __skb_queue_tail(&csk->ooq, skb); + fixup_and_send_ofo(csk, tid); + } else { + t4_set_arp_err_handler(skb, csk->cdev, abort_arp_failure); + send_or_defer(sk, tp, skb, mode == CPL_ABORT_SEND_RST); + } } static void chtls_send_reset(struct sock *sk, int mode, struct sk_buff *skb) @@ -467,9 +536,11 @@ static int wait_for_states(struct sock *sk, unsigned int states) int chtls_disconnect(struct sock *sk, int flags) { + struct chtls_sock *csk; struct tcp_sock *tp; int err; + csk = sk->sk_user_data; tp = tcp_sk(sk); chtls_purge_recv_queue(sk); chtls_purge_receive_queue(sk); @@ -484,6 +555,7 @@ int chtls_disconnect(struct sock *sk, int flags) } chtls_purge_recv_queue(sk); chtls_purge_receive_queue(sk); + __skb_queue_purge(&csk->ooq); tp->max_window = 0xFFFF << (tp->rx_opt.snd_wscale); return tcp_disconnect(sk, flags); } @@ -507,6 +579,7 @@ void chtls_destroy_sock(struct sock *sk) csk->ulp_mode = ULP_MODE_NONE; chtls_purge_write_queue(sk); free_tls_keyid(sk); + stop_hndsk_work(sk); kref_put(&csk->kref, chtls_sock_release); sk->sk_prot = &tcp_prot; sk->sk_prot->destroy(sk); @@ -825,8 +898,14 @@ static void chtls_release_resources(struct sock *sk) csk->l2t_entry = NULL; } - cxgb4_remove_tid(tids, csk->port_id, tid, sk->sk_family); - sock_put(sk); + if (sk->sk_state == TCP_SYN_SENT) { + free_atid(csk, cdev, tid); + __skb_queue_purge(&csk->ooq); + } else { + cxgb4_remove_tid(tids, csk->port_id, tid, sk->sk_family); + bh_remove_handle(cdev, csk->idr); + sock_put(sk); + } } static void chtls_conn_done(struct sock *sk) @@ -936,7 +1015,7 @@ static unsigned int chtls_select_mss(const struct chtls_sock *csk, unsigned int mss; struct sock *sk; - mss = ntohs(req->tcpopt.mss); + mss = req ? ntohs(req->tcpopt.mss) : 0; sk = csk->sk; dst = __sk_dst_get(sk); cdev = csk->cdev; @@ -944,7 +1023,7 @@ static unsigned int chtls_select_mss(const struct chtls_sock *csk, tcpoptsz = 0; iphdrsz = sizeof(struct iphdr) + sizeof(struct tcphdr); - if (req->tcpopt.tstamp) + if (sock_net(sk)->ipv4.sysctl_tcp_timestamps) tcpoptsz += round_up(TCPOLEN_TIMESTAMP, 4); tp->advmss = dst_metric_advmss(dst); @@ -1260,6 +1339,155 @@ static void chtls_connect_req_arp_failure(void *handle, struct sk_buff *skb) sock_put(sk); } +void chtls_handshake_work(struct sock *sk) +{ + struct chtls_sock *csk = sk->sk_user_data; + + sock_hold(sk); + kref_get(&csk->kref); + schedule_delayed_work(&csk->hsk_work, TLS_SRV_HELLO_BKOFF_TM); +} + +void stop_hndsk_work(struct sock *sk) +{ + struct chtls_sock *csk = sk->sk_user_data; + + csk->hsk_done = TLS_CLIENT_WQ_CLR; + if (cancel_delayed_work(&csk->hsk_work)) { + kref_put(&csk->kref, chtls_sock_release); + sock_put(sk); + } +} + +void chtls_fix_pending_tx_buffers(struct sock *sk) +{ + struct chtls_sock *csk = sk->sk_user_data; + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb; + + skb_queue_walk(&csk->txq, skb) { + if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NEED_HDR) { + ULP_SKB_CB(skb)->seq = tp->write_seq; + tp->write_seq += skb->len; + } + } +} + +static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt) +{ + struct tcp_sock *tp = tcp_sk(sk); + + tp->pushed_seq = snd_isn; + tp->write_seq = snd_isn; + tp->snd_nxt = snd_isn; + tp->snd_una = snd_isn; + inet_sk(sk)->inet_id = tp->write_seq ^ jiffies; + assign_rxopt(sk, opt); + + if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10)) + tp->rcv_wup -= tp->rcv_wnd - (RCV_BUFSIZ_M << 10); + dst_confirm(sk->sk_dst_cache); + + smp_mb(); + tcp_set_state(sk, TCP_ESTABLISHED); +} + +static void chtls_active_establish(struct sock *sk, struct sk_buff *skb) +{ + struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct cpl_act_establish *req = cplhdr(skb) + RSS_HDR; + unsigned int rcv_isn = ntohl(req->rcv_isn); + struct tcp_sock *tp = tcp_sk(sk); + + if (unlikely(sk->sk_state != TCP_SYN_SENT)) + pr_info("TID %u expected SYN_SENT, found %d\n", + csk->tid, sk->sk_state); + tp->rcv_tstamp = tcp_jiffies32; + csk->delack_seq = rcv_isn; + tp->copied_seq = rcv_isn; + tp->rcv_wup = rcv_isn; + tp->rcv_nxt = rcv_isn; + make_established(sk, ntohl(req->snd_isn), ntohs(req->tcp_opt)); + + if (skb_queue_len(&csk->ooq)) + fixup_and_send_ofo(csk, csk->tid); + if (skb_queue_len(&csk->ooq)) + fixup_and_send_ofo(csk, csk->tid); + + if (likely(!sock_flag(sk, SOCK_DEAD))) { + sk->sk_state_change(sk); + sk_wake_async(sk, 0, POLL_OUT); + } + kfree_skb(skb); + chtls_fix_pending_tx_buffers(sk); + if (chtls_push_frames(csk, 1)) + sk->sk_write_space(sk); + chtls_handshake_work(sk); +} + +static int chtls_act_establish(struct chtls_dev *cdev, struct sk_buff *skb) +{ + struct cpl_act_establish *req = cplhdr(skb) + RSS_HDR; + struct chtls_sock *csk; + unsigned int hwtid; + unsigned int atid; + struct sock *sk; + + hwtid = GET_TID(req); + atid = TID_TID_G(ntohl(req->tos_atid)); + sk = lookup_tid(cdev->tids, hwtid); + if (sk) { + if (sk->sk_state == TCP_SYN_SENT && + csk_flag(sk, CSK_ABORT_RPL_PENDING)) + return 0; + return (CPL_RET_UNKNOWN_TID | CPL_RET_BUF_DONE); + } + + csk = lookup_atid(cdev->tids, atid); + if (unlikely(!csk)) { + __kfree_skb(skb); + return (CPL_RET_UNKNOWN_TID | CPL_RET_BUF_DONE); + } + sk = csk->sk; + csk->tid = hwtid; + cxgb4_insert_tid(cdev->tids, sk, hwtid, sk->sk_family); + csk->idr = bh_insert_handle(cdev, sk, hwtid); + cxgb4_free_atid(cdev->tids, atid); + conn_remove_handle(cdev, atid); + kref_put(&csk->kref, chtls_sock_release); + + process_cpl_msg(chtls_active_establish, sk, skb); + return 0; +} + +static int chtls_act_open_rpl(struct chtls_dev *cdev, struct sk_buff *skb) +{ + struct cpl_act_open_rpl *rpl = cplhdr(skb) + RSS_HDR; + struct chtls_sock *csk; + unsigned int status; + unsigned int atid; + struct sock *sk; + + atid = TID_TID_G(AOPEN_ATID_G(be32_to_cpu(rpl->atid_status))); + status = AOPEN_STATUS_G(be32_to_cpu(rpl->atid_status)); + csk = lookup_atid(cdev->tids, atid); + + if (unlikely(!csk) || is_neg_adv(status)) { + pr_err("NO matching conn. atid %u.\n", atid); + __kfree_skb(skb); + return (CPL_RET_UNKNOWN_TID | CPL_RET_BUF_DONE); + } + sk = csk->sk; + if (status && status != CPL_ERR_TCAM_FULL && + status != CPL_ERR_CONN_EXIST && + status != CPL_ERR_ARP_MISS) + cxgb4_remove_tid(cdev->tids, csk->port_id, GET_TID(rpl), + sk->sk_family); + + process_cpl_msg(chtls_active_open_rpl, sk, skb); + return 0; +} + static void chtls_write_space(struct sock *sk) { struct socket *sock = sk->sk_socket; @@ -1768,30 +1996,6 @@ static int chtls_pass_accept_req(struct chtls_dev *cdev, struct sk_buff *skb) return 0; } -/* - * Completes some final bits of initialization for just established connections - * and changes their state to TCP_ESTABLISHED. - * - * snd_isn here is the ISN after the SYN, i.e., the true ISN + 1. - */ -static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt) -{ - struct tcp_sock *tp = tcp_sk(sk); - - tp->pushed_seq = snd_isn; - tp->write_seq = snd_isn; - tp->snd_nxt = snd_isn; - tp->snd_una = snd_isn; - inet_sk(sk)->inet_id = tp->write_seq ^ jiffies; - assign_rxopt(sk, opt); - - if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10)) - tp->rcv_wup -= tp->rcv_wnd - (RCV_BUFSIZ_M << 10); - - smp_mb(); - tcp_set_state(sk, TCP_ESTABLISHED); -} - static void chtls_abort_conn(struct sock *sk, struct sk_buff *skb) { struct sk_buff *abort_skb; @@ -1909,6 +2113,7 @@ static int chtls_pass_establish(struct chtls_dev *cdev, struct sk_buff *skb) csk->wr_max_credits = 64; csk->wr_credits = 64; csk->wr_unacked = 0; + csk->delack_mode = 0; make_established(sk, ntohl(req->snd_isn), ntohs(req->tcp_opt)); stid = PASS_OPEN_TID_G(ntohl(req->tos_stid)); sk->sk_state_change(sk); @@ -2333,20 +2538,6 @@ static void send_abort_rpl(struct sock *sk, struct sk_buff *skb, cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); } -/* - * Add an skb to the deferred skb queue for processing from process context. - */ -static void t4_defer_reply(struct sk_buff *skb, struct chtls_dev *cdev, - defer_handler_t handler) -{ - DEFERRED_SKB_CB(skb)->handler = handler; - spin_lock_bh(&cdev->deferq.lock); - __skb_queue_tail(&cdev->deferq, skb); - if (skb_queue_len(&cdev->deferq) == 1) - schedule_work(&cdev->deferq_task); - spin_unlock_bh(&cdev->deferq.lock); -} - static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, struct chtls_dev *cdev, int status, int queue) @@ -2362,7 +2553,7 @@ static void chtls_send_abort_rpl(struct sock *sk, struct sk_buff *skb, reply_skb = get_cpl_skb(skb, sizeof(struct cpl_abort_rpl), gfp_any()); if (!reply_skb) { req->status = (queue << 1) | status; - t4_defer_reply(skb, cdev, send_defer_abort_rpl); + chtls_defer_reply(skb, cdev, send_defer_abort_rpl); return; } @@ -2391,7 +2582,7 @@ static void bl_abort_syn_rcv(struct sock *lsk, struct sk_buff *skb) int queue; child = skb->sk; - csk = sk->sk_user_data; + csk = lsk->sk_user_data; queue = csk->txq_idx; skb->sk = NULL; @@ -2603,6 +2794,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb) if (tp->snd_una != snd_una) { tp->snd_una = snd_una; + dst_confirm(sk->sk_dst_cache); tp->rcv_tstamp = tcp_time_stamp(tp); if (tp->snd_una == tp->snd_nxt && !csk_flag_nochk(csk, CSK_TX_FAILOVER)) @@ -2626,7 +2818,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb) static int chtls_wr_ack(struct chtls_dev *cdev, struct sk_buff *skb) { struct cpl_fw4_ack *rpl = cplhdr(skb) + RSS_HDR; - unsigned int hwtid = GET_TID(rpl); + unsigned int hwtid = CPL_FW4_ACK_FLOWID_G(ntohl(OPCODE_TID(rpl))); struct sock *sk; sk = lookup_tid(cdev->tids, hwtid); @@ -2640,6 +2832,8 @@ static int chtls_wr_ack(struct chtls_dev *cdev, struct sk_buff *skb) } chtls_handler_func chtls_handlers[NUM_CPL_CMDS] = { + [CPL_ACT_ESTABLISH] = chtls_act_establish, + [CPL_ACT_OPEN_RPL] = chtls_act_open_rpl, [CPL_PASS_OPEN_RPL] = chtls_pass_open_rpl, [CPL_CLOSE_LISTSRV_RPL] = chtls_close_listsrv_rpl, [CPL_PASS_ACCEPT_REQ] = chtls_pass_accept_req, diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.h b/drivers/crypto/chelsio/chtls/chtls_cm.h index ca3ccb7..cea0d22 100644 --- a/drivers/crypto/chelsio/chtls/chtls_cm.h +++ b/drivers/crypto/chelsio/chtls/chtls_cm.h @@ -45,6 +45,8 @@ */ #define MAX_RCV_WND ((1U << 27) - 1) #define MAX_MSS 65536 +#define TLS_SRV_HELLO_BKOFF_TM (msecs_to_jiffies(250)) +#define TLS_SRV_HELLO_RD_TM (msecs_to_jiffies(100)) /* * Min receive window. We want it to be large enough to accommodate receive @@ -200,4 +202,5 @@ static inline void enqueue_wr(struct chtls_sock *csk, struct sk_buff *skb) int chtls_active_open(struct chtls_dev *cdev, struct sock *sk, struct net_device *ndev); +void stop_hndsk_work(struct sock *sk); #endif diff --git a/drivers/crypto/chelsio/chtls/chtls_hw.c b/drivers/crypto/chelsio/chtls/chtls_hw.c index 6266b9e..70bc0cc 100644 --- a/drivers/crypto/chelsio/chtls/chtls_hw.c +++ b/drivers/crypto/chelsio/chtls/chtls_hw.c @@ -313,6 +313,7 @@ int chtls_setkey(struct chtls_sock *csk, u32 keylen, u32 optname) cdev = csk->cdev; sk = csk->sk; + stop_hndsk_work(sk); klen = roundup((keylen + AEAD_H_SIZE) + sizeof(*kctx), 32); wrlen = roundup(sizeof(*kwr), 16); diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c b/drivers/crypto/chelsio/chtls/chtls_io.c index 18f553f..e07b671 100644 --- a/drivers/crypto/chelsio/chtls/chtls_io.c +++ b/drivers/crypto/chelsio/chtls/chtls_io.c @@ -45,7 +45,7 @@ static int data_sgl_len(const struct sk_buff *skb) static int nos_ivs(struct sock *sk, unsigned int size) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; return DIV_ROUND_UP(size, csk->tlshws.mfs); } @@ -93,7 +93,7 @@ static struct sk_buff *create_flowc_wr_skb(struct sock *sk, struct fw_flowc_wr *flowc, int flowclen) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct sk_buff *skb; skb = alloc_skb(flowclen, GFP_ATOMIC); @@ -109,21 +109,26 @@ static struct sk_buff *create_flowc_wr_skb(struct sock *sk, static int send_flowc_wr(struct sock *sk, struct fw_flowc_wr *flowc, int flowclen) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; int flowclen16; + bool syn_sent; int ret; flowclen16 = flowclen / 16; + syn_sent = (sk->sk_state == TCP_SYN_SENT); if (csk_flag(sk, CSK_TX_DATA_SENT)) { skb = create_flowc_wr_skb(sk, flowc, flowclen); if (!skb) return -ENOMEM; - skb_entail(sk, skb, - ULPCB_FLAG_NO_HDR | ULPCB_FLAG_NO_APPEND); + if (syn_sent) + __skb_queue_tail(&csk->ooq, skb); + else + skb_entail(sk, skb, + ULPCB_FLAG_NO_HDR | ULPCB_FLAG_NO_APPEND); return 0; } @@ -230,7 +235,7 @@ static int tls_copy_ivs(struct sock *sk, struct sk_buff *skb) struct page *page; int err = 0; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; hws = &csk->tlshws; number_of_ivs = nos_ivs(sk, skb->len); @@ -286,7 +291,7 @@ static void tls_copy_tx_key(struct sock *sk, struct sk_buff *skb) u32 immdlen; int kaddr; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; hws = &csk->tlshws; cdev = csk->cdev; @@ -359,7 +364,7 @@ static void tls_tx_data_wr(struct sock *sk, struct sk_buff *skb, int iv_imm; int len; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; iv_imm = skb_ulp_tls_iv_imm(skb); dev = csk->egress_dev; adap = netdev2adap(dev); @@ -446,7 +451,7 @@ static int chtls_expansion_size(struct sock *sk, int data_len, int fullpdu, unsigned short *pducnt) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct chtls_hws *hws = &csk->tlshws; struct tls_scmd *scmd = &hws->scmd; int fragsize = hws->mfs; @@ -488,7 +493,7 @@ static void make_tlstx_data_wr(struct sock *sk, struct sk_buff *skb, int expn_sz; int pdus; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; hws = &csk->tlshws; pdus = DIV_ROUND_UP(tls_len, hws->mfs); expn_sz = chtls_expansion_size(sk, tls_len, 0, NULL); @@ -517,7 +522,7 @@ static void make_tx_data_wr(struct sock *sk, struct sk_buff *skb, struct chtls_sock *csk; unsigned int opcode; - csk = rcu_dereference_sk_user_data(sk); + csk = sk->sk_user_data; opcode = FW_OFLD_TX_DATA_WR; req = (struct fw_ofld_tx_data_wr *)__skb_push(skb, sizeof(*req)); @@ -730,7 +735,7 @@ static void mark_urg(struct tcp_sock *tp, int flags, */ static bool should_push(struct sock *sk) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct chtls_dev *cdev = csk->cdev; struct tcp_sock *tp = tcp_sk(sk); @@ -767,7 +772,7 @@ static bool send_should_push(struct sock *sk, int flags) void chtls_tcp_push(struct sock *sk, int flags) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; int qlen = skb_queue_len(&csk->txq); if (likely(qlen)) { @@ -821,7 +826,7 @@ static int select_size(struct sock *sk, int io_len, int flags, int len) void skb_entail(struct sock *sk, struct sk_buff *skb, int flags) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct tcp_sock *tp = tcp_sk(sk); ULP_SKB_CB(skb)->seq = tp->write_seq; @@ -851,7 +856,7 @@ static struct sk_buff *get_tx_skb(struct sock *sk, int size) static struct sk_buff *get_record_skb(struct sock *sk, int size, bool zcopy) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct sk_buff *skb; skb = alloc_skb(((zcopy ? 0 : size) + TX_TLSHDR_LEN + @@ -879,7 +884,7 @@ static void tx_skb_finalize(struct sk_buff *skb) static void push_frames_if_head(struct sock *sk) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; if (skb_queue_len(&csk->txq) == 1) chtls_push_frames(csk, 1); @@ -1310,7 +1315,7 @@ int chtls_sendpage(struct sock *sk, struct page *page, static void chtls_select_window(struct sock *sk) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct tcp_sock *tp = tcp_sk(sk); unsigned int wnd = tp->rcv_wnd; @@ -1370,7 +1375,7 @@ static u32 send_rx_credits(struct chtls_sock *csk, u32 credits) */ static void chtls_cleanup_rbuf(struct sock *sk, int copied) { - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct chtls_sock *csk = sk->sk_user_data; struct tcp_sock *tp; int must_send; u32 credits; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index c62a0c8..302aec1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -286,6 +286,14 @@ struct work_request_hdr { #define RSS_QUEUE_VALID_V(x) ((x) << RSS_QUEUE_VALID_S) #define RSS_QUEUE_VALID_F RSS_QUEUE_VALID_V(1U) +#define RSS_RX_COALESCE_S 12 +#define RSS_RX_COALESCE_V(x) ((x) << RX_COALESCE_S) +#define RSS_RX_COALESCE_F RSS_RX_COALESCE_V(1U) + +#define T5_ISS_S 18 +#define T5_ISS_V(x) ((x) << T5_ISS_S) +#define T5_ISS_F T5_ISS_V(1U) + #define RX_FC_DISABLE_S 20 #define RX_FC_DISABLE_V(x) ((x) << RX_FC_DISABLE_S) #define RX_FC_DISABLE_F RX_FC_DISABLE_V(1U) @@ -298,6 +306,10 @@ struct work_request_hdr { #define RX_CHANNEL_V(x) ((x) << RX_CHANNEL_S) #define RX_CHANNEL_F RX_CHANNEL_V(1U) +#define RX_MODULATE_RX_S 27 +#define RX_MODULATE_RX_V(x) ((x) << RX_MODULATE_RX_S) +#define RX_MODULATE_RX_F RX_MODULATE_RX_V(1U) + #define WND_SCALE_EN_S 28 #define WND_SCALE_EN_V(x) ((x) << WND_SCALE_EN_S) #define WND_SCALE_EN_F WND_SCALE_EN_V(1U) @@ -1407,6 +1419,12 @@ struct cpl_fw4_ack { __be64 rsvd1; }; +#define CPL_FW4_ACK_FLOWID_S 0 +#define CPL_FW4_ACK_FLOWID_M 0xffffff +#define CPL_FW4_ACK_FLOWID_V(x) ((x) << CPL_FW4_ACK_FLOWID_S) +#define CPL_FW4_ACK_FLOWID_G(x) \ + (((x) >> CPL_FW4_ACK_FLOWID_S) & CPL_FW4_ACK_FLOWID_M) + enum { CPL_FW4_ACK_FLAGS_SEQVAL = 0x1, /* seqn valid */ CPL_FW4_ACK_FLAGS_CH = 0x2, /* channel change complete */ -- 1.8.3.1