diff options
author | Ganesh Goudar <ganeshgr@chelsio.com> | 2018-05-21 02:56:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-21 12:16:23 -0400 |
commit | a6076fcd187a1cb4900cf970a04401957b4b4ab8 (patch) | |
tree | 486b1bc25751d0b127758b78d91648003b352202 | |
parent | 6c541b4595a28b204888db75aba1966ede4a6184 (diff) |
cxgb4: copy the length of cpl_tx_pkt_core to fw_wr
immdlen field of FW_ETH_TX_PKT_WR is filled in a wrong way,
we must copy the length of all the cpls encapsulated in fw
work request. In the xmit path we missed adding the length
of CPL_TX_PKT_CORE but we added the length of WR_HDR and it
worked because WR_HDR and CPL_TX_PKT_CORE are of same length.
Add the length of cpl_tx_pkt_core not WR_HDR's. This also
fixes the lso cpl errors for udp tunnels
Fixes: d0a1299c6bf7 ("cxgb4: add support for vxlan segmentation offload")
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/sge.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 0f87e973a158..276f22357f81 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
@@ -1411,8 +1411,9 @@ out_free: dev_kfree_skb_any(skb); | |||
1411 | end = (u64 *)wr + flits; | 1411 | end = (u64 *)wr + flits; |
1412 | 1412 | ||
1413 | len = immediate ? skb->len : 0; | 1413 | len = immediate ? skb->len : 0; |
1414 | len += sizeof(*cpl); | ||
1414 | if (ssi->gso_size) { | 1415 | if (ssi->gso_size) { |
1415 | struct cpl_tx_pkt_lso *lso = (void *)wr; | 1416 | struct cpl_tx_pkt_lso_core *lso = (void *)(wr + 1); |
1416 | bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0; | 1417 | bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0; |
1417 | int l3hdr_len = skb_network_header_len(skb); | 1418 | int l3hdr_len = skb_network_header_len(skb); |
1418 | int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN; | 1419 | int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN; |
@@ -1442,20 +1443,19 @@ out_free: dev_kfree_skb_any(skb); | |||
1442 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 1443 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
1443 | cntrl = hwcsum(adap->params.chip, skb); | 1444 | cntrl = hwcsum(adap->params.chip, skb); |
1444 | } else { | 1445 | } else { |
1445 | lso->c.lso_ctrl = htonl(LSO_OPCODE_V(CPL_TX_PKT_LSO) | | 1446 | lso->lso_ctrl = htonl(LSO_OPCODE_V(CPL_TX_PKT_LSO) | |
1446 | LSO_FIRST_SLICE_F | LSO_LAST_SLICE_F | | 1447 | LSO_FIRST_SLICE_F | LSO_LAST_SLICE_F | |
1447 | LSO_IPV6_V(v6) | | 1448 | LSO_IPV6_V(v6) | |
1448 | LSO_ETHHDR_LEN_V(eth_xtra_len / 4) | | 1449 | LSO_ETHHDR_LEN_V(eth_xtra_len / 4) | |
1449 | LSO_IPHDR_LEN_V(l3hdr_len / 4) | | 1450 | LSO_IPHDR_LEN_V(l3hdr_len / 4) | |
1450 | LSO_TCPHDR_LEN_V(tcp_hdr(skb)->doff)); | 1451 | LSO_TCPHDR_LEN_V(tcp_hdr(skb)->doff)); |
1451 | lso->c.ipid_ofst = htons(0); | 1452 | lso->ipid_ofst = htons(0); |
1452 | lso->c.mss = htons(ssi->gso_size); | 1453 | lso->mss = htons(ssi->gso_size); |
1453 | lso->c.seqno_offset = htonl(0); | 1454 | lso->seqno_offset = htonl(0); |
1454 | if (is_t4(adap->params.chip)) | 1455 | if (is_t4(adap->params.chip)) |
1455 | lso->c.len = htonl(skb->len); | 1456 | lso->len = htonl(skb->len); |
1456 | else | 1457 | else |
1457 | lso->c.len = | 1458 | lso->len = htonl(LSO_T5_XFER_SIZE_V(skb->len)); |
1458 | htonl(LSO_T5_XFER_SIZE_V(skb->len)); | ||
1459 | cpl = (void *)(lso + 1); | 1459 | cpl = (void *)(lso + 1); |
1460 | 1460 | ||
1461 | if (CHELSIO_CHIP_VERSION(adap->params.chip) | 1461 | if (CHELSIO_CHIP_VERSION(adap->params.chip) |
@@ -1484,7 +1484,6 @@ out_free: dev_kfree_skb_any(skb); | |||
1484 | q->tso++; | 1484 | q->tso++; |
1485 | q->tx_cso += ssi->gso_segs; | 1485 | q->tx_cso += ssi->gso_segs; |
1486 | } else { | 1486 | } else { |
1487 | len += sizeof(*cpl); | ||
1488 | if (ptp_enabled) | 1487 | if (ptp_enabled) |
1489 | op = FW_PTP_TX_PKT_WR; | 1488 | op = FW_PTP_TX_PKT_WR; |
1490 | else | 1489 | else |
@@ -1538,7 +1537,7 @@ out_free: dev_kfree_skb_any(skb); | |||
1538 | if (last_desc >= q->q.size) | 1537 | if (last_desc >= q->q.size) |
1539 | last_desc -= q->q.size; | 1538 | last_desc -= q->q.size; |
1540 | q->q.sdesc[last_desc].skb = skb; | 1539 | q->q.sdesc[last_desc].skb = skb; |
1541 | q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1); | 1540 | q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)sgl; |
1542 | } | 1541 | } |
1543 | 1542 | ||
1544 | txq_advance(&q->q, ndesc); | 1543 | txq_advance(&q->q, ndesc); |