1d4fd0404SClaudiu Manoil /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2d4fd0404SClaudiu Manoil /* Copyright 2017-2019 NXP */ 3d4fd0404SClaudiu Manoil 4d4fd0404SClaudiu Manoil #include <linux/timer.h> 5d4fd0404SClaudiu Manoil #include <linux/pci.h> 6d4fd0404SClaudiu Manoil #include <linux/netdevice.h> 7d4fd0404SClaudiu Manoil #include <linux/etherdevice.h> 8d4fd0404SClaudiu Manoil #include <linux/dma-mapping.h> 9d4fd0404SClaudiu Manoil #include <linux/skbuff.h> 10d4fd0404SClaudiu Manoil #include <linux/ethtool.h> 11d4fd0404SClaudiu Manoil #include <linux/if_vlan.h> 1271b77a7aSClaudiu Manoil #include <linux/phylink.h> 13ae0e6a5dSClaudiu Manoil #include <linux/dim.h> 14d4fd0404SClaudiu Manoil 15d4fd0404SClaudiu Manoil #include "enetc_hw.h" 16d4fd0404SClaudiu Manoil 17d4fd0404SClaudiu Manoil #define ENETC_MAC_MAXFRM_SIZE 9600 18d4fd0404SClaudiu Manoil #define ENETC_MAX_MTU (ENETC_MAC_MAXFRM_SIZE - \ 19d4fd0404SClaudiu Manoil (ETH_FCS_LEN + ETH_HLEN + VLAN_HLEN)) 20d4fd0404SClaudiu Manoil 21d4fd0404SClaudiu Manoil struct enetc_tx_swbd { 229d2b68ccSVladimir Oltean union { 23d4fd0404SClaudiu Manoil struct sk_buff *skb; 249d2b68ccSVladimir Oltean struct xdp_frame *xdp_frame; 259d2b68ccSVladimir Oltean }; 26d4fd0404SClaudiu Manoil dma_addr_t dma; 277ed2bc80SVladimir Oltean struct page *page; /* valid only if is_xdp_tx */ 287ed2bc80SVladimir Oltean u16 page_offset; /* valid only if is_xdp_tx */ 29d4fd0404SClaudiu Manoil u16 len; 307ed2bc80SVladimir Oltean enum dma_data_direction dir; 31d3982312SY.b. Lu u8 is_dma_page:1; 32d3982312SY.b. Lu u8 check_wb:1; 337294380cSYangbo Lu u8 do_twostep_tstamp:1; 34d504498dSVladimir Oltean u8 is_eof:1; 357ed2bc80SVladimir Oltean u8 is_xdp_tx:1; 369d2b68ccSVladimir Oltean u8 is_xdp_redirect:1; 37d4fd0404SClaudiu Manoil }; 38d4fd0404SClaudiu Manoil 39d4fd0404SClaudiu Manoil #define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE 40d4fd0404SClaudiu Manoil #define ENETC_RXB_TRUESIZE 2048 /* PAGE_SIZE >> 1 */ 41d4fd0404SClaudiu Manoil #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */ 42d4fd0404SClaudiu Manoil #define ENETC_RXB_DMA_SIZE \ 43d4fd0404SClaudiu Manoil (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD) 44d1b15102SVladimir Oltean #define ENETC_RXB_DMA_SIZE_XDP \ 45d1b15102SVladimir Oltean (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - XDP_PACKET_HEADROOM) 46d4fd0404SClaudiu Manoil 47d4fd0404SClaudiu Manoil struct enetc_rx_swbd { 48d4fd0404SClaudiu Manoil dma_addr_t dma; 49d4fd0404SClaudiu Manoil struct page *page; 50d4fd0404SClaudiu Manoil u16 page_offset; 517ed2bc80SVladimir Oltean enum dma_data_direction dir; 527ed2bc80SVladimir Oltean u16 len; 53d4fd0404SClaudiu Manoil }; 54d4fd0404SClaudiu Manoil 557ed2bc80SVladimir Oltean /* ENETC overhead: optional extension BD + 1 BD gap */ 567ed2bc80SVladimir Oltean #define ENETC_TXBDS_NEEDED(val) ((val) + 2) 577ed2bc80SVladimir Oltean /* max # of chained Tx BDs is 15, including head and extension BD */ 587ed2bc80SVladimir Oltean #define ENETC_MAX_SKB_FRAGS 13 597ed2bc80SVladimir Oltean #define ENETC_TXBDS_MAX_NEEDED ENETC_TXBDS_NEEDED(ENETC_MAX_SKB_FRAGS + 1) 607ed2bc80SVladimir Oltean 61d4fd0404SClaudiu Manoil struct enetc_ring_stats { 62d4fd0404SClaudiu Manoil unsigned int packets; 63d4fd0404SClaudiu Manoil unsigned int bytes; 64d4fd0404SClaudiu Manoil unsigned int rx_alloc_errs; 65d1b15102SVladimir Oltean unsigned int xdp_drops; 667ed2bc80SVladimir Oltean unsigned int xdp_tx; 677ed2bc80SVladimir Oltean unsigned int xdp_tx_drops; 689d2b68ccSVladimir Oltean unsigned int xdp_redirect; 699d2b68ccSVladimir Oltean unsigned int xdp_redirect_failures; 709d2b68ccSVladimir Oltean unsigned int xdp_redirect_sg; 717ed2bc80SVladimir Oltean unsigned int recycles; 727ed2bc80SVladimir Oltean unsigned int recycle_failures; 73d1b15102SVladimir Oltean }; 74d1b15102SVladimir Oltean 75d1b15102SVladimir Oltean struct enetc_xdp_data { 76d1b15102SVladimir Oltean struct xdp_rxq_info rxq; 77d1b15102SVladimir Oltean struct bpf_prog *prog; 787ed2bc80SVladimir Oltean int xdp_tx_in_flight; 79d4fd0404SClaudiu Manoil }; 80d4fd0404SClaudiu Manoil 81d6a2829eSVladimir Oltean #define ENETC_RX_RING_DEFAULT_SIZE 2048 8202293dd4SClaudiu Manoil #define ENETC_TX_RING_DEFAULT_SIZE 256 8302293dd4SClaudiu Manoil #define ENETC_DEFAULT_TX_WORK (ENETC_TX_RING_DEFAULT_SIZE / 2) 84d4fd0404SClaudiu Manoil 85d4fd0404SClaudiu Manoil struct enetc_bdr { 86d4fd0404SClaudiu Manoil struct device *dev; /* for DMA mapping */ 87d4fd0404SClaudiu Manoil struct net_device *ndev; 88d4fd0404SClaudiu Manoil void *bd_base; /* points to Rx or Tx BD ring */ 89d4fd0404SClaudiu Manoil union { 90d4fd0404SClaudiu Manoil void __iomem *tpir; 91d4fd0404SClaudiu Manoil void __iomem *rcir; 92d4fd0404SClaudiu Manoil }; 93d4fd0404SClaudiu Manoil u16 index; 94d4fd0404SClaudiu Manoil int bd_count; /* # of BDs */ 95d4fd0404SClaudiu Manoil int next_to_use; 96d4fd0404SClaudiu Manoil int next_to_clean; 97d4fd0404SClaudiu Manoil union { 98d4fd0404SClaudiu Manoil struct enetc_tx_swbd *tx_swbd; 99d4fd0404SClaudiu Manoil struct enetc_rx_swbd *rx_swbd; 100d4fd0404SClaudiu Manoil }; 101d4fd0404SClaudiu Manoil union { 102d4fd0404SClaudiu Manoil void __iomem *tcir; /* Tx */ 103d4fd0404SClaudiu Manoil int next_to_alloc; /* Rx */ 104d4fd0404SClaudiu Manoil }; 105d4fd0404SClaudiu Manoil void __iomem *idr; /* Interrupt Detect Register pointer */ 106d4fd0404SClaudiu Manoil 107d1b15102SVladimir Oltean int buffer_offset; 108d1b15102SVladimir Oltean struct enetc_xdp_data xdp; 109d1b15102SVladimir Oltean 110d4fd0404SClaudiu Manoil struct enetc_ring_stats stats; 111d4fd0404SClaudiu Manoil 112d4fd0404SClaudiu Manoil dma_addr_t bd_dma_base; 1130d08c9ecSPo Liu u8 tsd_enable; /* Time specific departure */ 114434cebabSClaudiu Manoil bool ext_en; /* enable h/w descriptor extensions */ 115d4fd0404SClaudiu Manoil } ____cacheline_aligned_in_smp; 116d4fd0404SClaudiu Manoil 117d4fd0404SClaudiu Manoil static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i) 118d4fd0404SClaudiu Manoil { 119d4fd0404SClaudiu Manoil if (unlikely(++*i == bdr->bd_count)) 120d4fd0404SClaudiu Manoil *i = 0; 121d4fd0404SClaudiu Manoil } 122d4fd0404SClaudiu Manoil 123d4fd0404SClaudiu Manoil static inline int enetc_bd_unused(struct enetc_bdr *bdr) 124d4fd0404SClaudiu Manoil { 125d4fd0404SClaudiu Manoil if (bdr->next_to_clean > bdr->next_to_use) 126d4fd0404SClaudiu Manoil return bdr->next_to_clean - bdr->next_to_use - 1; 127d4fd0404SClaudiu Manoil 128d4fd0404SClaudiu Manoil return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1; 129d4fd0404SClaudiu Manoil } 130d4fd0404SClaudiu Manoil 1317ed2bc80SVladimir Oltean static inline int enetc_swbd_unused(struct enetc_bdr *bdr) 1327ed2bc80SVladimir Oltean { 1337ed2bc80SVladimir Oltean if (bdr->next_to_clean > bdr->next_to_alloc) 1347ed2bc80SVladimir Oltean return bdr->next_to_clean - bdr->next_to_alloc - 1; 1357ed2bc80SVladimir Oltean 1367ed2bc80SVladimir Oltean return bdr->bd_count + bdr->next_to_clean - bdr->next_to_alloc - 1; 1377ed2bc80SVladimir Oltean } 1387ed2bc80SVladimir Oltean 139d4fd0404SClaudiu Manoil /* Control BD ring */ 140d4fd0404SClaudiu Manoil #define ENETC_CBDR_DEFAULT_SIZE 64 141d4fd0404SClaudiu Manoil struct enetc_cbdr { 142d4fd0404SClaudiu Manoil void *bd_base; /* points to Rx or Tx BD ring */ 143d4fd0404SClaudiu Manoil void __iomem *pir; 144d4fd0404SClaudiu Manoil void __iomem *cir; 14527f9025dSVladimir Oltean void __iomem *mr; /* mode register */ 146d4fd0404SClaudiu Manoil 147d4fd0404SClaudiu Manoil int bd_count; /* # of BDs */ 148d4fd0404SClaudiu Manoil int next_to_use; 149d4fd0404SClaudiu Manoil int next_to_clean; 150d4fd0404SClaudiu Manoil 151d4fd0404SClaudiu Manoil dma_addr_t bd_dma_base; 15201121ab7SVladimir Oltean struct device *dma_dev; 153d4fd0404SClaudiu Manoil }; 154d4fd0404SClaudiu Manoil 155d4fd0404SClaudiu Manoil #define ENETC_TXBD(BDR, i) (&(((union enetc_tx_bd *)((BDR).bd_base))[i])) 156714239acSClaudiu Manoil 157714239acSClaudiu Manoil static inline union enetc_rx_bd *enetc_rxbd(struct enetc_bdr *rx_ring, int i) 158714239acSClaudiu Manoil { 159434cebabSClaudiu Manoil int hw_idx = i; 160434cebabSClaudiu Manoil 161434cebabSClaudiu Manoil #ifdef CONFIG_FSL_ENETC_PTP_CLOCK 162434cebabSClaudiu Manoil if (rx_ring->ext_en) 163434cebabSClaudiu Manoil hw_idx = 2 * i; 164434cebabSClaudiu Manoil #endif 165434cebabSClaudiu Manoil return &(((union enetc_rx_bd *)rx_ring->bd_base)[hw_idx]); 166714239acSClaudiu Manoil } 167714239acSClaudiu Manoil 168c027aa92SVladimir Oltean static inline void enetc_rxbd_next(struct enetc_bdr *rx_ring, 169c027aa92SVladimir Oltean union enetc_rx_bd **old_rxbd, int *old_index) 170714239acSClaudiu Manoil { 171c027aa92SVladimir Oltean union enetc_rx_bd *new_rxbd = *old_rxbd; 172c027aa92SVladimir Oltean int new_index = *old_index; 173c027aa92SVladimir Oltean 174c027aa92SVladimir Oltean new_rxbd++; 175c027aa92SVladimir Oltean 176434cebabSClaudiu Manoil #ifdef CONFIG_FSL_ENETC_PTP_CLOCK 177434cebabSClaudiu Manoil if (rx_ring->ext_en) 178c027aa92SVladimir Oltean new_rxbd++; 179434cebabSClaudiu Manoil #endif 180714239acSClaudiu Manoil 181c027aa92SVladimir Oltean if (unlikely(++new_index == rx_ring->bd_count)) { 182c027aa92SVladimir Oltean new_rxbd = rx_ring->bd_base; 183c027aa92SVladimir Oltean new_index = 0; 184c027aa92SVladimir Oltean } 185c027aa92SVladimir Oltean 186c027aa92SVladimir Oltean *old_rxbd = new_rxbd; 187c027aa92SVladimir Oltean *old_index = new_index; 188714239acSClaudiu Manoil } 189d4fd0404SClaudiu Manoil 190434cebabSClaudiu Manoil static inline union enetc_rx_bd *enetc_rxbd_ext(union enetc_rx_bd *rxbd) 191434cebabSClaudiu Manoil { 192434cebabSClaudiu Manoil return ++rxbd; 193434cebabSClaudiu Manoil } 194434cebabSClaudiu Manoil 195beb74ac8SClaudiu Manoil struct enetc_msg_swbd { 196beb74ac8SClaudiu Manoil void *vaddr; 197beb74ac8SClaudiu Manoil dma_addr_t dma; 198beb74ac8SClaudiu Manoil int size; 199beb74ac8SClaudiu Manoil }; 200beb74ac8SClaudiu Manoil 201d4fd0404SClaudiu Manoil #define ENETC_REV1 0x1 202d4fd0404SClaudiu Manoil enum enetc_errata { 20382728b91SClaudiu Manoil ENETC_ERR_VLAN_ISOL = BIT(0), 20482728b91SClaudiu Manoil ENETC_ERR_UCMCSWP = BIT(1), 205d4fd0404SClaudiu Manoil }; 206d4fd0404SClaudiu Manoil 2072e47cb41SPo Liu #define ENETC_SI_F_QBV BIT(0) 20879e49982SPo Liu #define ENETC_SI_F_PSFP BIT(1) 2092e47cb41SPo Liu 210d4fd0404SClaudiu Manoil /* PCI IEP device data */ 211d4fd0404SClaudiu Manoil struct enetc_si { 212d4fd0404SClaudiu Manoil struct pci_dev *pdev; 213d4fd0404SClaudiu Manoil struct enetc_hw hw; 214d4fd0404SClaudiu Manoil enum enetc_errata errata; 215d4fd0404SClaudiu Manoil 216d4fd0404SClaudiu Manoil struct net_device *ndev; /* back ref. */ 217d4fd0404SClaudiu Manoil 218d4fd0404SClaudiu Manoil struct enetc_cbdr cbd_ring; 219d4fd0404SClaudiu Manoil 220d4fd0404SClaudiu Manoil int num_rx_rings; /* how many rings are available in the SI */ 221d4fd0404SClaudiu Manoil int num_tx_rings; 222d382563fSClaudiu Manoil int num_fs_entries; 223d382563fSClaudiu Manoil int num_rss; /* number of RSS buckets */ 224d4fd0404SClaudiu Manoil unsigned short pad; 2252e47cb41SPo Liu int hw_features; 226d4fd0404SClaudiu Manoil }; 227d4fd0404SClaudiu Manoil 228d4fd0404SClaudiu Manoil #define ENETC_SI_ALIGN 32 229d4fd0404SClaudiu Manoil 230d4fd0404SClaudiu Manoil static inline void *enetc_si_priv(const struct enetc_si *si) 231d4fd0404SClaudiu Manoil { 232d4fd0404SClaudiu Manoil return (char *)si + ALIGN(sizeof(struct enetc_si), ENETC_SI_ALIGN); 233d4fd0404SClaudiu Manoil } 234d4fd0404SClaudiu Manoil 235d4fd0404SClaudiu Manoil static inline bool enetc_si_is_pf(struct enetc_si *si) 236d4fd0404SClaudiu Manoil { 237d4fd0404SClaudiu Manoil return !!(si->hw.port); 238d4fd0404SClaudiu Manoil } 239d4fd0404SClaudiu Manoil 240d4fd0404SClaudiu Manoil #define ENETC_MAX_NUM_TXQS 8 241d4fd0404SClaudiu Manoil #define ENETC_INT_NAME_MAX (IFNAMSIZ + 8) 242d4fd0404SClaudiu Manoil 243d4fd0404SClaudiu Manoil struct enetc_int_vector { 244d4fd0404SClaudiu Manoil void __iomem *rbier; 245d4fd0404SClaudiu Manoil void __iomem *tbier_base; 24691571081SClaudiu Manoil void __iomem *ricr1; 247d4fd0404SClaudiu Manoil unsigned long tx_rings_map; 248d4fd0404SClaudiu Manoil int count_tx_rings; 24991571081SClaudiu Manoil u32 rx_ictt; 250ae0e6a5dSClaudiu Manoil u16 comp_cnt; 251ae0e6a5dSClaudiu Manoil bool rx_dim_en, rx_napi_work; 252ae0e6a5dSClaudiu Manoil struct napi_struct napi ____cacheline_aligned_in_smp; 253ae0e6a5dSClaudiu Manoil struct dim rx_dim ____cacheline_aligned_in_smp; 254d4fd0404SClaudiu Manoil char name[ENETC_INT_NAME_MAX]; 255d4fd0404SClaudiu Manoil 256058d9cfaSClaudiu Manoil struct enetc_bdr rx_ring; 257cc5b48b5SGustavo A. R. Silva struct enetc_bdr tx_ring[]; 258ae0e6a5dSClaudiu Manoil } ____cacheline_aligned_in_smp; 259d4fd0404SClaudiu Manoil 260d382563fSClaudiu Manoil struct enetc_cls_rule { 261d382563fSClaudiu Manoil struct ethtool_rx_flow_spec fs; 262d382563fSClaudiu Manoil int used; 263d382563fSClaudiu Manoil }; 264d382563fSClaudiu Manoil 265d4fd0404SClaudiu Manoil #define ENETC_MAX_BDR_INT 2 /* fixed to max # of available cpus */ 26679e49982SPo Liu struct psfp_cap { 26779e49982SPo Liu u32 max_streamid; 26879e49982SPo Liu u32 max_psfp_filter; 26979e49982SPo Liu u32 max_psfp_gate; 27079e49982SPo Liu u32 max_psfp_gatelist; 27179e49982SPo Liu u32 max_psfp_meter; 27279e49982SPo Liu }; 273d4fd0404SClaudiu Manoil 274f768e751SYangbo Lu #define ENETC_F_TX_TSTAMP_MASK 0xff 275d3982312SY.b. Lu /* TODO: more hardware offloads */ 276d3982312SY.b. Lu enum enetc_active_offloads { 277f768e751SYangbo Lu /* 8 bits reserved for TX timestamp types (hwtstamp_tx_types) */ 278f768e751SYangbo Lu ENETC_F_TX_TSTAMP = BIT(0), 2797294380cSYangbo Lu ENETC_F_TX_ONESTEP_SYNC_TSTAMP = BIT(1), 280f768e751SYangbo Lu 281f768e751SYangbo Lu ENETC_F_RX_TSTAMP = BIT(8), 282f768e751SYangbo Lu ENETC_F_QBV = BIT(9), 283f768e751SYangbo Lu ENETC_F_QCI = BIT(10), 284d3982312SY.b. Lu }; 285d3982312SY.b. Lu 2867294380cSYangbo Lu enum enetc_flags_bit { 2877294380cSYangbo Lu ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, 2887294380cSYangbo Lu }; 2897294380cSYangbo Lu 29091571081SClaudiu Manoil /* interrupt coalescing modes */ 29191571081SClaudiu Manoil enum enetc_ic_mode { 29291571081SClaudiu Manoil /* one interrupt per frame */ 29391571081SClaudiu Manoil ENETC_IC_NONE = 0, 29491571081SClaudiu Manoil /* activated when int coalescing time is set to a non-0 value */ 29591571081SClaudiu Manoil ENETC_IC_RX_MANUAL = BIT(0), 29691571081SClaudiu Manoil ENETC_IC_TX_MANUAL = BIT(1), 297ae0e6a5dSClaudiu Manoil /* use dynamic interrupt moderation */ 298ae0e6a5dSClaudiu Manoil ENETC_IC_RX_ADAPTIVE = BIT(2), 29991571081SClaudiu Manoil }; 30091571081SClaudiu Manoil 30191571081SClaudiu Manoil #define ENETC_RXIC_PKTTHR min_t(u32, 256, ENETC_RX_RING_DEFAULT_SIZE / 2) 30291571081SClaudiu Manoil #define ENETC_TXIC_PKTTHR min_t(u32, 128, ENETC_TX_RING_DEFAULT_SIZE / 2) 303ae0e6a5dSClaudiu Manoil #define ENETC_TXIC_TIMETHR enetc_usecs_to_cycles(600) 30491571081SClaudiu Manoil 305d4fd0404SClaudiu Manoil struct enetc_ndev_priv { 306d4fd0404SClaudiu Manoil struct net_device *ndev; 307d4fd0404SClaudiu Manoil struct device *dev; /* dma-mapping device */ 308d4fd0404SClaudiu Manoil struct enetc_si *si; 309d4fd0404SClaudiu Manoil 310d4fd0404SClaudiu Manoil int bdr_int_num; /* number of Rx/Tx ring interrupts */ 311d4fd0404SClaudiu Manoil struct enetc_int_vector *int_vector[ENETC_MAX_BDR_INT]; 312d4fd0404SClaudiu Manoil u16 num_rx_rings, num_tx_rings; 313d4fd0404SClaudiu Manoil u16 rx_bd_count, tx_bd_count; 314d4fd0404SClaudiu Manoil 315d4fd0404SClaudiu Manoil u16 msg_enable; 3167f071a45SVladimir Oltean enum enetc_active_offloads active_offloads; 317d4fd0404SClaudiu Manoil 3182e47cb41SPo Liu u32 speed; /* store speed for compare update pspeed */ 3192e47cb41SPo Liu 320d4fd0404SClaudiu Manoil struct enetc_bdr *tx_ring[16]; 321d4fd0404SClaudiu Manoil struct enetc_bdr *rx_ring[16]; 322d4fd0404SClaudiu Manoil 323d382563fSClaudiu Manoil struct enetc_cls_rule *cls_rules; 324d382563fSClaudiu Manoil 32579e49982SPo Liu struct psfp_cap psfp_cap; 32679e49982SPo Liu 32771b77a7aSClaudiu Manoil struct phylink *phylink; 32891571081SClaudiu Manoil int ic_mode; 32991571081SClaudiu Manoil u32 tx_ictt; 330d1b15102SVladimir Oltean 331d1b15102SVladimir Oltean struct bpf_prog *xdp_prog; 3327294380cSYangbo Lu 3337294380cSYangbo Lu unsigned long flags; 3347294380cSYangbo Lu 3357294380cSYangbo Lu struct work_struct tx_onestep_tstamp; 3367294380cSYangbo Lu struct sk_buff_head tx_skbs; 337d4fd0404SClaudiu Manoil }; 338d4fd0404SClaudiu Manoil 339beb74ac8SClaudiu Manoil /* Messaging */ 340beb74ac8SClaudiu Manoil 341beb74ac8SClaudiu Manoil /* VF-PF set primary MAC address message format */ 342beb74ac8SClaudiu Manoil struct enetc_msg_cmd_set_primary_mac { 343beb74ac8SClaudiu Manoil struct enetc_msg_cmd_header header; 344beb74ac8SClaudiu Manoil struct sockaddr mac; 345beb74ac8SClaudiu Manoil }; 346beb74ac8SClaudiu Manoil 347d4fd0404SClaudiu Manoil #define ENETC_CBD(R, i) (&(((struct enetc_cbd *)((R).bd_base))[i])) 348d4fd0404SClaudiu Manoil 349d4fd0404SClaudiu Manoil #define ENETC_CBDR_TIMEOUT 1000 /* usecs */ 350d4fd0404SClaudiu Manoil 35141514737SY.b. Lu /* PTP driver exports */ 35241514737SY.b. Lu extern int enetc_phc_index; 35341514737SY.b. Lu 354d4fd0404SClaudiu Manoil /* SI common */ 355d4fd0404SClaudiu Manoil int enetc_pci_probe(struct pci_dev *pdev, const char *name, int sizeof_priv); 356d4fd0404SClaudiu Manoil void enetc_pci_remove(struct pci_dev *pdev); 357d4fd0404SClaudiu Manoil int enetc_alloc_msix(struct enetc_ndev_priv *priv); 358d4fd0404SClaudiu Manoil void enetc_free_msix(struct enetc_ndev_priv *priv); 359d4fd0404SClaudiu Manoil void enetc_get_si_caps(struct enetc_si *si); 360d4fd0404SClaudiu Manoil void enetc_init_si_rings_params(struct enetc_ndev_priv *priv); 361d4fd0404SClaudiu Manoil int enetc_alloc_si_resources(struct enetc_ndev_priv *priv); 362d4fd0404SClaudiu Manoil void enetc_free_si_resources(struct enetc_ndev_priv *priv); 363c646d10dSVladimir Oltean int enetc_configure_si(struct enetc_ndev_priv *priv); 364d4fd0404SClaudiu Manoil 365d4fd0404SClaudiu Manoil int enetc_open(struct net_device *ndev); 366d4fd0404SClaudiu Manoil int enetc_close(struct net_device *ndev); 36791571081SClaudiu Manoil void enetc_start(struct net_device *ndev); 36891571081SClaudiu Manoil void enetc_stop(struct net_device *ndev); 369d4fd0404SClaudiu Manoil netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev); 370d4fd0404SClaudiu Manoil struct net_device_stats *enetc_get_stats(struct net_device *ndev); 371d382563fSClaudiu Manoil int enetc_set_features(struct net_device *ndev, 372d382563fSClaudiu Manoil netdev_features_t features); 373d3982312SY.b. Lu int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd); 374cbe9e835SCamelia Groza int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, 375cbe9e835SCamelia Groza void *type_data); 376d1b15102SVladimir Oltean int enetc_setup_bpf(struct net_device *dev, struct netdev_bpf *xdp); 3779d2b68ccSVladimir Oltean int enetc_xdp_xmit(struct net_device *ndev, int num_frames, 3789d2b68ccSVladimir Oltean struct xdp_frame **frames, u32 flags); 379cbe9e835SCamelia Groza 380d4fd0404SClaudiu Manoil /* ethtool */ 381d4fd0404SClaudiu Manoil void enetc_set_ethtool_ops(struct net_device *ndev); 382d4fd0404SClaudiu Manoil 383d4fd0404SClaudiu Manoil /* control buffer descriptor ring (CBDR) */ 3845b4daa7fSVladimir Oltean int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count, 38524be14e3SVladimir Oltean struct enetc_cbdr *cbdr); 3860bfde022SVladimir Oltean void enetc_teardown_cbdr(struct enetc_cbdr *cbdr); 387d4fd0404SClaudiu Manoil int enetc_set_mac_flt_entry(struct enetc_si *si, int index, 388d4fd0404SClaudiu Manoil char *mac_addr, int si_map); 389d4fd0404SClaudiu Manoil int enetc_clear_mac_flt_entry(struct enetc_si *si, int index); 390d382563fSClaudiu Manoil int enetc_set_fs_entry(struct enetc_si *si, struct enetc_cmd_rfse *rfse, 391d382563fSClaudiu Manoil int index); 392d382563fSClaudiu Manoil void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes); 393d382563fSClaudiu Manoil int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count); 394d382563fSClaudiu Manoil int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count); 39534c6adf1SPo Liu int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd); 39634c6adf1SPo Liu 39734c6adf1SPo Liu #ifdef CONFIG_FSL_ENETC_QOS 39834c6adf1SPo Liu int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data); 39971b77a7aSClaudiu Manoil void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed); 400c431047cSPo Liu int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data); 4010d08c9ecSPo Liu int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data); 402888ae5a3SPo Liu int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 403888ae5a3SPo Liu void *cb_priv); 404888ae5a3SPo Liu int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data); 405888ae5a3SPo Liu int enetc_psfp_init(struct enetc_ndev_priv *priv); 406888ae5a3SPo Liu int enetc_psfp_clean(struct enetc_ndev_priv *priv); 40779e49982SPo Liu 40879e49982SPo Liu static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv) 40979e49982SPo Liu { 41079e49982SPo Liu u32 reg; 41179e49982SPo Liu 41279e49982SPo Liu reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR); 41379e49982SPo Liu priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK; 41479e49982SPo Liu /* Port stream filter capability */ 41579e49982SPo Liu reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR); 41679e49982SPo Liu priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK; 41779e49982SPo Liu /* Port stream gate capability */ 41879e49982SPo Liu reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR); 41979e49982SPo Liu priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK); 42079e49982SPo Liu priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16; 42179e49982SPo Liu /* Port flow meter capability */ 42279e49982SPo Liu reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR); 42379e49982SPo Liu priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK; 42479e49982SPo Liu } 42579e49982SPo Liu 426888ae5a3SPo Liu static inline int enetc_psfp_enable(struct enetc_ndev_priv *priv) 42779e49982SPo Liu { 428888ae5a3SPo Liu struct enetc_hw *hw = &priv->si->hw; 429888ae5a3SPo Liu int err; 430888ae5a3SPo Liu 431888ae5a3SPo Liu enetc_get_max_cap(priv); 432888ae5a3SPo Liu 433888ae5a3SPo Liu err = enetc_psfp_init(priv); 434888ae5a3SPo Liu if (err) 435888ae5a3SPo Liu return err; 436888ae5a3SPo Liu 43779e49982SPo Liu enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) | 43879e49982SPo Liu ENETC_PPSFPMR_PSFPEN | ENETC_PPSFPMR_VS | 43979e49982SPo Liu ENETC_PPSFPMR_PVC | ENETC_PPSFPMR_PVZC); 440888ae5a3SPo Liu 441888ae5a3SPo Liu return 0; 44279e49982SPo Liu } 44379e49982SPo Liu 444888ae5a3SPo Liu static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv) 44579e49982SPo Liu { 446888ae5a3SPo Liu struct enetc_hw *hw = &priv->si->hw; 447888ae5a3SPo Liu int err; 448888ae5a3SPo Liu 449888ae5a3SPo Liu err = enetc_psfp_clean(priv); 450888ae5a3SPo Liu if (err) 451888ae5a3SPo Liu return err; 452888ae5a3SPo Liu 45379e49982SPo Liu enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) & 45479e49982SPo Liu ~ENETC_PPSFPMR_PSFPEN & ~ENETC_PPSFPMR_VS & 45579e49982SPo Liu ~ENETC_PPSFPMR_PVC & ~ENETC_PPSFPMR_PVZC); 456888ae5a3SPo Liu 457888ae5a3SPo Liu memset(&priv->psfp_cap, 0, sizeof(struct psfp_cap)); 458888ae5a3SPo Liu 459888ae5a3SPo Liu return 0; 46079e49982SPo Liu } 461888ae5a3SPo Liu 46234c6adf1SPo Liu #else 46334c6adf1SPo Liu #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP 46471b77a7aSClaudiu Manoil #define enetc_sched_speed_set(priv, speed) (void)0 465c431047cSPo Liu #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP 4660d08c9ecSPo Liu #define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP 467888ae5a3SPo Liu #define enetc_setup_tc_psfp(ndev, type_data) -EOPNOTSUPP 468888ae5a3SPo Liu #define enetc_setup_tc_block_cb NULL 469888ae5a3SPo Liu 47079e49982SPo Liu #define enetc_get_max_cap(p) \ 47179e49982SPo Liu memset(&((p)->psfp_cap), 0, sizeof(struct psfp_cap)) 47279e49982SPo Liu 473888ae5a3SPo Liu static inline int enetc_psfp_enable(struct enetc_ndev_priv *priv) 474888ae5a3SPo Liu { 475888ae5a3SPo Liu return 0; 476888ae5a3SPo Liu } 477888ae5a3SPo Liu 478888ae5a3SPo Liu static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv) 479888ae5a3SPo Liu { 480888ae5a3SPo Liu return 0; 481888ae5a3SPo Liu } 48234c6adf1SPo Liu #endif 483