1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2*4882a593Smuzhiyun /* Copyright 2017-2019 NXP */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #include <linux/timer.h>
5*4882a593Smuzhiyun #include <linux/pci.h>
6*4882a593Smuzhiyun #include <linux/netdevice.h>
7*4882a593Smuzhiyun #include <linux/etherdevice.h>
8*4882a593Smuzhiyun #include <linux/dma-mapping.h>
9*4882a593Smuzhiyun #include <linux/skbuff.h>
10*4882a593Smuzhiyun #include <linux/ethtool.h>
11*4882a593Smuzhiyun #include <linux/if_vlan.h>
12*4882a593Smuzhiyun #include <linux/phylink.h>
13*4882a593Smuzhiyun #include <linux/dim.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include "enetc_hw.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define ENETC_MAC_MAXFRM_SIZE 9600
18*4882a593Smuzhiyun #define ENETC_MAX_MTU (ENETC_MAC_MAXFRM_SIZE - \
19*4882a593Smuzhiyun (ETH_FCS_LEN + ETH_HLEN + VLAN_HLEN))
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun struct enetc_tx_swbd {
22*4882a593Smuzhiyun struct sk_buff *skb;
23*4882a593Smuzhiyun dma_addr_t dma;
24*4882a593Smuzhiyun u16 len;
25*4882a593Smuzhiyun u8 is_dma_page:1;
26*4882a593Smuzhiyun u8 check_wb:1;
27*4882a593Smuzhiyun u8 do_tstamp:1;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE
31*4882a593Smuzhiyun #define ENETC_RXB_TRUESIZE 2048 /* PAGE_SIZE >> 1 */
32*4882a593Smuzhiyun #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */
33*4882a593Smuzhiyun #define ENETC_RXB_DMA_SIZE \
34*4882a593Smuzhiyun (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD)
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun struct enetc_rx_swbd {
37*4882a593Smuzhiyun dma_addr_t dma;
38*4882a593Smuzhiyun struct page *page;
39*4882a593Smuzhiyun u16 page_offset;
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun struct enetc_ring_stats {
43*4882a593Smuzhiyun unsigned int packets;
44*4882a593Smuzhiyun unsigned int bytes;
45*4882a593Smuzhiyun unsigned int rx_alloc_errs;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun #define ENETC_RX_RING_DEFAULT_SIZE 512
49*4882a593Smuzhiyun #define ENETC_TX_RING_DEFAULT_SIZE 256
50*4882a593Smuzhiyun #define ENETC_DEFAULT_TX_WORK (ENETC_TX_RING_DEFAULT_SIZE / 2)
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun struct enetc_bdr {
53*4882a593Smuzhiyun struct device *dev; /* for DMA mapping */
54*4882a593Smuzhiyun struct net_device *ndev;
55*4882a593Smuzhiyun void *bd_base; /* points to Rx or Tx BD ring */
56*4882a593Smuzhiyun union {
57*4882a593Smuzhiyun void __iomem *tpir;
58*4882a593Smuzhiyun void __iomem *rcir;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun u16 index;
61*4882a593Smuzhiyun u16 prio;
62*4882a593Smuzhiyun int bd_count; /* # of BDs */
63*4882a593Smuzhiyun int next_to_use;
64*4882a593Smuzhiyun int next_to_clean;
65*4882a593Smuzhiyun union {
66*4882a593Smuzhiyun struct enetc_tx_swbd *tx_swbd;
67*4882a593Smuzhiyun struct enetc_rx_swbd *rx_swbd;
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun union {
70*4882a593Smuzhiyun void __iomem *tcir; /* Tx */
71*4882a593Smuzhiyun int next_to_alloc; /* Rx */
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun void __iomem *idr; /* Interrupt Detect Register pointer */
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun struct enetc_ring_stats stats;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun dma_addr_t bd_dma_base;
78*4882a593Smuzhiyun u8 tsd_enable; /* Time specific departure */
79*4882a593Smuzhiyun bool ext_en; /* enable h/w descriptor extensions */
80*4882a593Smuzhiyun } ____cacheline_aligned_in_smp;
81*4882a593Smuzhiyun
enetc_bdr_idx_inc(struct enetc_bdr * bdr,int * i)82*4882a593Smuzhiyun static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun if (unlikely(++*i == bdr->bd_count))
85*4882a593Smuzhiyun *i = 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
enetc_bd_unused(struct enetc_bdr * bdr)88*4882a593Smuzhiyun static inline int enetc_bd_unused(struct enetc_bdr *bdr)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun if (bdr->next_to_clean > bdr->next_to_use)
91*4882a593Smuzhiyun return bdr->next_to_clean - bdr->next_to_use - 1;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun return bdr->bd_count + bdr->next_to_clean - bdr->next_to_use - 1;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Control BD ring */
97*4882a593Smuzhiyun #define ENETC_CBDR_DEFAULT_SIZE 64
98*4882a593Smuzhiyun struct enetc_cbdr {
99*4882a593Smuzhiyun void *bd_base; /* points to Rx or Tx BD ring */
100*4882a593Smuzhiyun void __iomem *pir;
101*4882a593Smuzhiyun void __iomem *cir;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun int bd_count; /* # of BDs */
104*4882a593Smuzhiyun int next_to_use;
105*4882a593Smuzhiyun int next_to_clean;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun dma_addr_t bd_dma_base;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define ENETC_TXBD(BDR, i) (&(((union enetc_tx_bd *)((BDR).bd_base))[i]))
111*4882a593Smuzhiyun
enetc_rxbd(struct enetc_bdr * rx_ring,int i)112*4882a593Smuzhiyun static inline union enetc_rx_bd *enetc_rxbd(struct enetc_bdr *rx_ring, int i)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun int hw_idx = i;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #ifdef CONFIG_FSL_ENETC_PTP_CLOCK
117*4882a593Smuzhiyun if (rx_ring->ext_en)
118*4882a593Smuzhiyun hw_idx = 2 * i;
119*4882a593Smuzhiyun #endif
120*4882a593Smuzhiyun return &(((union enetc_rx_bd *)rx_ring->bd_base)[hw_idx]);
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
enetc_rxbd_next(struct enetc_bdr * rx_ring,union enetc_rx_bd * rxbd,int i)123*4882a593Smuzhiyun static inline union enetc_rx_bd *enetc_rxbd_next(struct enetc_bdr *rx_ring,
124*4882a593Smuzhiyun union enetc_rx_bd *rxbd,
125*4882a593Smuzhiyun int i)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun rxbd++;
128*4882a593Smuzhiyun #ifdef CONFIG_FSL_ENETC_PTP_CLOCK
129*4882a593Smuzhiyun if (rx_ring->ext_en)
130*4882a593Smuzhiyun rxbd++;
131*4882a593Smuzhiyun #endif
132*4882a593Smuzhiyun if (unlikely(++i == rx_ring->bd_count))
133*4882a593Smuzhiyun rxbd = rx_ring->bd_base;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun return rxbd;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
enetc_rxbd_ext(union enetc_rx_bd * rxbd)138*4882a593Smuzhiyun static inline union enetc_rx_bd *enetc_rxbd_ext(union enetc_rx_bd *rxbd)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun return ++rxbd;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun struct enetc_msg_swbd {
144*4882a593Smuzhiyun void *vaddr;
145*4882a593Smuzhiyun dma_addr_t dma;
146*4882a593Smuzhiyun int size;
147*4882a593Smuzhiyun };
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun #define ENETC_REV1 0x1
150*4882a593Smuzhiyun enum enetc_errata {
151*4882a593Smuzhiyun ENETC_ERR_TXCSUM = BIT(0),
152*4882a593Smuzhiyun ENETC_ERR_VLAN_ISOL = BIT(1),
153*4882a593Smuzhiyun ENETC_ERR_UCMCSWP = BIT(2),
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun #define ENETC_SI_F_QBV BIT(0)
157*4882a593Smuzhiyun #define ENETC_SI_F_PSFP BIT(1)
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /* PCI IEP device data */
160*4882a593Smuzhiyun struct enetc_si {
161*4882a593Smuzhiyun struct pci_dev *pdev;
162*4882a593Smuzhiyun struct enetc_hw hw;
163*4882a593Smuzhiyun enum enetc_errata errata;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun struct net_device *ndev; /* back ref. */
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun struct enetc_cbdr cbd_ring;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun int num_rx_rings; /* how many rings are available in the SI */
170*4882a593Smuzhiyun int num_tx_rings;
171*4882a593Smuzhiyun int num_fs_entries;
172*4882a593Smuzhiyun int num_rss; /* number of RSS buckets */
173*4882a593Smuzhiyun unsigned short pad;
174*4882a593Smuzhiyun int hw_features;
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun #define ENETC_SI_ALIGN 32
178*4882a593Smuzhiyun
enetc_si_priv(const struct enetc_si * si)179*4882a593Smuzhiyun static inline void *enetc_si_priv(const struct enetc_si *si)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun return (char *)si + ALIGN(sizeof(struct enetc_si), ENETC_SI_ALIGN);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
enetc_si_is_pf(struct enetc_si * si)184*4882a593Smuzhiyun static inline bool enetc_si_is_pf(struct enetc_si *si)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun return !!(si->hw.port);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun #define ENETC_MAX_NUM_TXQS 8
190*4882a593Smuzhiyun #define ENETC_INT_NAME_MAX (IFNAMSIZ + 8)
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun struct enetc_int_vector {
193*4882a593Smuzhiyun void __iomem *rbier;
194*4882a593Smuzhiyun void __iomem *tbier_base;
195*4882a593Smuzhiyun void __iomem *ricr1;
196*4882a593Smuzhiyun unsigned long tx_rings_map;
197*4882a593Smuzhiyun int count_tx_rings;
198*4882a593Smuzhiyun u32 rx_ictt;
199*4882a593Smuzhiyun u16 comp_cnt;
200*4882a593Smuzhiyun bool rx_dim_en, rx_napi_work;
201*4882a593Smuzhiyun struct napi_struct napi ____cacheline_aligned_in_smp;
202*4882a593Smuzhiyun struct dim rx_dim ____cacheline_aligned_in_smp;
203*4882a593Smuzhiyun char name[ENETC_INT_NAME_MAX];
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun struct enetc_bdr rx_ring;
206*4882a593Smuzhiyun struct enetc_bdr tx_ring[];
207*4882a593Smuzhiyun } ____cacheline_aligned_in_smp;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun struct enetc_cls_rule {
210*4882a593Smuzhiyun struct ethtool_rx_flow_spec fs;
211*4882a593Smuzhiyun int used;
212*4882a593Smuzhiyun };
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #define ENETC_MAX_BDR_INT 2 /* fixed to max # of available cpus */
215*4882a593Smuzhiyun struct psfp_cap {
216*4882a593Smuzhiyun u32 max_streamid;
217*4882a593Smuzhiyun u32 max_psfp_filter;
218*4882a593Smuzhiyun u32 max_psfp_gate;
219*4882a593Smuzhiyun u32 max_psfp_gatelist;
220*4882a593Smuzhiyun u32 max_psfp_meter;
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /* TODO: more hardware offloads */
224*4882a593Smuzhiyun enum enetc_active_offloads {
225*4882a593Smuzhiyun ENETC_F_RX_TSTAMP = BIT(0),
226*4882a593Smuzhiyun ENETC_F_TX_TSTAMP = BIT(1),
227*4882a593Smuzhiyun ENETC_F_QBV = BIT(2),
228*4882a593Smuzhiyun ENETC_F_QCI = BIT(3),
229*4882a593Smuzhiyun };
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun /* interrupt coalescing modes */
232*4882a593Smuzhiyun enum enetc_ic_mode {
233*4882a593Smuzhiyun /* one interrupt per frame */
234*4882a593Smuzhiyun ENETC_IC_NONE = 0,
235*4882a593Smuzhiyun /* activated when int coalescing time is set to a non-0 value */
236*4882a593Smuzhiyun ENETC_IC_RX_MANUAL = BIT(0),
237*4882a593Smuzhiyun ENETC_IC_TX_MANUAL = BIT(1),
238*4882a593Smuzhiyun /* use dynamic interrupt moderation */
239*4882a593Smuzhiyun ENETC_IC_RX_ADAPTIVE = BIT(2),
240*4882a593Smuzhiyun };
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun #define ENETC_RXIC_PKTTHR min_t(u32, 256, ENETC_RX_RING_DEFAULT_SIZE / 2)
243*4882a593Smuzhiyun #define ENETC_TXIC_PKTTHR min_t(u32, 128, ENETC_TX_RING_DEFAULT_SIZE / 2)
244*4882a593Smuzhiyun #define ENETC_TXIC_TIMETHR enetc_usecs_to_cycles(600)
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun struct enetc_ndev_priv {
247*4882a593Smuzhiyun struct net_device *ndev;
248*4882a593Smuzhiyun struct device *dev; /* dma-mapping device */
249*4882a593Smuzhiyun struct enetc_si *si;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun int bdr_int_num; /* number of Rx/Tx ring interrupts */
252*4882a593Smuzhiyun struct enetc_int_vector *int_vector[ENETC_MAX_BDR_INT];
253*4882a593Smuzhiyun u16 num_rx_rings, num_tx_rings;
254*4882a593Smuzhiyun u16 rx_bd_count, tx_bd_count;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun u16 msg_enable;
257*4882a593Smuzhiyun int active_offloads;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun u32 speed; /* store speed for compare update pspeed */
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun struct enetc_bdr *tx_ring[16];
262*4882a593Smuzhiyun struct enetc_bdr *rx_ring[16];
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun struct enetc_cls_rule *cls_rules;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun struct psfp_cap psfp_cap;
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun struct phylink *phylink;
269*4882a593Smuzhiyun int ic_mode;
270*4882a593Smuzhiyun u32 tx_ictt;
271*4882a593Smuzhiyun };
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun /* Messaging */
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun /* VF-PF set primary MAC address message format */
276*4882a593Smuzhiyun struct enetc_msg_cmd_set_primary_mac {
277*4882a593Smuzhiyun struct enetc_msg_cmd_header header;
278*4882a593Smuzhiyun struct sockaddr mac;
279*4882a593Smuzhiyun };
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun #define ENETC_CBD(R, i) (&(((struct enetc_cbd *)((R).bd_base))[i]))
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun #define ENETC_CBDR_TIMEOUT 1000 /* usecs */
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /* PTP driver exports */
286*4882a593Smuzhiyun extern int enetc_phc_index;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun /* SI common */
289*4882a593Smuzhiyun int enetc_pci_probe(struct pci_dev *pdev, const char *name, int sizeof_priv);
290*4882a593Smuzhiyun void enetc_pci_remove(struct pci_dev *pdev);
291*4882a593Smuzhiyun int enetc_alloc_msix(struct enetc_ndev_priv *priv);
292*4882a593Smuzhiyun void enetc_free_msix(struct enetc_ndev_priv *priv);
293*4882a593Smuzhiyun void enetc_get_si_caps(struct enetc_si *si);
294*4882a593Smuzhiyun void enetc_init_si_rings_params(struct enetc_ndev_priv *priv);
295*4882a593Smuzhiyun int enetc_alloc_si_resources(struct enetc_ndev_priv *priv);
296*4882a593Smuzhiyun void enetc_free_si_resources(struct enetc_ndev_priv *priv);
297*4882a593Smuzhiyun int enetc_configure_si(struct enetc_ndev_priv *priv);
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun int enetc_open(struct net_device *ndev);
300*4882a593Smuzhiyun int enetc_close(struct net_device *ndev);
301*4882a593Smuzhiyun void enetc_start(struct net_device *ndev);
302*4882a593Smuzhiyun void enetc_stop(struct net_device *ndev);
303*4882a593Smuzhiyun netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
304*4882a593Smuzhiyun struct net_device_stats *enetc_get_stats(struct net_device *ndev);
305*4882a593Smuzhiyun void enetc_set_features(struct net_device *ndev, netdev_features_t features);
306*4882a593Smuzhiyun int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd);
307*4882a593Smuzhiyun int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
308*4882a593Smuzhiyun void *type_data);
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* ethtool */
311*4882a593Smuzhiyun void enetc_set_ethtool_ops(struct net_device *ndev);
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun /* control buffer descriptor ring (CBDR) */
314*4882a593Smuzhiyun int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
315*4882a593Smuzhiyun void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
316*4882a593Smuzhiyun void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr);
317*4882a593Smuzhiyun void enetc_clear_cbdr(struct enetc_hw *hw);
318*4882a593Smuzhiyun int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
319*4882a593Smuzhiyun char *mac_addr, int si_map);
320*4882a593Smuzhiyun int enetc_clear_mac_flt_entry(struct enetc_si *si, int index);
321*4882a593Smuzhiyun int enetc_set_fs_entry(struct enetc_si *si, struct enetc_cmd_rfse *rfse,
322*4882a593Smuzhiyun int index);
323*4882a593Smuzhiyun void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes);
324*4882a593Smuzhiyun int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count);
325*4882a593Smuzhiyun int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count);
326*4882a593Smuzhiyun int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun #ifdef CONFIG_FSL_ENETC_QOS
329*4882a593Smuzhiyun int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
330*4882a593Smuzhiyun void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed);
331*4882a593Smuzhiyun int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
332*4882a593Smuzhiyun int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
333*4882a593Smuzhiyun int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
334*4882a593Smuzhiyun void *cb_priv);
335*4882a593Smuzhiyun int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data);
336*4882a593Smuzhiyun int enetc_psfp_init(struct enetc_ndev_priv *priv);
337*4882a593Smuzhiyun int enetc_psfp_clean(struct enetc_ndev_priv *priv);
338*4882a593Smuzhiyun int enetc_set_psfp(struct net_device *ndev, bool en);
339*4882a593Smuzhiyun
enetc_get_max_cap(struct enetc_ndev_priv * priv)340*4882a593Smuzhiyun static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun struct enetc_hw *hw = &priv->si->hw;
343*4882a593Smuzhiyun u32 reg;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
346*4882a593Smuzhiyun priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
347*4882a593Smuzhiyun /* Port stream filter capability */
348*4882a593Smuzhiyun reg = enetc_port_rd(hw, ENETC_PSFCAPR);
349*4882a593Smuzhiyun priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
350*4882a593Smuzhiyun /* Port stream gate capability */
351*4882a593Smuzhiyun reg = enetc_port_rd(hw, ENETC_PSGCAPR);
352*4882a593Smuzhiyun priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
353*4882a593Smuzhiyun priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
354*4882a593Smuzhiyun /* Port flow meter capability */
355*4882a593Smuzhiyun reg = enetc_port_rd(hw, ENETC_PFMCAPR);
356*4882a593Smuzhiyun priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
enetc_psfp_enable(struct enetc_ndev_priv * priv)359*4882a593Smuzhiyun static inline int enetc_psfp_enable(struct enetc_ndev_priv *priv)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun struct enetc_hw *hw = &priv->si->hw;
362*4882a593Smuzhiyun int err;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun enetc_get_max_cap(priv);
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun err = enetc_psfp_init(priv);
367*4882a593Smuzhiyun if (err)
368*4882a593Smuzhiyun return err;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) |
371*4882a593Smuzhiyun ENETC_PPSFPMR_PSFPEN | ENETC_PPSFPMR_VS |
372*4882a593Smuzhiyun ENETC_PPSFPMR_PVC | ENETC_PPSFPMR_PVZC);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun return 0;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
enetc_psfp_disable(struct enetc_ndev_priv * priv)377*4882a593Smuzhiyun static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun struct enetc_hw *hw = &priv->si->hw;
380*4882a593Smuzhiyun int err;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun err = enetc_psfp_clean(priv);
383*4882a593Smuzhiyun if (err)
384*4882a593Smuzhiyun return err;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) &
387*4882a593Smuzhiyun ~ENETC_PPSFPMR_PSFPEN & ~ENETC_PPSFPMR_VS &
388*4882a593Smuzhiyun ~ENETC_PPSFPMR_PVC & ~ENETC_PPSFPMR_PVZC);
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun memset(&priv->psfp_cap, 0, sizeof(struct psfp_cap));
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun #else
396*4882a593Smuzhiyun #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
397*4882a593Smuzhiyun #define enetc_sched_speed_set(priv, speed) (void)0
398*4882a593Smuzhiyun #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
399*4882a593Smuzhiyun #define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
400*4882a593Smuzhiyun #define enetc_setup_tc_psfp(ndev, type_data) -EOPNOTSUPP
401*4882a593Smuzhiyun #define enetc_setup_tc_block_cb NULL
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun #define enetc_get_max_cap(p) \
404*4882a593Smuzhiyun memset(&((p)->psfp_cap), 0, sizeof(struct psfp_cap))
405*4882a593Smuzhiyun
enetc_psfp_enable(struct enetc_ndev_priv * priv)406*4882a593Smuzhiyun static inline int enetc_psfp_enable(struct enetc_ndev_priv *priv)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun return 0;
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
enetc_psfp_disable(struct enetc_ndev_priv * priv)411*4882a593Smuzhiyun static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)
412*4882a593Smuzhiyun {
413*4882a593Smuzhiyun return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun
enetc_set_psfp(struct net_device * ndev,bool en)416*4882a593Smuzhiyun static inline int enetc_set_psfp(struct net_device *ndev, bool en)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun return 0;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun #endif
421