net/ice: calculate TCP header size for offload
[dpdk.git] / drivers / net / ice / ice_rxtx.c
index deb904d..bcb67ec 100644 (file)
@@ -481,7 +481,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
        tx_ctx.tso_qnum = txq->reg_idx; /* index for tso state structure */
        tx_ctx.legacy_int = 1; /* Legacy or Advanced Host Interface */
 
-       ice_set_ctx((uint8_t *)&tx_ctx, txq_elem.txqs[0].txq_ctx,
+       ice_set_ctx(hw, (uint8_t *)&tx_ctx, txq_elem.txqs[0].txq_ctx,
                    ice_tlan_ctx_info);
 
        txq->qtx_tail = hw->hw_addr + QTX_COMM_DBELL(txq->reg_idx);
@@ -653,7 +653,7 @@ ice_fdir_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
        tx_ctx.tso_qnum = txq->reg_idx; /* index for tso state structure */
        tx_ctx.legacy_int = 1; /* Legacy or Advanced Host Interface */
 
-       ice_set_ctx((uint8_t *)&tx_ctx, txq_elem.txqs[0].txq_ctx,
+       ice_set_ctx(hw, (uint8_t *)&tx_ctx, txq_elem.txqs[0].txq_ctx,
                    ice_tlan_ctx_info);
 
        txq->qtx_tail = hw->hw_addr + QTX_COMM_DBELL(txq->reg_idx);
@@ -1905,6 +1905,7 @@ ice_free_queues(struct rte_eth_dev *dev)
                        continue;
                ice_rx_queue_release(dev->data->rx_queues[i]);
                dev->data->rx_queues[i] = NULL;
+               rte_eth_dma_zone_free(dev, "rx_ring", i);
        }
        dev->data->nb_rx_queues = 0;
 
@@ -1913,6 +1914,7 @@ ice_free_queues(struct rte_eth_dev *dev)
                        continue;
                ice_tx_queue_release(dev->data->tx_queues[i]);
                dev->data->tx_queues[i] = NULL;
+               rte_eth_dma_zone_free(dev, "tx_ring", i);
        }
        dev->data->nb_tx_queues = 0;
 }
@@ -2232,7 +2234,7 @@ ice_txd_enable_checksum(uint64_t ol_flags,
        switch (ol_flags & PKT_TX_L4_MASK) {
        case PKT_TX_TCP_CKSUM:
                *td_cmd |= ICE_TX_DESC_CMD_L4T_EOFT_TCP;
-               *td_offset |= (sizeof(struct rte_tcp_hdr) >> 2) <<
+               *td_offset |= (tx_offload.l4_len >> 2) <<
                              ICE_TX_DESC_LEN_L4_LEN_S;
                break;
        case PKT_TX_SCTP_CKSUM:
@@ -2369,6 +2371,28 @@ ice_calc_pkt_desc(struct rte_mbuf *tx_pkt)
        return count;
 }
 
+/* Calculate TCP header length for PKT_TX_TCP_CKSUM if not provided */
+static inline uint16_t
+ice_calc_pkt_tcp_hdr(struct rte_mbuf *tx_pkt, union ice_tx_offload tx_offload)
+{
+       uint16_t tcpoff = tx_offload.l2_len + tx_offload.l3_len;
+       const struct rte_tcp_hdr *tcp_hdr;
+       struct rte_tcp_hdr _tcp_hdr;
+
+       if (tcpoff + sizeof(struct rte_tcp_hdr) < tx_pkt->data_len) {
+               tcp_hdr = rte_pktmbuf_mtod_offset(tx_pkt, struct rte_tcp_hdr *,
+                                                 tcpoff);
+
+               return (tcp_hdr->data_off & 0xf0) >> 2;
+       }
+
+       tcp_hdr = rte_pktmbuf_read(tx_pkt, tcpoff, sizeof(_tcp_hdr), &_tcp_hdr);
+       if (tcp_hdr)
+               return (tcp_hdr->data_off & 0xf0) >> 2;
+       else
+               return 0;
+}
+
 uint16_t
 ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
@@ -2466,6 +2490,11 @@ ice_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
                /* Enable checksum offloading */
                if (ol_flags & ICE_TX_CKSUM_OFFLOAD_MASK) {
+                       if ((ol_flags & PKT_TX_L4_MASK) == PKT_TX_TCP_CKSUM &&
+                           !tx_offload.l4_len)
+                               tx_offload.l4_len =
+                                    ice_calc_pkt_tcp_hdr(tx_pkt, tx_offload);
+
                        ice_txd_enable_checksum(ol_flags, &td_cmd,
                                                &td_offset, tx_offload);
                }
@@ -2874,7 +2903,7 @@ ice_xmit_pkts_simple(void *tx_queue,
        return nb_tx;
 }
 
-void __attribute__((cold))
+void __rte_cold
 ice_set_rx_function(struct rte_eth_dev *dev)
 {
        PMD_INIT_FUNC_TRACE();
@@ -2984,7 +3013,7 @@ ice_rx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
        return ret;
 }
 
-void __attribute__((cold))
+void __rte_cold
 ice_set_tx_function_flag(struct rte_eth_dev *dev, struct ice_tx_queue *txq)
 {
        struct ice_adapter *ad =
@@ -3053,7 +3082,7 @@ ice_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
        return i;
 }
 
-void __attribute__((cold))
+void __rte_cold
 ice_set_tx_function(struct rte_eth_dev *dev)
 {
        struct ice_adapter *ad =
@@ -3682,7 +3711,7 @@ ice_get_default_pkt_type(uint16_t ptype)
        return type_table[ptype];
 }
 
-void __attribute__((cold))
+void __rte_cold
 ice_set_default_ptype_table(struct rte_eth_dev *dev)
 {
        struct ice_adapter *ad =