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