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
);
31 if (unlikely(rdes3
& XGMAC_RDES3_OWN
))
33 if (likely(!(rdes3
& XGMAC_RDES3_LD
)))
35 if (unlikely(rdes3
& XGMAC_RDES3_ES
))
41 static int dwxgmac2_get_tx_len(struct dma_desc
*p
)
43 return (le32_to_cpu(p
->des2
) & XGMAC_TDES2_B1L
);
46 static int dwxgmac2_get_tx_owner(struct dma_desc
*p
)
48 return (le32_to_cpu(p
->des3
) & XGMAC_TDES3_OWN
) > 0;
51 static void dwxgmac2_set_tx_owner(struct dma_desc
*p
)
53 p
->des3
|= cpu_to_le32(XGMAC_TDES3_OWN
);
56 static void dwxgmac2_set_rx_owner(struct dma_desc
*p
, int disable_rx_ic
)
58 p
->des3
= cpu_to_le32(XGMAC_RDES3_OWN
);
61 p
->des3
|= cpu_to_le32(XGMAC_RDES3_IOC
);
64 static int dwxgmac2_get_tx_ls(struct dma_desc
*p
)
66 return (le32_to_cpu(p
->des3
) & XGMAC_RDES3_LD
) > 0;
69 static int dwxgmac2_get_rx_frame_len(struct dma_desc
*p
, int rx_coe
)
71 return (le32_to_cpu(p
->des3
) & XGMAC_RDES3_PL
);
74 static void dwxgmac2_enable_tx_timestamp(struct dma_desc
*p
)
76 p
->des2
|= cpu_to_le32(XGMAC_TDES2_TTSE
);
79 static int dwxgmac2_get_tx_timestamp_status(struct dma_desc
*p
)
81 return 0; /* Not supported */
84 static inline void dwxgmac2_get_timestamp(void *desc
, u32 ats
, u64
*ts
)
86 struct dma_desc
*p
= (struct dma_desc
*)desc
;
89 ns
+= le32_to_cpu(p
->des1
) * 1000000000ULL;
90 ns
+= le32_to_cpu(p
->des0
);
95 static int dwxgmac2_rx_check_timestamp(void *desc
)
97 struct dma_desc
*p
= (struct dma_desc
*)desc
;
98 unsigned int rdes3
= le32_to_cpu(p
->des3
);
99 bool desc_valid
, ts_valid
;
101 desc_valid
= !(rdes3
& XGMAC_RDES3_OWN
) && (rdes3
& XGMAC_RDES3_CTXT
);
102 ts_valid
= !(rdes3
& XGMAC_RDES3_TSD
) && (rdes3
& XGMAC_RDES3_TSA
);
104 if (likely(desc_valid
&& ts_valid
))
109 static int dwxgmac2_get_rx_timestamp_status(void *desc
, void *next_desc
,
112 struct dma_desc
*p
= (struct dma_desc
*)desc
;
113 unsigned int rdes3
= le32_to_cpu(p
->des3
);
116 if (likely(rdes3
& XGMAC_RDES3_CDA
)) {
117 ret
= dwxgmac2_rx_check_timestamp(next_desc
);
125 static void dwxgmac2_init_rx_desc(struct dma_desc
*p
, int disable_rx_ic
,
128 dwxgmac2_set_rx_owner(p
, disable_rx_ic
);
131 static void dwxgmac2_init_tx_desc(struct dma_desc
*p
, int mode
, int end
)
139 static void dwxgmac2_prepare_tx_desc(struct dma_desc
*p
, int is_fs
, int len
,
140 bool csum_flag
, int mode
, bool tx_own
,
141 bool ls
, unsigned int tot_pkt_len
)
143 unsigned int tdes3
= le32_to_cpu(p
->des3
);
145 p
->des2
|= cpu_to_le32(len
& XGMAC_TDES2_B1L
);
147 tdes3
= tot_pkt_len
& XGMAC_TDES3_FL
;
149 tdes3
|= XGMAC_TDES3_FD
;
151 tdes3
&= ~XGMAC_TDES3_FD
;
154 tdes3
|= 0x3 << XGMAC_TDES3_CIC_SHIFT
;
156 tdes3
&= ~XGMAC_TDES3_CIC
;
159 tdes3
|= XGMAC_TDES3_LD
;
161 tdes3
&= ~XGMAC_TDES3_LD
;
163 /* Finally set the OWN bit. Later the DMA will start! */
165 tdes3
|= XGMAC_TDES3_OWN
;
168 /* When the own bit, for the first frame, has to be set, all
169 * descriptors for the same frame has to be set before, to
170 * avoid race condition.
174 p
->des3
= cpu_to_le32(tdes3
);
177 static void dwxgmac2_prepare_tso_tx_desc(struct dma_desc
*p
, int is_fs
,
178 int len1
, int len2
, bool tx_own
,
179 bool ls
, unsigned int tcphdrlen
,
180 unsigned int tcppayloadlen
)
182 unsigned int tdes3
= le32_to_cpu(p
->des3
);
185 p
->des2
|= cpu_to_le32(len1
& XGMAC_TDES2_B1L
);
187 p
->des2
|= cpu_to_le32((len2
<< XGMAC_TDES2_B2L_SHIFT
) &
190 tdes3
|= XGMAC_TDES3_FD
| XGMAC_TDES3_TSE
;
191 tdes3
|= (tcphdrlen
<< XGMAC_TDES3_THL_SHIFT
) &
193 tdes3
|= tcppayloadlen
& XGMAC_TDES3_TPL
;
195 tdes3
&= ~XGMAC_TDES3_FD
;
199 tdes3
|= XGMAC_TDES3_LD
;
201 tdes3
&= ~XGMAC_TDES3_LD
;
203 /* Finally set the OWN bit. Later the DMA will start! */
205 tdes3
|= XGMAC_TDES3_OWN
;
208 /* When the own bit, for the first frame, has to be set, all
209 * descriptors for the same frame has to be set before, to
210 * avoid race condition.
214 p
->des3
= cpu_to_le32(tdes3
);
217 static void dwxgmac2_release_tx_desc(struct dma_desc
*p
, int mode
)
225 static void dwxgmac2_set_tx_ic(struct dma_desc
*p
)
227 p
->des2
|= cpu_to_le32(XGMAC_TDES2_IOC
);
230 static void dwxgmac2_set_mss(struct dma_desc
*p
, unsigned int mss
)
234 p
->des2
= cpu_to_le32(mss
);
235 p
->des3
= cpu_to_le32(XGMAC_TDES3_CTXT
| XGMAC_TDES3_TCMSSV
);
238 static void dwxgmac2_get_addr(struct dma_desc
*p
, unsigned int *addr
)
240 *addr
= le32_to_cpu(p
->des0
);
243 static void dwxgmac2_set_addr(struct dma_desc
*p
, dma_addr_t addr
)
245 p
->des0
= cpu_to_le32(addr
);
249 static void dwxgmac2_clear(struct dma_desc
*p
)
257 const struct stmmac_desc_ops dwxgmac210_desc_ops
= {
258 .tx_status
= dwxgmac2_get_tx_status
,
259 .rx_status
= dwxgmac2_get_rx_status
,
260 .get_tx_len
= dwxgmac2_get_tx_len
,
261 .get_tx_owner
= dwxgmac2_get_tx_owner
,
262 .set_tx_owner
= dwxgmac2_set_tx_owner
,
263 .set_rx_owner
= dwxgmac2_set_rx_owner
,
264 .get_tx_ls
= dwxgmac2_get_tx_ls
,
265 .get_rx_frame_len
= dwxgmac2_get_rx_frame_len
,
266 .enable_tx_timestamp
= dwxgmac2_enable_tx_timestamp
,
267 .get_tx_timestamp_status
= dwxgmac2_get_tx_timestamp_status
,
268 .get_rx_timestamp_status
= dwxgmac2_get_rx_timestamp_status
,
269 .get_timestamp
= dwxgmac2_get_timestamp
,
270 .set_tx_ic
= dwxgmac2_set_tx_ic
,
271 .prepare_tx_desc
= dwxgmac2_prepare_tx_desc
,
272 .prepare_tso_tx_desc
= dwxgmac2_prepare_tso_tx_desc
,
273 .release_tx_desc
= dwxgmac2_release_tx_desc
,
274 .init_rx_desc
= dwxgmac2_init_rx_desc
,
275 .init_tx_desc
= dwxgmac2_init_tx_desc
,
276 .set_mss
= dwxgmac2_set_mss
,
277 .get_addr
= dwxgmac2_get_addr
,
278 .set_addr
= dwxgmac2_set_addr
,
279 .clear
= dwxgmac2_clear
,