10891d6d4SKrzysztof Kazimierczak /* SPDX-License-Identifier: GPL-2.0 */
20891d6d4SKrzysztof Kazimierczak /* Copyright (c) 2019, Intel Corporation. */
30891d6d4SKrzysztof Kazimierczak 
40891d6d4SKrzysztof Kazimierczak #ifndef _ICE_TXRX_LIB_H_
50891d6d4SKrzysztof Kazimierczak #define _ICE_TXRX_LIB_H_
60891d6d4SKrzysztof Kazimierczak #include "ice.h"
70891d6d4SKrzysztof Kazimierczak 
80891d6d4SKrzysztof Kazimierczak /**
90891d6d4SKrzysztof Kazimierczak  * ice_test_staterr - tests bits in Rx descriptor status and error fields
100d54d8f7SBrett Creeley  * @status_err_n: Rx descriptor status_error0 or status_error1 bits
110891d6d4SKrzysztof Kazimierczak  * @stat_err_bits: value to mask
120891d6d4SKrzysztof Kazimierczak  *
130891d6d4SKrzysztof Kazimierczak  * This function does some fast chicanery in order to return the
140891d6d4SKrzysztof Kazimierczak  * value of the mask which is really only used for boolean tests.
150891d6d4SKrzysztof Kazimierczak  * The status_error_len doesn't need to be shifted because it begins
160891d6d4SKrzysztof Kazimierczak  * at offset zero.
170891d6d4SKrzysztof Kazimierczak  */
180891d6d4SKrzysztof Kazimierczak static inline bool
190d54d8f7SBrett Creeley ice_test_staterr(__le16 status_err_n, const u16 stat_err_bits)
200891d6d4SKrzysztof Kazimierczak {
210d54d8f7SBrett Creeley 	return !!(status_err_n & cpu_to_le16(stat_err_bits));
220891d6d4SKrzysztof Kazimierczak }
230891d6d4SKrzysztof Kazimierczak 
24*e44f4790SMaciej Fijalkowski /**
25*e44f4790SMaciej Fijalkowski  * ice_is_non_eop - process handling of non-EOP buffers
26*e44f4790SMaciej Fijalkowski  * @rx_ring: Rx ring being processed
27*e44f4790SMaciej Fijalkowski  * @rx_desc: Rx descriptor for current buffer
28*e44f4790SMaciej Fijalkowski  *
29*e44f4790SMaciej Fijalkowski  * If the buffer is an EOP buffer, this function exits returning false,
30*e44f4790SMaciej Fijalkowski  * otherwise return true indicating that this is in fact a non-EOP buffer.
31*e44f4790SMaciej Fijalkowski  */
32*e44f4790SMaciej Fijalkowski static inline bool
33*e44f4790SMaciej Fijalkowski ice_is_non_eop(const struct ice_rx_ring *rx_ring,
34*e44f4790SMaciej Fijalkowski 	       const union ice_32b_rx_flex_desc *rx_desc)
35*e44f4790SMaciej Fijalkowski {
36*e44f4790SMaciej Fijalkowski 	/* if we are the last buffer then there is nothing else to do */
37*e44f4790SMaciej Fijalkowski #define ICE_RXD_EOF BIT(ICE_RX_FLEX_DESC_STATUS0_EOF_S)
38*e44f4790SMaciej Fijalkowski 	if (likely(ice_test_staterr(rx_desc->wb.status_error0, ICE_RXD_EOF)))
39*e44f4790SMaciej Fijalkowski 		return false;
40*e44f4790SMaciej Fijalkowski 
41*e44f4790SMaciej Fijalkowski 	rx_ring->ring_stats->rx_stats.non_eop_descs++;
42*e44f4790SMaciej Fijalkowski 
43*e44f4790SMaciej Fijalkowski 	return true;
44*e44f4790SMaciej Fijalkowski }
45*e44f4790SMaciej Fijalkowski 
460891d6d4SKrzysztof Kazimierczak static inline __le64
475757cc7cSTony Nguyen ice_build_ctob(u64 td_cmd, u64 td_offset, unsigned int size, u64 td_tag)
480891d6d4SKrzysztof Kazimierczak {
490891d6d4SKrzysztof Kazimierczak 	return cpu_to_le64(ICE_TX_DESC_DTYPE_DATA |
500891d6d4SKrzysztof Kazimierczak 			   (td_cmd    << ICE_TXD_QW1_CMD_S) |
510891d6d4SKrzysztof Kazimierczak 			   (td_offset << ICE_TXD_QW1_OFFSET_S) |
520891d6d4SKrzysztof Kazimierczak 			   ((u64)size << ICE_TXD_QW1_TX_BUF_SZ_S) |
530891d6d4SKrzysztof Kazimierczak 			   (td_tag    << ICE_TXD_QW1_L2TAG1_S));
540891d6d4SKrzysztof Kazimierczak }
550891d6d4SKrzysztof Kazimierczak 
560891d6d4SKrzysztof Kazimierczak /**
570d54d8f7SBrett Creeley  * ice_get_vlan_tag_from_rx_desc - get VLAN from Rx flex descriptor
580d54d8f7SBrett Creeley  * @rx_desc: Rx 32b flex descriptor with RXDID=2
590d54d8f7SBrett Creeley  *
600d54d8f7SBrett Creeley  * The OS and current PF implementation only support stripping a single VLAN tag
610d54d8f7SBrett Creeley  * at a time, so there should only ever be 0 or 1 tags in the l2tag* fields. If
620d54d8f7SBrett Creeley  * one is found return the tag, else return 0 to mean no VLAN tag was found.
630d54d8f7SBrett Creeley  */
640d54d8f7SBrett Creeley static inline u16
650d54d8f7SBrett Creeley ice_get_vlan_tag_from_rx_desc(union ice_32b_rx_flex_desc *rx_desc)
660d54d8f7SBrett Creeley {
670d54d8f7SBrett Creeley 	u16 stat_err_bits;
680d54d8f7SBrett Creeley 
690d54d8f7SBrett Creeley 	stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_L2TAG1P_S);
700d54d8f7SBrett Creeley 	if (ice_test_staterr(rx_desc->wb.status_error0, stat_err_bits))
710d54d8f7SBrett Creeley 		return le16_to_cpu(rx_desc->wb.l2tag1);
720d54d8f7SBrett Creeley 
730d54d8f7SBrett Creeley 	stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS1_L2TAG2P_S);
740d54d8f7SBrett Creeley 	if (ice_test_staterr(rx_desc->wb.status_error1, stat_err_bits))
750d54d8f7SBrett Creeley 		return le16_to_cpu(rx_desc->wb.l2tag2_2nd);
760d54d8f7SBrett Creeley 
770d54d8f7SBrett Creeley 	return 0;
780d54d8f7SBrett Creeley }
790d54d8f7SBrett Creeley 
800d54d8f7SBrett Creeley /**
810891d6d4SKrzysztof Kazimierczak  * ice_xdp_ring_update_tail - Updates the XDP Tx ring tail register
820891d6d4SKrzysztof Kazimierczak  * @xdp_ring: XDP Tx ring
830891d6d4SKrzysztof Kazimierczak  *
840891d6d4SKrzysztof Kazimierczak  * This function updates the XDP Tx ring tail register.
850891d6d4SKrzysztof Kazimierczak  */
86e72bba21SMaciej Fijalkowski static inline void ice_xdp_ring_update_tail(struct ice_tx_ring *xdp_ring)
870891d6d4SKrzysztof Kazimierczak {
880891d6d4SKrzysztof Kazimierczak 	/* Force memory writes to complete before letting h/w
890891d6d4SKrzysztof Kazimierczak 	 * know there are new descriptors to fetch.
900891d6d4SKrzysztof Kazimierczak 	 */
910891d6d4SKrzysztof Kazimierczak 	wmb();
920891d6d4SKrzysztof Kazimierczak 	writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail);
930891d6d4SKrzysztof Kazimierczak }
940891d6d4SKrzysztof Kazimierczak 
95eb087cd8SMaciej Fijalkowski void ice_finalize_xdp_rx(struct ice_tx_ring *xdp_ring, unsigned int xdp_res);
96e72bba21SMaciej Fijalkowski int ice_xmit_xdp_buff(struct xdp_buff *xdp, struct ice_tx_ring *xdp_ring);
97e72bba21SMaciej Fijalkowski int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring);
98e72bba21SMaciej Fijalkowski void ice_release_rx_desc(struct ice_rx_ring *rx_ring, u16 val);
990891d6d4SKrzysztof Kazimierczak void
100e72bba21SMaciej Fijalkowski ice_process_skb_fields(struct ice_rx_ring *rx_ring,
1010891d6d4SKrzysztof Kazimierczak 		       union ice_32b_rx_flex_desc *rx_desc,
102dda90cb9SJesse Brandeburg 		       struct sk_buff *skb, u16 ptype);
1030891d6d4SKrzysztof Kazimierczak void
104e72bba21SMaciej Fijalkowski ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag);
1050891d6d4SKrzysztof Kazimierczak #endif /* !_ICE_TXRX_LIB_H_ */
106