1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 // Copyright (c) 2017 Synopsys, Inc. and/or its affiliates.
3 // stmmac Support for 5.xx Ethernet QoS cores
5 #include <linux/bitops.h>
6 #include <linux/iopoll.h>
11 #include "stmmac_ptp.h"
13 struct dwmac5_error_desc
{
16 const char *detailed_desc
;
19 #define STAT_OFF(field) offsetof(struct stmmac_safety_stats, field)
21 static void dwmac5_log_error(struct net_device
*ndev
, u32 value
, bool corr
,
22 const char *module_name
, const struct dwmac5_error_desc
*desc
,
23 unsigned long field_offset
, struct stmmac_safety_stats
*stats
)
25 unsigned long loc
, mask
;
26 u8
*bptr
= (u8
*)stats
;
29 ptr
= (unsigned long *)(bptr
+ field_offset
);
32 for_each_set_bit(loc
, &mask
, 32) {
33 netdev_err(ndev
, "Found %s error in %s: '%s: %s'\n", corr
?
34 "correctable" : "uncorrectable", module_name
,
35 desc
[loc
].desc
, desc
[loc
].detailed_desc
);
42 static const struct dwmac5_error_desc dwmac5_mac_errors
[32]= {
43 { true, "ATPES", "Application Transmit Interface Parity Check Error" },
44 { true, "TPES", "TSO Data Path Parity Check Error" },
45 { true, "RDPES", "Read Descriptor Parity Check Error" },
46 { true, "MPES", "MTL Data Path Parity Check Error" },
47 { true, "MTSPES", "MTL TX Status Data Path Parity Check Error" },
48 { true, "ARPES", "Application Receive Interface Data Path Parity Check Error" },
49 { true, "CWPES", "CSR Write Data Path Parity Check Error" },
50 { true, "ASRPES", "AXI Slave Read Data Path Parity Check Error" },
51 { true, "TTES", "TX FSM Timeout Error" },
52 { true, "RTES", "RX FSM Timeout Error" },
53 { true, "CTES", "CSR FSM Timeout Error" },
54 { true, "ATES", "APP FSM Timeout Error" },
55 { true, "PTES", "PTP FSM Timeout Error" },
56 { true, "T125ES", "TX125 FSM Timeout Error" },
57 { true, "R125ES", "RX125 FSM Timeout Error" },
58 { true, "RVCTES", "REV MDC FSM Timeout Error" },
59 { true, "MSTTES", "Master Read/Write Timeout Error" },
60 { true, "SLVTES", "Slave Read/Write Timeout Error" },
61 { true, "ATITES", "Application Timeout on ATI Interface Error" },
62 { true, "ARITES", "Application Timeout on ARI Interface Error" },
63 { false, "UNKNOWN", "Unknown Error" }, /* 20 */
64 { false, "UNKNOWN", "Unknown Error" }, /* 21 */
65 { false, "UNKNOWN", "Unknown Error" }, /* 22 */
66 { false, "UNKNOWN", "Unknown Error" }, /* 23 */
67 { true, "FSMPES", "FSM State Parity Error" },
68 { false, "UNKNOWN", "Unknown Error" }, /* 25 */
69 { false, "UNKNOWN", "Unknown Error" }, /* 26 */
70 { false, "UNKNOWN", "Unknown Error" }, /* 27 */
71 { false, "UNKNOWN", "Unknown Error" }, /* 28 */
72 { false, "UNKNOWN", "Unknown Error" }, /* 29 */
73 { false, "UNKNOWN", "Unknown Error" }, /* 30 */
74 { false, "UNKNOWN", "Unknown Error" }, /* 31 */
77 static void dwmac5_handle_mac_err(struct net_device
*ndev
,
78 void __iomem
*ioaddr
, bool correctable
,
79 struct stmmac_safety_stats
*stats
)
83 value
= readl(ioaddr
+ MAC_DPP_FSM_INT_STATUS
);
84 writel(value
, ioaddr
+ MAC_DPP_FSM_INT_STATUS
);
86 dwmac5_log_error(ndev
, value
, correctable
, "MAC", dwmac5_mac_errors
,
87 STAT_OFF(mac_errors
), stats
);
90 static const struct dwmac5_error_desc dwmac5_mtl_errors
[32]= {
91 { true, "TXCES", "MTL TX Memory Error" },
92 { true, "TXAMS", "MTL TX Memory Address Mismatch Error" },
93 { true, "TXUES", "MTL TX Memory Error" },
94 { false, "UNKNOWN", "Unknown Error" }, /* 3 */
95 { true, "RXCES", "MTL RX Memory Error" },
96 { true, "RXAMS", "MTL RX Memory Address Mismatch Error" },
97 { true, "RXUES", "MTL RX Memory Error" },
98 { false, "UNKNOWN", "Unknown Error" }, /* 7 */
99 { true, "ECES", "MTL EST Memory Error" },
100 { true, "EAMS", "MTL EST Memory Address Mismatch Error" },
101 { true, "EUES", "MTL EST Memory Error" },
102 { false, "UNKNOWN", "Unknown Error" }, /* 11 */
103 { true, "RPCES", "MTL RX Parser Memory Error" },
104 { true, "RPAMS", "MTL RX Parser Memory Address Mismatch Error" },
105 { true, "RPUES", "MTL RX Parser Memory Error" },
106 { false, "UNKNOWN", "Unknown Error" }, /* 15 */
107 { false, "UNKNOWN", "Unknown Error" }, /* 16 */
108 { false, "UNKNOWN", "Unknown Error" }, /* 17 */
109 { false, "UNKNOWN", "Unknown Error" }, /* 18 */
110 { false, "UNKNOWN", "Unknown Error" }, /* 19 */
111 { false, "UNKNOWN", "Unknown Error" }, /* 20 */
112 { false, "UNKNOWN", "Unknown Error" }, /* 21 */
113 { false, "UNKNOWN", "Unknown Error" }, /* 22 */
114 { false, "UNKNOWN", "Unknown Error" }, /* 23 */
115 { false, "UNKNOWN", "Unknown Error" }, /* 24 */
116 { false, "UNKNOWN", "Unknown Error" }, /* 25 */
117 { false, "UNKNOWN", "Unknown Error" }, /* 26 */
118 { false, "UNKNOWN", "Unknown Error" }, /* 27 */
119 { false, "UNKNOWN", "Unknown Error" }, /* 28 */
120 { false, "UNKNOWN", "Unknown Error" }, /* 29 */
121 { false, "UNKNOWN", "Unknown Error" }, /* 30 */
122 { false, "UNKNOWN", "Unknown Error" }, /* 31 */
125 static void dwmac5_handle_mtl_err(struct net_device
*ndev
,
126 void __iomem
*ioaddr
, bool correctable
,
127 struct stmmac_safety_stats
*stats
)
131 value
= readl(ioaddr
+ MTL_ECC_INT_STATUS
);
132 writel(value
, ioaddr
+ MTL_ECC_INT_STATUS
);
134 dwmac5_log_error(ndev
, value
, correctable
, "MTL", dwmac5_mtl_errors
,
135 STAT_OFF(mtl_errors
), stats
);
138 static const struct dwmac5_error_desc dwmac5_dma_errors
[32]= {
139 { true, "TCES", "DMA TSO Memory Error" },
140 { true, "TAMS", "DMA TSO Memory Address Mismatch Error" },
141 { true, "TUES", "DMA TSO Memory Error" },
142 { false, "UNKNOWN", "Unknown Error" }, /* 3 */
143 { false, "UNKNOWN", "Unknown Error" }, /* 4 */
144 { false, "UNKNOWN", "Unknown Error" }, /* 5 */
145 { false, "UNKNOWN", "Unknown Error" }, /* 6 */
146 { false, "UNKNOWN", "Unknown Error" }, /* 7 */
147 { false, "UNKNOWN", "Unknown Error" }, /* 8 */
148 { false, "UNKNOWN", "Unknown Error" }, /* 9 */
149 { false, "UNKNOWN", "Unknown Error" }, /* 10 */
150 { false, "UNKNOWN", "Unknown Error" }, /* 11 */
151 { false, "UNKNOWN", "Unknown Error" }, /* 12 */
152 { false, "UNKNOWN", "Unknown Error" }, /* 13 */
153 { false, "UNKNOWN", "Unknown Error" }, /* 14 */
154 { false, "UNKNOWN", "Unknown Error" }, /* 15 */
155 { false, "UNKNOWN", "Unknown Error" }, /* 16 */
156 { false, "UNKNOWN", "Unknown Error" }, /* 17 */
157 { false, "UNKNOWN", "Unknown Error" }, /* 18 */
158 { false, "UNKNOWN", "Unknown Error" }, /* 19 */
159 { false, "UNKNOWN", "Unknown Error" }, /* 20 */
160 { false, "UNKNOWN", "Unknown Error" }, /* 21 */
161 { false, "UNKNOWN", "Unknown Error" }, /* 22 */
162 { false, "UNKNOWN", "Unknown Error" }, /* 23 */
163 { false, "UNKNOWN", "Unknown Error" }, /* 24 */
164 { false, "UNKNOWN", "Unknown Error" }, /* 25 */
165 { false, "UNKNOWN", "Unknown Error" }, /* 26 */
166 { false, "UNKNOWN", "Unknown Error" }, /* 27 */
167 { false, "UNKNOWN", "Unknown Error" }, /* 28 */
168 { false, "UNKNOWN", "Unknown Error" }, /* 29 */
169 { false, "UNKNOWN", "Unknown Error" }, /* 30 */
170 { false, "UNKNOWN", "Unknown Error" }, /* 31 */
173 static void dwmac5_handle_dma_err(struct net_device
*ndev
,
174 void __iomem
*ioaddr
, bool correctable
,
175 struct stmmac_safety_stats
*stats
)
179 value
= readl(ioaddr
+ DMA_ECC_INT_STATUS
);
180 writel(value
, ioaddr
+ DMA_ECC_INT_STATUS
);
182 dwmac5_log_error(ndev
, value
, correctable
, "DMA", dwmac5_dma_errors
,
183 STAT_OFF(dma_errors
), stats
);
186 int dwmac5_safety_feat_config(void __iomem
*ioaddr
, unsigned int asp
,
187 struct stmmac_safety_feature_cfg
*safety_feat_cfg
)
189 struct stmmac_safety_feature_cfg all_safety_feats
= {
205 if (!safety_feat_cfg
)
206 safety_feat_cfg
= &all_safety_feats
;
208 /* 1. Enable Safety Features */
209 value
= readl(ioaddr
+ MTL_ECC_CONTROL
);
210 value
|= MEEAO
; /* MTL ECC Error Addr Status Override */
211 if (safety_feat_cfg
->tsoee
)
212 value
|= TSOEE
; /* TSO ECC */
213 if (safety_feat_cfg
->mrxpee
)
214 value
|= MRXPEE
; /* MTL RX Parser ECC */
215 if (safety_feat_cfg
->mestee
)
216 value
|= MESTEE
; /* MTL EST ECC */
217 if (safety_feat_cfg
->mrxee
)
218 value
|= MRXEE
; /* MTL RX FIFO ECC */
219 if (safety_feat_cfg
->mtxee
)
220 value
|= MTXEE
; /* MTL TX FIFO ECC */
221 writel(value
, ioaddr
+ MTL_ECC_CONTROL
);
223 /* 2. Enable MTL Safety Interrupts */
224 value
= readl(ioaddr
+ MTL_ECC_INT_ENABLE
);
225 value
|= RPCEIE
; /* RX Parser Memory Correctable Error */
226 value
|= ECEIE
; /* EST Memory Correctable Error */
227 value
|= RXCEIE
; /* RX Memory Correctable Error */
228 value
|= TXCEIE
; /* TX Memory Correctable Error */
229 writel(value
, ioaddr
+ MTL_ECC_INT_ENABLE
);
231 /* 3. Enable DMA Safety Interrupts */
232 value
= readl(ioaddr
+ DMA_ECC_INT_ENABLE
);
233 value
|= TCEIE
; /* TSO Memory Correctable Error */
234 writel(value
, ioaddr
+ DMA_ECC_INT_ENABLE
);
236 /* Only ECC Protection for External Memory feature is selected */
240 /* 5. Enable Parity and Timeout for FSM */
241 value
= readl(ioaddr
+ MAC_FSM_CONTROL
);
242 if (safety_feat_cfg
->prtyen
)
243 value
|= PRTYEN
; /* FSM Parity Feature */
244 if (safety_feat_cfg
->tmouten
)
245 value
|= TMOUTEN
; /* FSM Timeout Feature */
246 writel(value
, ioaddr
+ MAC_FSM_CONTROL
);
248 /* 4. Enable Data Parity Protection */
249 value
= readl(ioaddr
+ MTL_DPP_CONTROL
);
250 if (safety_feat_cfg
->edpp
)
252 writel(value
, ioaddr
+ MTL_DPP_CONTROL
);
255 * All the Automotive Safety features are selected without the "Parity
256 * Port Enable for external interface" feature.
261 if (safety_feat_cfg
->epsi
)
263 writel(value
, ioaddr
+ MTL_DPP_CONTROL
);
267 int dwmac5_safety_feat_irq_status(struct net_device
*ndev
,
268 void __iomem
*ioaddr
, unsigned int asp
,
269 struct stmmac_safety_stats
*stats
)
278 mtl
= readl(ioaddr
+ MTL_SAFETY_INT_STATUS
);
279 dma
= readl(ioaddr
+ DMA_SAFETY_INT_STATUS
);
281 err
= (mtl
& MCSIS
) || (dma
& MCSIS
);
284 dwmac5_handle_mac_err(ndev
, ioaddr
, corr
, stats
);
288 err
= (mtl
& (MEUIS
| MECIS
)) || (dma
& (MSUIS
| MSCIS
));
289 corr
= (mtl
& MECIS
) || (dma
& MSCIS
);
291 dwmac5_handle_mtl_err(ndev
, ioaddr
, corr
, stats
);
295 err
= dma
& (DEUIS
| DECIS
);
298 dwmac5_handle_dma_err(ndev
, ioaddr
, corr
, stats
);
305 static const struct dwmac5_error
{
306 const struct dwmac5_error_desc
*desc
;
307 } dwmac5_all_errors
[] = {
308 { dwmac5_mac_errors
},
309 { dwmac5_mtl_errors
},
310 { dwmac5_dma_errors
},
313 int dwmac5_safety_feat_dump(struct stmmac_safety_stats
*stats
,
314 int index
, unsigned long *count
, const char **desc
)
316 int module
= index
/ 32, offset
= index
% 32;
317 unsigned long *ptr
= (unsigned long *)stats
;
319 if (module
>= ARRAY_SIZE(dwmac5_all_errors
))
321 if (!dwmac5_all_errors
[module
].desc
[offset
].valid
)
324 *count
= *(ptr
+ index
);
326 *desc
= dwmac5_all_errors
[module
].desc
[offset
].desc
;
330 static int dwmac5_rxp_disable(void __iomem
*ioaddr
)
334 val
= readl(ioaddr
+ MTL_OPERATION_MODE
);
336 writel(val
, ioaddr
+ MTL_OPERATION_MODE
);
338 return readl_poll_timeout(ioaddr
+ MTL_RXP_CONTROL_STATUS
, val
,
339 val
& RXPI
, 1, 10000);
342 static void dwmac5_rxp_enable(void __iomem
*ioaddr
)
346 val
= readl(ioaddr
+ MTL_OPERATION_MODE
);
348 writel(val
, ioaddr
+ MTL_OPERATION_MODE
);
351 static int dwmac5_rxp_update_single_entry(void __iomem
*ioaddr
,
352 struct stmmac_tc_entry
*entry
,
357 for (i
= 0; i
< (sizeof(entry
->val
) / sizeof(u32
)); i
++) {
358 int real_pos
= pos
* (sizeof(entry
->val
) / sizeof(u32
)) + i
;
362 ret
= readl_poll_timeout(ioaddr
+ MTL_RXP_IACC_CTRL_STATUS
,
363 val
, !(val
& STARTBUSY
), 1, 10000);
368 val
= *((u32
*)&entry
->val
+ i
);
369 writel(val
, ioaddr
+ MTL_RXP_IACC_DATA
);
372 val
= real_pos
& ADDR
;
373 writel(val
, ioaddr
+ MTL_RXP_IACC_CTRL_STATUS
);
377 writel(val
, ioaddr
+ MTL_RXP_IACC_CTRL_STATUS
);
381 writel(val
, ioaddr
+ MTL_RXP_IACC_CTRL_STATUS
);
384 ret
= readl_poll_timeout(ioaddr
+ MTL_RXP_IACC_CTRL_STATUS
,
385 val
, !(val
& STARTBUSY
), 1, 10000);
393 static struct stmmac_tc_entry
*
394 dwmac5_rxp_get_next_entry(struct stmmac_tc_entry
*entries
, unsigned int count
,
397 struct stmmac_tc_entry
*entry
;
402 for (i
= count
- 1; i
>= 0; i
--) {
405 /* Do not update unused entries */
408 /* Do not update already updated entries (i.e. fragments) */
411 /* Let last entry be updated last */
414 /* Do not return fragments */
417 /* Check if we already checked this prio */
418 if (entry
->prio
< curr_prio
)
420 /* Check if this is the minimum prio */
421 if (entry
->prio
< min_prio
) {
422 min_prio
= entry
->prio
;
429 return &entries
[min_prio_idx
];
433 int dwmac5_rxp_config(void __iomem
*ioaddr
, struct stmmac_tc_entry
*entries
,
436 struct stmmac_tc_entry
*entry
, *frag
;
441 /* Force disable RX */
442 old_val
= readl(ioaddr
+ GMAC_CONFIG
);
443 val
= old_val
& ~GMAC_CONFIG_RE
;
444 writel(val
, ioaddr
+ GMAC_CONFIG
);
446 /* Disable RX Parser */
447 ret
= dwmac5_rxp_disable(ioaddr
);
451 /* Set all entries as NOT in HW */
452 for (i
= 0; i
< count
; i
++) {
454 entry
->in_hw
= false;
457 /* Update entries by reverse order */
459 entry
= dwmac5_rxp_get_next_entry(entries
, count
, curr_prio
);
463 curr_prio
= entry
->prio
;
464 frag
= entry
->frag_ptr
;
466 /* Set special fragment requirements */
471 entry
->val
.ok_index
= nve
+ 2;
474 ret
= dwmac5_rxp_update_single_entry(ioaddr
, entry
, nve
);
478 entry
->table_pos
= nve
++;
481 if (frag
&& !frag
->in_hw
) {
482 ret
= dwmac5_rxp_update_single_entry(ioaddr
, frag
, nve
);
485 frag
->table_pos
= nve
++;
493 /* Update all pass entry */
494 for (i
= 0; i
< count
; i
++) {
499 ret
= dwmac5_rxp_update_single_entry(ioaddr
, entry
, nve
);
503 entry
->table_pos
= nve
++;
506 /* Assume n. of parsable entries == n. of valid entries */
507 val
= (nve
<< 16) & NPE
;
509 writel(val
, ioaddr
+ MTL_RXP_CONTROL_STATUS
);
511 /* Enable RX Parser */
512 dwmac5_rxp_enable(ioaddr
);
516 writel(old_val
, ioaddr
+ GMAC_CONFIG
);
520 int dwmac5_flex_pps_config(void __iomem
*ioaddr
, int index
,
521 struct stmmac_pps_cfg
*cfg
, bool enable
,
522 u32 sub_second_inc
, u32 systime_flags
)
524 u32 tnsec
= readl(ioaddr
+ MAC_PPSx_TARGET_TIME_NSEC(index
));
525 u32 val
= readl(ioaddr
+ MAC_PPS_CONTROL
);
530 if (tnsec
& TRGTBUSY0
)
532 if (!sub_second_inc
|| !systime_flags
)
535 val
&= ~PPSx_MASK(index
);
538 val
|= PPSCMDx(index
, 0x5);
540 writel(val
, ioaddr
+ MAC_PPS_CONTROL
);
544 val
|= TRGTMODSELx(index
, 0x2);
546 writel(val
, ioaddr
+ MAC_PPS_CONTROL
);
548 writel(cfg
->start
.tv_sec
, ioaddr
+ MAC_PPSx_TARGET_TIME_SEC(index
));
550 if (!(systime_flags
& PTP_TCR_TSCTRLSSR
))
551 cfg
->start
.tv_nsec
= (cfg
->start
.tv_nsec
* 1000) / 465;
552 writel(cfg
->start
.tv_nsec
, ioaddr
+ MAC_PPSx_TARGET_TIME_NSEC(index
));
554 period
= cfg
->period
.tv_sec
* 1000000000;
555 period
+= cfg
->period
.tv_nsec
;
557 do_div(period
, sub_second_inc
);
562 writel(period
- 1, ioaddr
+ MAC_PPSx_INTERVAL(index
));
568 writel(period
- 1, ioaddr
+ MAC_PPSx_WIDTH(index
));
570 /* Finally, activate it */
571 val
|= PPSCMDx(index
, 0x2);
572 writel(val
, ioaddr
+ MAC_PPS_CONTROL
);
576 static int dwmac5_est_write(void __iomem
*ioaddr
, u32 reg
, u32 val
, bool gcl
)
580 writel(val
, ioaddr
+ MTL_EST_GCL_DATA
);
582 ctrl
= (reg
<< ADDR_SHIFT
);
583 ctrl
|= gcl
? 0 : GCRR
;
585 writel(ctrl
, ioaddr
+ MTL_EST_GCL_CONTROL
);
588 writel(ctrl
, ioaddr
+ MTL_EST_GCL_CONTROL
);
590 return readl_poll_timeout(ioaddr
+ MTL_EST_GCL_CONTROL
,
591 ctrl
, !(ctrl
& SRWO
), 100, 5000);
594 int dwmac5_est_configure(void __iomem
*ioaddr
, struct stmmac_est
*cfg
,
595 unsigned int ptp_rate
)
600 ret
|= dwmac5_est_write(ioaddr
, BTR_LOW
, cfg
->btr
[0], false);
601 ret
|= dwmac5_est_write(ioaddr
, BTR_HIGH
, cfg
->btr
[1], false);
602 ret
|= dwmac5_est_write(ioaddr
, TER
, cfg
->ter
, false);
603 ret
|= dwmac5_est_write(ioaddr
, LLR
, cfg
->gcl_size
, false);
604 ret
|= dwmac5_est_write(ioaddr
, CTR_LOW
, cfg
->ctr
[0], false);
605 ret
|= dwmac5_est_write(ioaddr
, CTR_HIGH
, cfg
->ctr
[1], false);
609 for (i
= 0; i
< cfg
->gcl_size
; i
++) {
610 ret
= dwmac5_est_write(ioaddr
, i
, cfg
->gcl
[i
], true);
615 ctrl
= readl(ioaddr
+ MTL_EST_CONTROL
);
617 ctrl
|= ((1000000000 / ptp_rate
) * 6) << PTOV_SHIFT
;
623 writel(ctrl
, ioaddr
+ MTL_EST_CONTROL
);
625 /* Configure EST interrupt */
627 ctrl
= (IECGCE
| IEHS
| IEHF
| IEBE
| IECC
);
631 writel(ctrl
, ioaddr
+ MTL_EST_INT_EN
);
636 void dwmac5_est_irq_status(void __iomem
*ioaddr
, struct net_device
*dev
,
637 struct stmmac_extra_stats
*x
, u32 txqcnt
)
639 u32 status
, value
, feqn
, hbfq
, hbfs
, btrl
;
640 u32 txqcnt_mask
= (1 << txqcnt
) - 1;
642 status
= readl(ioaddr
+ MTL_EST_STATUS
);
644 value
= (CGCE
| HLBS
| HLBF
| BTRE
| SWLC
);
646 /* Return if there is no error */
647 if (!(status
& value
))
651 /* Clear Interrupt */
652 writel(CGCE
, ioaddr
+ MTL_EST_STATUS
);
658 value
= readl(ioaddr
+ MTL_EST_SCH_ERR
);
659 value
&= txqcnt_mask
;
663 /* Clear Interrupt */
664 writel(value
, ioaddr
+ MTL_EST_SCH_ERR
);
666 /* Collecting info to shows all the queues that has HLBS
667 * issue. The only way to clear this is to clear the
671 netdev_err(dev
, "EST: HLB(sched) Queue 0x%x\n", value
);
675 value
= readl(ioaddr
+ MTL_EST_FRM_SZ_ERR
);
676 feqn
= value
& txqcnt_mask
;
678 value
= readl(ioaddr
+ MTL_EST_FRM_SZ_CAP
);
679 hbfq
= (value
& SZ_CAP_HBFQ_MASK(txqcnt
)) >> SZ_CAP_HBFQ_SHIFT
;
680 hbfs
= value
& SZ_CAP_HBFS_MASK
;
684 /* Clear Interrupt */
685 writel(feqn
, ioaddr
+ MTL_EST_FRM_SZ_ERR
);
688 netdev_err(dev
, "EST: HLB(size) Queue %u Size %u\n",
693 if ((status
& BTRL
) == BTRL_MAX
)
698 btrl
= (status
& BTRL
) >> BTRL_SHIFT
;
701 netdev_info(dev
, "EST: BTR Error Loop Count %u\n",
704 writel(BTRE
, ioaddr
+ MTL_EST_STATUS
);
708 writel(SWLC
, ioaddr
+ MTL_EST_STATUS
);
709 netdev_info(dev
, "EST: SWOL has been switched\n");
713 void dwmac5_fpe_configure(void __iomem
*ioaddr
, u32 num_txq
, u32 num_rxq
,
719 value
= readl(ioaddr
+ MAC_FPE_CTRL_STS
);
723 writel(value
, ioaddr
+ MAC_FPE_CTRL_STS
);
727 value
= readl(ioaddr
+ GMAC_RXQ_CTRL1
);
728 value
&= ~GMAC_RXQCTRL_FPRQ
;
729 value
|= (num_rxq
- 1) << GMAC_RXQCTRL_FPRQ_SHIFT
;
730 writel(value
, ioaddr
+ GMAC_RXQ_CTRL1
);
732 value
= readl(ioaddr
+ MAC_FPE_CTRL_STS
);
734 writel(value
, ioaddr
+ MAC_FPE_CTRL_STS
);
737 int dwmac5_fpe_irq_status(void __iomem
*ioaddr
, struct net_device
*dev
)
742 status
= FPE_EVENT_UNKNOWN
;
744 value
= readl(ioaddr
+ MAC_FPE_CTRL_STS
);
747 status
|= FPE_EVENT_TRSP
;
748 netdev_info(dev
, "FPE: Respond mPacket is transmitted\n");
752 status
|= FPE_EVENT_TVER
;
753 netdev_info(dev
, "FPE: Verify mPacket is transmitted\n");
757 status
|= FPE_EVENT_RRSP
;
758 netdev_info(dev
, "FPE: Respond mPacket is received\n");
762 status
|= FPE_EVENT_RVER
;
763 netdev_info(dev
, "FPE: Verify mPacket is received\n");
769 void dwmac5_fpe_send_mpacket(void __iomem
*ioaddr
, enum stmmac_mpacket_type type
)
773 value
= readl(ioaddr
+ MAC_FPE_CTRL_STS
);
775 if (type
== MPACKET_VERIFY
) {
783 writel(value
, ioaddr
+ MAC_FPE_CTRL_STS
);