+ if (tx_queue_id < eth_dev->data->nb_tx_queues) {
+ txq = eth_dev->data->tx_queues[tx_queue_id];
+ /* Drain txq */
+ if (qede_drain_txq(qdev, txq, true))
+ return -1; /* For the lack of retcodes */
+ /* Stop txq */
+ hwfn_index = tx_queue_id % edev->num_hwfns;
+ p_hwfn = &edev->hwfns[hwfn_index];
+ rc = ecore_eth_tx_queue_stop(p_hwfn, txq->handle);
+ if (rc != ECORE_SUCCESS) {
+ DP_ERR(edev, "TX queue %u stop fails\n", tx_queue_id);
+ return -1;
+ }
+ qede_tx_queue_release_mbufs(txq);
+ qede_tx_queue_reset(qdev, txq);
+ eth_dev->data->tx_queue_state[tx_queue_id] =
+ RTE_ETH_QUEUE_STATE_STOPPED;
+ DP_INFO(edev, "TX queue %u stopped\n", tx_queue_id);
+ } else {
+ DP_ERR(edev, "TX queue %u is not in range\n", tx_queue_id);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+int qede_start_queues(struct rte_eth_dev *eth_dev)
+{
+ struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+ uint8_t id;
+ int rc = -1;
+
+ for_each_rss(id) {
+ rc = qede_rx_queue_start(eth_dev, id);
+ if (rc != ECORE_SUCCESS)
+ return -1;
+ }
+
+ for_each_tss(id) {
+ rc = qede_tx_queue_start(eth_dev, id);
+ if (rc != ECORE_SUCCESS)
+ return -1;
+ }
+
+ return rc;
+}
+
+void qede_stop_queues(struct rte_eth_dev *eth_dev)
+{
+ struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+ uint8_t id;
+
+ /* Stopping RX/TX queues */
+ for_each_tss(id) {
+ qede_tx_queue_stop(eth_dev, id);
+ }
+
+ for_each_rss(id) {
+ qede_rx_queue_stop(eth_dev, id);
+ }
+}
+
+static inline bool qede_tunn_exist(uint16_t flag)
+{
+ return !!((PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
+ PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT) & flag);
+}
+
+static inline uint8_t qede_check_tunn_csum_l3(uint16_t flag)
+{
+ return !!((PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_MASK <<
+ PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_SHIFT) & flag);
+}
+
+/*
+ * qede_check_tunn_csum_l4:
+ * Returns:
+ * 1 : If L4 csum is enabled AND if the validation has failed.
+ * 0 : Otherwise
+ */
+static inline uint8_t qede_check_tunn_csum_l4(uint16_t flag)
+{
+ if ((PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_MASK <<
+ PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_SHIFT) & flag)
+ return !!((PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_MASK <<
+ PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT) & flag);
+
+ return 0;
+}
+
+static inline uint8_t qede_check_notunn_csum_l4(uint16_t flag)
+{
+ if ((PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK <<
+ PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT) & flag)
+ return !!((PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
+ PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT) & flag);
+
+ return 0;
+}
+
+/* Returns outer L2, L3 and L4 packet_type for tunneled packets */
+static inline uint32_t qede_rx_cqe_to_pkt_type_outer(struct rte_mbuf *m)
+{
+ uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+ struct rte_ether_hdr *eth_hdr;
+ struct ipv4_hdr *ipv4_hdr;
+ struct ipv6_hdr *ipv6_hdr;
+ struct rte_vlan_hdr *vlan_hdr;
+ uint16_t ethertype;
+ bool vlan_tagged = 0;
+ uint16_t len;
+
+ eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
+ len = sizeof(struct rte_ether_hdr);
+ ethertype = rte_cpu_to_be_16(eth_hdr->ether_type);
+
+ /* Note: Valid only if VLAN stripping is disabled */
+ if (ethertype == RTE_ETHER_TYPE_VLAN) {
+ vlan_tagged = 1;
+ vlan_hdr = (struct rte_vlan_hdr *)(eth_hdr + 1);
+ len += sizeof(struct rte_vlan_hdr);
+ ethertype = rte_cpu_to_be_16(vlan_hdr->eth_proto);
+ }
+
+ if (ethertype == RTE_ETHER_TYPE_IPv4) {
+ packet_type |= RTE_PTYPE_L3_IPV4;
+ ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, len);
+ if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
+ packet_type |= RTE_PTYPE_L4_TCP;
+ else if (ipv4_hdr->next_proto_id == IPPROTO_UDP)
+ packet_type |= RTE_PTYPE_L4_UDP;
+ } else if (ethertype == RTE_ETHER_TYPE_IPv6) {
+ packet_type |= RTE_PTYPE_L3_IPV6;
+ ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, len);
+ if (ipv6_hdr->proto == IPPROTO_TCP)
+ packet_type |= RTE_PTYPE_L4_TCP;
+ else if (ipv6_hdr->proto == IPPROTO_UDP)
+ packet_type |= RTE_PTYPE_L4_UDP;
+ }
+
+ if (vlan_tagged)
+ packet_type |= RTE_PTYPE_L2_ETHER_VLAN;
+ else
+ packet_type |= RTE_PTYPE_L2_ETHER;
+
+ return packet_type;
+}
+
+static inline uint32_t qede_rx_cqe_to_pkt_type_inner(uint16_t flags)
+{
+ uint16_t val;
+
+ /* Lookup table */
+ static const uint32_t
+ ptype_lkup_tbl[QEDE_PKT_TYPE_MAX] __rte_cache_aligned = {
+ [QEDE_PKT_TYPE_IPV4] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV4_TCP] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_TCP |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_TCP] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_TCP |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV4_UDP] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_UDP |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_UDP] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_UDP |
+ RTE_PTYPE_INNER_L2_ETHER,
+ /* Frags with no VLAN */
+ [QEDE_PKT_TYPE_IPV4_FRAG] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_FRAG |
+ RTE_PTYPE_INNER_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_FRAG] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_FRAG |
+ RTE_PTYPE_INNER_L2_ETHER,
+ /* VLANs */
+ [QEDE_PKT_TYPE_IPV4_VLAN] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_VLAN] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV4_TCP_VLAN] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_TCP |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_TCP_VLAN] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_TCP |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV4_UDP_VLAN] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_UDP |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_UDP_VLAN] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_UDP |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ /* Frags with VLAN */
+ [QEDE_PKT_TYPE_IPV4_VLAN_FRAG] = RTE_PTYPE_INNER_L3_IPV4 |
+ RTE_PTYPE_INNER_L4_FRAG |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_VLAN_FRAG] = RTE_PTYPE_INNER_L3_IPV6 |
+ RTE_PTYPE_INNER_L4_FRAG |
+ RTE_PTYPE_INNER_L2_ETHER_VLAN,
+ };
+
+ /* Bits (0..3) provides L3/L4 protocol type */
+ /* Bits (4,5) provides frag and VLAN info */
+ val = ((PARSING_AND_ERR_FLAGS_L3TYPE_MASK <<
+ PARSING_AND_ERR_FLAGS_L3TYPE_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_L4PROTOCOL_MASK <<
+ PARSING_AND_ERR_FLAGS_L4PROTOCOL_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_IPV4FRAG_MASK <<
+ PARSING_AND_ERR_FLAGS_IPV4FRAG_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_TAG8021QEXIST_MASK <<
+ PARSING_AND_ERR_FLAGS_TAG8021QEXIST_SHIFT)) & flags;
+
+ if (val < QEDE_PKT_TYPE_MAX)
+ return ptype_lkup_tbl[val];
+
+ return RTE_PTYPE_UNKNOWN;
+}
+
+static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags)
+{
+ uint16_t val;
+
+ /* Lookup table */
+ static const uint32_t
+ ptype_lkup_tbl[QEDE_PKT_TYPE_MAX] __rte_cache_aligned = {
+ [QEDE_PKT_TYPE_IPV4] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV4_TCP] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_TCP |
+ RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_TCP] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_TCP |
+ RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV4_UDP] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_UDP |
+ RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_UDP] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_UDP |
+ RTE_PTYPE_L2_ETHER,
+ /* Frags with no VLAN */
+ [QEDE_PKT_TYPE_IPV4_FRAG] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_FRAG |
+ RTE_PTYPE_L2_ETHER,
+ [QEDE_PKT_TYPE_IPV6_FRAG] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_FRAG |
+ RTE_PTYPE_L2_ETHER,
+ /* VLANs */
+ [QEDE_PKT_TYPE_IPV4_VLAN] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_VLAN] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV4_TCP_VLAN] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_TCP |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_TCP_VLAN] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_TCP |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV4_UDP_VLAN] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_UDP |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_UDP_VLAN] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_UDP |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ /* Frags with VLAN */
+ [QEDE_PKT_TYPE_IPV4_VLAN_FRAG] = RTE_PTYPE_L3_IPV4 |
+ RTE_PTYPE_L4_FRAG |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ [QEDE_PKT_TYPE_IPV6_VLAN_FRAG] = RTE_PTYPE_L3_IPV6 |
+ RTE_PTYPE_L4_FRAG |
+ RTE_PTYPE_L2_ETHER_VLAN,
+ };
+
+ /* Bits (0..3) provides L3/L4 protocol type */
+ /* Bits (4,5) provides frag and VLAN info */
+ val = ((PARSING_AND_ERR_FLAGS_L3TYPE_MASK <<
+ PARSING_AND_ERR_FLAGS_L3TYPE_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_L4PROTOCOL_MASK <<
+ PARSING_AND_ERR_FLAGS_L4PROTOCOL_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_IPV4FRAG_MASK <<
+ PARSING_AND_ERR_FLAGS_IPV4FRAG_SHIFT) |
+ (PARSING_AND_ERR_FLAGS_TAG8021QEXIST_MASK <<
+ PARSING_AND_ERR_FLAGS_TAG8021QEXIST_SHIFT)) & flags;
+
+ if (val < QEDE_PKT_TYPE_MAX)
+ return ptype_lkup_tbl[val];
+
+ return RTE_PTYPE_UNKNOWN;
+}
+
+static inline uint8_t
+qede_check_notunn_csum_l3(struct rte_mbuf *m, uint16_t flag)
+{
+ struct ipv4_hdr *ip;
+ uint16_t pkt_csum;
+ uint16_t calc_csum;
+ uint16_t val;
+
+ val = ((PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
+ PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT) & flag);
+
+ if (unlikely(val)) {