On Fri, 23 Oct 2020 11:01:29 +0530 Rohit Maheshwari wrote: > There is a possibility of linear skbs coming in. Correcting > the length extraction logic. > > Fixes: 5a4b9fe7fece ("cxgb4/chcr: complete record tx handling") > Signed-off-by: Rohit Maheshwari <roh...@chelsio.com>
> @@ -980,6 +979,10 @@ chcr_ktls_write_tcp_options(struct chcr_ktls_info > *tx_info, struct sk_buff *skb, > return NETDEV_TX_BUSY; > } > > + if (unlikely(credits < ETHTXQ_STOP_THRES)) { > + chcr_eth_txq_stop(q); > + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; > + } > pos = &q->q.desc[q->q.pidx]; > wr = pos; > > @@ -987,42 +990,51 @@ chcr_ktls_write_tcp_options(struct chcr_ktls_info > *tx_info, struct sk_buff *skb, > wr->op_immdlen = htonl(FW_WR_OP_V(FW_ETH_TX_PKT_WR) | > FW_WR_IMMDLEN_V(ctrl)); > > - wr->equiq_to_len16 = htonl(FW_WR_LEN16_V(len16)); > + wr->equiq_to_len16 = htonl(wr_mid | FW_WR_LEN16_V(len16)); > wr->r3 = 0; > > cpl = (void *)(wr + 1); > > /* CPL header */ > - cpl->ctrl0 = htonl(TXPKT_OPCODE_V(CPL_TX_PKT) | TXPKT_INTF_V(tx_chan) | > + cpl->ctrl0 = htonl(TXPKT_OPCODE_V(CPL_TX_PKT) | > + TXPKT_INTF_V(tx_info->tx_chan) | > TXPKT_PF_V(tx_info->adap->pf)); > cpl->pack = 0; > cpl->len = htons(pktlen); > - /* checksum offload */ > - cpl->ctrl1 = 0; > - > - pos = cpl + 1; > > memcpy(buf, skb->data, pktlen); > if (tx_info->ip_family == AF_INET) { > /* we need to correct ip header len */ > ip = (struct iphdr *)(buf + maclen); > ip->tot_len = htons(pktlen - maclen); > + cntrl1 = TXPKT_CSUM_TYPE_V(TX_CSUM_TCPIP); > #if IS_ENABLED(CONFIG_IPV6) > } else { > ip6 = (struct ipv6hdr *)(buf + maclen); > ip6->payload_len = htons(pktlen - maclen - iplen); > + cntrl1 = TXPKT_CSUM_TYPE_V(TX_CSUM_TCPIP6); > #endif > } > + > + cntrl1 |= T6_TXPKT_ETHHDR_LEN_V(maclen - ETH_HLEN) | > + TXPKT_IPHDR_LEN_V(iplen); > + /* checksum offload */ > + cpl->ctrl1 = cpu_to_be64(cntrl1); > + > + pos = cpl + 1; > + > /* now take care of the tcp header, if fin is not set then clear push > * bit as well, and if fin is set, it will be sent at the last so we > * need to update the tcp sequence number as per the last packet. > */ > tcp = (struct tcphdr *)(buf + maclen + iplen); > > - if (!tcp->fin) > + if (!fin) { > tcp->psh = 0; > - else > + tcp->fin = 0; > + } else { > tcp->seq = htonl(tx_info->prev_seq); > + } > > chcr_copy_to_txd(buf, &q->q, pos, pktlen); > > @@ -1905,8 +1920,7 @@ static int chcr_ktls_xmit(struct sk_buff *skb, struct > net_device *dev) > cxgb4_reclaim_completed_tx(adap, &q->q, true); > /* if tcp options are set but finish is not send the options first */ > if (!th->fin && chcr_ktls_check_tcp_options(th)) { > - ret = chcr_ktls_write_tcp_options(tx_info, skb, q, > - tx_info->tx_chan); > + ret = chcr_ktls_write_tcp_options(tx_info, skb, q, false); > if (ret) > return NETDEV_TX_BUSY; > } > /* tcp finish is set, send a separate tcp msg including all the options > * as well. > */ > if (th->fin) > - chcr_ktls_write_tcp_options(tx_info, skb, q, tx_info->tx_chan); > + chcr_ktls_write_tcp_options(tx_info, skb, q, true); > > out: > dev_kfree_skb_any(skb); I don't see how these changes related to a linear skb.