1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
4 * stmmac XGMAC support.
7 #include <linux/stmmac.h>
11 static int dwxgmac2_get_tx_status(void *data
, struct stmmac_extra_stats
*x
,
12 struct dma_desc
*p
, void __iomem
*ioaddr
)
14 unsigned int tdes3
= le32_to_cpu(p
->des3
);
17 if (unlikely(tdes3
& XGMAC_TDES3_OWN
))
19 if (likely(!(tdes3
& XGMAC_TDES3_LD
)))
25 static int dwxgmac2_get_rx_status(void *data
, struct stmmac_extra_stats
*x
,
28 unsigned int rdes3
= le32_to_cpu(p
->des3
);
30 if (unlikely(rdes3
& XGMAC_RDES3_OWN
))
32 if (unlikely(rdes3
& XGMAC_RDES3_CTXT
))
34 if (likely(!(rdes3
& XGMAC_RDES3_LD
)))
36 if (unlikely((rdes3
& XGMAC_RDES3_ES
) && (rdes3
& XGMAC_RDES3_LD
)))
42 static int dwxgmac2_get_tx_len(struct dma_desc
*p
)
44 return (le32_to_cpu(p
->des2
) & XGMAC_TDES2_B1L
);
47 static int dwxgmac2_get_tx_owner(struct dma_desc
*p
)
49 return (le32_to_cpu(p
->des3
) & XGMAC_TDES3_OWN
) > 0;
52 static void dwxgmac2_set_tx_owner(struct dma_desc
*p
)
54 p
->des3
|= cpu_to_le32(XGMAC_TDES3_OWN
);
57 static void dwxgmac2_set_rx_owner(struct dma_desc
*p
, int disable_rx_ic
)
59 p
->des3
|= cpu_to_le32(XGMAC_RDES3_OWN
);
62 p
->des3
|= cpu_to_le32(XGMAC_RDES3_IOC
);
65 static int dwxgmac2_get_tx_ls(struct dma_desc
*p
)
67 return (le32_to_cpu(p
->des3
) & XGMAC_RDES3_LD
) > 0;
70 static int dwxgmac2_get_rx_frame_len(struct dma_desc
*p
, int rx_coe
)
72 return (le32_to_cpu(p
->des3
) & XGMAC_RDES3_PL
);
75 static void dwxgmac2_enable_tx_timestamp(struct dma_desc
*p
)
77 p
->des2
|= cpu_to_le32(XGMAC_TDES2_TTSE
);
80 static int dwxgmac2_get_tx_timestamp_status(struct dma_desc
*p
)
82 return 0; /* Not supported */
85 static inline void dwxgmac2_get_timestamp(void *desc
, u32 ats
, u64
*ts
)
87 struct dma_desc
*p
= (struct dma_desc
*)desc
;
90 ns
+= le32_to_cpu(p
->des1
) * 1000000000ULL;
91 ns
+= le32_to_cpu(p
->des0
);
96 static int dwxgmac2_rx_check_timestamp(void *desc
)
98 struct dma_desc
*p
= (struct dma_desc
*)desc
;
99 unsigned int rdes3
= le32_to_cpu(p
->des3
);
100 bool desc_valid
, ts_valid
;
104 desc_valid
= !(rdes3
& XGMAC_RDES3_OWN
) && (rdes3
& XGMAC_RDES3_CTXT
);
105 ts_valid
= !(rdes3
& XGMAC_RDES3_TSD
) && (rdes3
& XGMAC_RDES3_TSA
);
107 if (likely(desc_valid
&& ts_valid
)) {
108 if ((p
->des0
== 0xffffffff) && (p
->des1
== 0xffffffff))
116 static int dwxgmac2_get_rx_timestamp_status(void *desc
, void *next_desc
,
119 struct dma_desc
*p
= (struct dma_desc
*)desc
;
120 unsigned int rdes3
= le32_to_cpu(p
->des3
);
123 if (likely(rdes3
& XGMAC_RDES3_CDA
))
124 ret
= dwxgmac2_rx_check_timestamp(next_desc
);
129 static void dwxgmac2_init_rx_desc(struct dma_desc
*p
, int disable_rx_ic
,
130 int mode
, int end
, int bfsize
)
132 dwxgmac2_set_rx_owner(p
, disable_rx_ic
);
135 static void dwxgmac2_init_tx_desc(struct dma_desc
*p
, int mode
, int end
)
143 static void dwxgmac2_prepare_tx_desc(struct dma_desc
*p
, int is_fs
, int len
,
144 bool csum_flag
, int mode
, bool tx_own
,
145 bool ls
, unsigned int tot_pkt_len
)
147 unsigned int tdes3
= le32_to_cpu(p
->des3
);
149 p
->des2
|= cpu_to_le32(len
& XGMAC_TDES2_B1L
);
151 tdes3
|= tot_pkt_len
& XGMAC_TDES3_FL
;
153 tdes3
|= XGMAC_TDES3_FD
;
155 tdes3
&= ~XGMAC_TDES3_FD
;
158 tdes3
|= 0x3 << XGMAC_TDES3_CIC_SHIFT
;
160 tdes3
&= ~XGMAC_TDES3_CIC
;
163 tdes3
|= XGMAC_TDES3_LD
;
165 tdes3
&= ~XGMAC_TDES3_LD
;
167 /* Finally set the OWN bit. Later the DMA will start! */
169 tdes3
|= XGMAC_TDES3_OWN
;
172 /* When the own bit, for the first frame, has to be set, all
173 * descriptors for the same frame has to be set before, to
174 * avoid race condition.
178 p
->des3
= cpu_to_le32(tdes3
);
181 static void dwxgmac2_prepare_tso_tx_desc(struct dma_desc
*p
, int is_fs
,
182 int len1
, int len2
, bool tx_own
,
183 bool ls
, unsigned int tcphdrlen
,
184 unsigned int tcppayloadlen
)
186 unsigned int tdes3
= le32_to_cpu(p
->des3
);
189 p
->des2
|= cpu_to_le32(len1
& XGMAC_TDES2_B1L
);
191 p
->des2
|= cpu_to_le32((len2
<< XGMAC_TDES2_B2L_SHIFT
) &
194 tdes3
|= XGMAC_TDES3_FD
| XGMAC_TDES3_TSE
;
195 tdes3
|= (tcphdrlen
<< XGMAC_TDES3_THL_SHIFT
) &
197 tdes3
|= tcppayloadlen
& XGMAC_TDES3_TPL
;
199 tdes3
&= ~XGMAC_TDES3_FD
;
203 tdes3
|= XGMAC_TDES3_LD
;
205 tdes3
&= ~XGMAC_TDES3_LD
;
207 /* Finally set the OWN bit. Later the DMA will start! */
209 tdes3
|= XGMAC_TDES3_OWN
;
212 /* When the own bit, for the first frame, has to be set, all
213 * descriptors for the same frame has to be set before, to
214 * avoid race condition.
218 p
->des3
= cpu_to_le32(tdes3
);
221 static void dwxgmac2_release_tx_desc(struct dma_desc
*p
, int mode
)
229 static void dwxgmac2_set_tx_ic(struct dma_desc
*p
)
231 p
->des2
|= cpu_to_le32(XGMAC_TDES2_IOC
);
234 static void dwxgmac2_set_mss(struct dma_desc
*p
, unsigned int mss
)
238 p
->des2
= cpu_to_le32(mss
);
239 p
->des3
= cpu_to_le32(XGMAC_TDES3_CTXT
| XGMAC_TDES3_TCMSSV
);
242 static void dwxgmac2_get_addr(struct dma_desc
*p
, unsigned int *addr
)
244 *addr
= le32_to_cpu(p
->des0
);
247 static void dwxgmac2_set_addr(struct dma_desc
*p
, dma_addr_t addr
)
249 p
->des0
= cpu_to_le32(lower_32_bits(addr
));
250 p
->des1
= cpu_to_le32(upper_32_bits(addr
));
253 static void dwxgmac2_clear(struct dma_desc
*p
)
261 static int dwxgmac2_get_rx_hash(struct dma_desc
*p
, u32
*hash
,
262 enum pkt_hash_types
*type
)
264 unsigned int rdes3
= le32_to_cpu(p
->des3
);
267 if (rdes3
& XGMAC_RDES3_RSV
) {
268 ptype
= (rdes3
& XGMAC_RDES3_L34T
) >> XGMAC_RDES3_L34T_SHIFT
;
271 case XGMAC_L34T_IP4TCP
:
272 case XGMAC_L34T_IP4UDP
:
273 case XGMAC_L34T_IP6TCP
:
274 case XGMAC_L34T_IP6UDP
:
275 *type
= PKT_HASH_TYPE_L4
;
278 *type
= PKT_HASH_TYPE_L3
;
282 *hash
= le32_to_cpu(p
->des1
);
289 static int dwxgmac2_get_rx_header_len(struct dma_desc
*p
, unsigned int *len
)
291 if (le32_to_cpu(p
->des3
) & XGMAC_RDES3_L34T
)
292 *len
= le32_to_cpu(p
->des2
) & XGMAC_RDES2_HL
;
296 static void dwxgmac2_set_sec_addr(struct dma_desc
*p
, dma_addr_t addr
)
298 p
->des2
= cpu_to_le32(lower_32_bits(addr
));
299 p
->des3
= cpu_to_le32(upper_32_bits(addr
));
302 static void dwxgmac2_set_sarc(struct dma_desc
*p
, u32 sarc_type
)
304 sarc_type
<<= XGMAC_TDES3_SAIC_SHIFT
;
306 p
->des3
|= cpu_to_le32(sarc_type
& XGMAC_TDES3_SAIC
);
309 static void dwxgmac2_set_vlan_tag(struct dma_desc
*p
, u16 tag
, u16 inner_tag
,
319 u32 des
= inner_tag
<< XGMAC_TDES2_IVT_SHIFT
;
321 des
&= XGMAC_TDES2_IVT
;
322 p
->des2
= cpu_to_le32(des
);
324 des
= inner_type
<< XGMAC_TDES3_IVTIR_SHIFT
;
325 des
&= XGMAC_TDES3_IVTIR
;
326 p
->des3
= cpu_to_le32(des
| XGMAC_TDES3_IVLTV
);
330 p
->des3
|= cpu_to_le32(tag
& XGMAC_TDES3_VT
);
331 p
->des3
|= cpu_to_le32(XGMAC_TDES3_VLTV
);
333 p
->des3
|= cpu_to_le32(XGMAC_TDES3_CTXT
);
336 static void dwxgmac2_set_vlan(struct dma_desc
*p
, u32 type
)
338 type
<<= XGMAC_TDES2_VTIR_SHIFT
;
339 p
->des2
|= cpu_to_le32(type
& XGMAC_TDES2_VTIR
);
342 static void dwxgmac2_set_tbs(struct dma_edesc
*p
, u32 sec
, u32 nsec
)
344 p
->des4
= cpu_to_le32((sec
& XGMAC_TDES0_LT
) | XGMAC_TDES0_LTV
);
345 p
->des5
= cpu_to_le32(nsec
& XGMAC_TDES1_LT
);
350 const struct stmmac_desc_ops dwxgmac210_desc_ops
= {
351 .tx_status
= dwxgmac2_get_tx_status
,
352 .rx_status
= dwxgmac2_get_rx_status
,
353 .get_tx_len
= dwxgmac2_get_tx_len
,
354 .get_tx_owner
= dwxgmac2_get_tx_owner
,
355 .set_tx_owner
= dwxgmac2_set_tx_owner
,
356 .set_rx_owner
= dwxgmac2_set_rx_owner
,
357 .get_tx_ls
= dwxgmac2_get_tx_ls
,
358 .get_rx_frame_len
= dwxgmac2_get_rx_frame_len
,
359 .enable_tx_timestamp
= dwxgmac2_enable_tx_timestamp
,
360 .get_tx_timestamp_status
= dwxgmac2_get_tx_timestamp_status
,
361 .get_rx_timestamp_status
= dwxgmac2_get_rx_timestamp_status
,
362 .get_timestamp
= dwxgmac2_get_timestamp
,
363 .set_tx_ic
= dwxgmac2_set_tx_ic
,
364 .prepare_tx_desc
= dwxgmac2_prepare_tx_desc
,
365 .prepare_tso_tx_desc
= dwxgmac2_prepare_tso_tx_desc
,
366 .release_tx_desc
= dwxgmac2_release_tx_desc
,
367 .init_rx_desc
= dwxgmac2_init_rx_desc
,
368 .init_tx_desc
= dwxgmac2_init_tx_desc
,
369 .set_mss
= dwxgmac2_set_mss
,
370 .get_addr
= dwxgmac2_get_addr
,
371 .set_addr
= dwxgmac2_set_addr
,
372 .clear
= dwxgmac2_clear
,
373 .get_rx_hash
= dwxgmac2_get_rx_hash
,
374 .get_rx_header_len
= dwxgmac2_get_rx_header_len
,
375 .set_sec_addr
= dwxgmac2_set_sec_addr
,
376 .set_sarc
= dwxgmac2_set_sarc
,
377 .set_vlan_tag
= dwxgmac2_set_vlan_tag
,
378 .set_vlan
= dwxgmac2_set_vlan
,
379 .set_tbs
= dwxgmac2_set_tbs
,