14d6a6005SBhargava Marreddy /* SPDX-License-Identifier: GPL-2.0 */ 24d6a6005SBhargava Marreddy /* Copyright (c) 2025 Broadcom */ 34d6a6005SBhargava Marreddy 44d6a6005SBhargava Marreddy #ifndef _BNGE_TXRX_H_ 54d6a6005SBhargava Marreddy #define _BNGE_TXRX_H_ 64d6a6005SBhargava Marreddy 7*42d1c54dSVikas Gupta #include <linux/bnge/hsi.h> 84d6a6005SBhargava Marreddy #include "bnge_netdev.h" 94d6a6005SBhargava Marreddy 10bd5ad9c0SBhargava Marreddy static inline u32 bnge_tx_avail(struct bnge_net *bn, 11bd5ad9c0SBhargava Marreddy const struct bnge_tx_ring_info *txr) 12bd5ad9c0SBhargava Marreddy { 13bd5ad9c0SBhargava Marreddy u32 used = READ_ONCE(txr->tx_prod) - READ_ONCE(txr->tx_cons); 14bd5ad9c0SBhargava Marreddy 15bd5ad9c0SBhargava Marreddy return bn->tx_ring_size - (used & bn->tx_ring_mask); 16bd5ad9c0SBhargava Marreddy } 17bd5ad9c0SBhargava Marreddy 18bd5ad9c0SBhargava Marreddy static inline void bnge_writeq_relaxed(struct bnge_dev *bd, u64 val, 19bd5ad9c0SBhargava Marreddy void __iomem *addr) 20bd5ad9c0SBhargava Marreddy { 21bd5ad9c0SBhargava Marreddy #if BITS_PER_LONG == 32 22bd5ad9c0SBhargava Marreddy spin_lock(&bd->db_lock); 23bd5ad9c0SBhargava Marreddy lo_hi_writeq_relaxed(val, addr); 24bd5ad9c0SBhargava Marreddy spin_unlock(&bd->db_lock); 25bd5ad9c0SBhargava Marreddy #else 26bd5ad9c0SBhargava Marreddy writeq_relaxed(val, addr); 27bd5ad9c0SBhargava Marreddy #endif 28bd5ad9c0SBhargava Marreddy } 29bd5ad9c0SBhargava Marreddy 30bd5ad9c0SBhargava Marreddy /* For TX and RX ring doorbells with no ordering guarantee*/ 31bd5ad9c0SBhargava Marreddy static inline void bnge_db_write_relaxed(struct bnge_net *bn, 32bd5ad9c0SBhargava Marreddy struct bnge_db_info *db, u32 idx) 33bd5ad9c0SBhargava Marreddy { 34bd5ad9c0SBhargava Marreddy bnge_writeq_relaxed(bn->bd, db->db_key64 | DB_RING_IDX(db, idx), 35bd5ad9c0SBhargava Marreddy db->doorbell); 36bd5ad9c0SBhargava Marreddy } 37bd5ad9c0SBhargava Marreddy 384d6a6005SBhargava Marreddy #define TX_OPAQUE_IDX_MASK 0x0000ffff 394d6a6005SBhargava Marreddy #define TX_OPAQUE_BDS_MASK 0x00ff0000 404d6a6005SBhargava Marreddy #define TX_OPAQUE_BDS_SHIFT 16 414d6a6005SBhargava Marreddy #define TX_OPAQUE_RING_MASK 0xff000000 424d6a6005SBhargava Marreddy #define TX_OPAQUE_RING_SHIFT 24 434d6a6005SBhargava Marreddy 444d6a6005SBhargava Marreddy #define SET_TX_OPAQUE(bn, txr, idx, bds) \ 454d6a6005SBhargava Marreddy (((txr)->tx_napi_idx << TX_OPAQUE_RING_SHIFT) | \ 464d6a6005SBhargava Marreddy ((bds) << TX_OPAQUE_BDS_SHIFT) | ((idx) & (bn)->tx_ring_mask)) 474d6a6005SBhargava Marreddy 484d6a6005SBhargava Marreddy #define TX_OPAQUE_IDX(opq) ((opq) & TX_OPAQUE_IDX_MASK) 494d6a6005SBhargava Marreddy #define TX_OPAQUE_RING(opq) (((opq) & TX_OPAQUE_RING_MASK) >> \ 504d6a6005SBhargava Marreddy TX_OPAQUE_RING_SHIFT) 514d6a6005SBhargava Marreddy #define TX_OPAQUE_BDS(opq) (((opq) & TX_OPAQUE_BDS_MASK) >> \ 524d6a6005SBhargava Marreddy TX_OPAQUE_BDS_SHIFT) 534d6a6005SBhargava Marreddy #define TX_OPAQUE_PROD(bn, opq) ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\ 544d6a6005SBhargava Marreddy (bn)->tx_ring_mask) 55bd5ad9c0SBhargava Marreddy #define TX_BD_CNT(n) (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT) 56bd5ad9c0SBhargava Marreddy 57bd5ad9c0SBhargava Marreddy #define TX_MAX_BD_CNT 32 58bd5ad9c0SBhargava Marreddy 59bd5ad9c0SBhargava Marreddy #define TX_MAX_FRAGS (TX_MAX_BD_CNT - 2) 604d6a6005SBhargava Marreddy 614d6a6005SBhargava Marreddy /* Minimum TX BDs for a TX packet with MAX_SKB_FRAGS + 1. We need one extra 624d6a6005SBhargava Marreddy * BD because the first TX BD is always a long BD. 634d6a6005SBhargava Marreddy */ 644d6a6005SBhargava Marreddy #define BNGE_MIN_TX_DESC_CNT (MAX_SKB_FRAGS + 2) 654d6a6005SBhargava Marreddy 664d6a6005SBhargava Marreddy #define RX_RING(bn, x) (((x) & (bn)->rx_ring_mask) >> (BNGE_PAGE_SHIFT - 4)) 674d6a6005SBhargava Marreddy #define RX_AGG_RING(bn, x) (((x) & (bn)->rx_agg_ring_mask) >> \ 684d6a6005SBhargava Marreddy (BNGE_PAGE_SHIFT - 4)) 694d6a6005SBhargava Marreddy #define RX_IDX(x) ((x) & (RX_DESC_CNT - 1)) 704d6a6005SBhargava Marreddy 714d6a6005SBhargava Marreddy #define TX_RING(bn, x) (((x) & (bn)->tx_ring_mask) >> (BNGE_PAGE_SHIFT - 4)) 724d6a6005SBhargava Marreddy #define TX_IDX(x) ((x) & (TX_DESC_CNT - 1)) 734d6a6005SBhargava Marreddy 744d6a6005SBhargava Marreddy #define CP_RING(x) (((x) & ~(CP_DESC_CNT - 1)) >> (BNGE_PAGE_SHIFT - 4)) 754d6a6005SBhargava Marreddy #define CP_IDX(x) ((x) & (CP_DESC_CNT - 1)) 764d6a6005SBhargava Marreddy 774d6a6005SBhargava Marreddy #define TX_CMP_VALID(bn, txcmp, raw_cons) \ 784d6a6005SBhargava Marreddy (!!((txcmp)->tx_cmp_errors_v & cpu_to_le32(TX_CMP_V)) == \ 794d6a6005SBhargava Marreddy !((raw_cons) & (bn)->cp_bit)) 804d6a6005SBhargava Marreddy 814d6a6005SBhargava Marreddy #define RX_CMP_VALID(bn, rxcmp1, raw_cons) \ 824d6a6005SBhargava Marreddy (!!((rxcmp1)->rx_cmp_cfa_code_errors_v2 & cpu_to_le32(RX_CMP_V)) ==\ 834d6a6005SBhargava Marreddy !((raw_cons) & (bn)->cp_bit)) 844d6a6005SBhargava Marreddy 854d6a6005SBhargava Marreddy #define RX_AGG_CMP_VALID(bn, agg, raw_cons) \ 864d6a6005SBhargava Marreddy (!!((agg)->rx_agg_cmp_v & cpu_to_le32(RX_AGG_CMP_V)) == \ 874d6a6005SBhargava Marreddy !((raw_cons) & (bn)->cp_bit)) 884d6a6005SBhargava Marreddy 894d6a6005SBhargava Marreddy #define NQ_CMP_VALID(bn, nqcmp, raw_cons) \ 904d6a6005SBhargava Marreddy (!!((nqcmp)->v & cpu_to_le32(NQ_CN_V)) == !((raw_cons) & (bn)->cp_bit)) 914d6a6005SBhargava Marreddy 924d6a6005SBhargava Marreddy #define TX_CMP_TYPE(txcmp) \ 934d6a6005SBhargava Marreddy (le32_to_cpu((txcmp)->tx_cmp_flags_type) & CMP_TYPE) 944d6a6005SBhargava Marreddy 954d6a6005SBhargava Marreddy #define RX_CMP_TYPE(rxcmp) \ 964d6a6005SBhargava Marreddy (le32_to_cpu((rxcmp)->rx_cmp_len_flags_type) & RX_CMP_CMP_TYPE) 974d6a6005SBhargava Marreddy 984d6a6005SBhargava Marreddy #define RING_RX(bn, idx) ((idx) & (bn)->rx_ring_mask) 994d6a6005SBhargava Marreddy #define NEXT_RX(idx) ((idx) + 1) 1004d6a6005SBhargava Marreddy 1014d6a6005SBhargava Marreddy #define RING_RX_AGG(bn, idx) ((idx) & (bn)->rx_agg_ring_mask) 1024d6a6005SBhargava Marreddy #define NEXT_RX_AGG(idx) ((idx) + 1) 1034d6a6005SBhargava Marreddy 104bd5ad9c0SBhargava Marreddy #define SW_TX_RING(bn, idx) ((idx) & (bn)->tx_ring_mask) 1054d6a6005SBhargava Marreddy #define NEXT_TX(idx) ((idx) + 1) 1064d6a6005SBhargava Marreddy 1074d6a6005SBhargava Marreddy #define ADV_RAW_CMP(idx, n) ((idx) + (n)) 1084d6a6005SBhargava Marreddy #define NEXT_RAW_CMP(idx) ADV_RAW_CMP(idx, 1) 1094d6a6005SBhargava Marreddy #define RING_CMP(bn, idx) ((idx) & (bn)->cp_ring_mask) 110c858ac87SBhargava Marreddy #define NEXT_CMP(bn, idx) RING_CMP(bn, ADV_RAW_CMP(idx, 1)) 1114d6a6005SBhargava Marreddy 1124d6a6005SBhargava Marreddy #define RX_CMP_ITYPES(rxcmp) \ 1134d6a6005SBhargava Marreddy (le32_to_cpu((rxcmp)->rx_cmp_len_flags_type) & RX_CMP_FLAGS_ITYPES_MASK) 1144d6a6005SBhargava Marreddy 1154d6a6005SBhargava Marreddy #define RX_CMP_CFA_CODE(rxcmpl1) \ 1164d6a6005SBhargava Marreddy ((le32_to_cpu((rxcmpl1)->rx_cmp_cfa_code_errors_v2) & \ 1174d6a6005SBhargava Marreddy RX_CMPL_CFA_CODE_MASK) >> RX_CMPL_CFA_CODE_SFT) 1184d6a6005SBhargava Marreddy 1194d6a6005SBhargava Marreddy irqreturn_t bnge_msix(int irq, void *dev_instance); 120bd5ad9c0SBhargava Marreddy netdev_tx_t bnge_start_xmit(struct sk_buff *skb, struct net_device *dev); 1214d6a6005SBhargava Marreddy void bnge_reuse_rx_data(struct bnge_rx_ring_info *rxr, u16 cons, void *data); 1224d6a6005SBhargava Marreddy int bnge_napi_poll(struct napi_struct *napi, int budget); 1235deaeae1SBhargava Marreddy netdev_features_t bnge_features_check(struct sk_buff *skb, 1245deaeae1SBhargava Marreddy struct net_device *dev, 1255deaeae1SBhargava Marreddy netdev_features_t features); 1264d6a6005SBhargava Marreddy #endif /* _BNGE_TXRX_H_ */ 127