xref: /linux/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h (revision 8e1bb4a41aa78d6105e59186af3dcd545fc66e70)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * stmmac_pcs.h: Physical Coding Sublayer Header File
4  *
5  * Copyright (C) 2016 STMicroelectronics (R&D) Limited
6  * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
7  */
8 
9 #ifndef __STMMAC_PCS_H__
10 #define __STMMAC_PCS_H__
11 
12 #include <linux/slab.h>
13 #include <linux/io.h>
14 #include "common.h"
15 
16 /* PCS registers (AN/TBI/SGMII/RGMII) offsets */
17 #define GMAC_AN_CTRL(x)		(x)		/* AN control */
18 #define GMAC_AN_STATUS(x)	(x + 0x4)	/* AN status */
19 #define GMAC_ANE_ADV(x)		(x + 0x8)	/* ANE Advertisement */
20 #define GMAC_ANE_LPA(x)		(x + 0xc)	/* ANE link partener ability */
21 #define GMAC_ANE_EXP(x)		(x + 0x10)	/* ANE expansion */
22 #define GMAC_TBI(x)		(x + 0x14)	/* TBI extend status */
23 
24 /* AN Configuration defines */
25 #define GMAC_AN_CTRL_RAN	BIT(9)	/* Restart Auto-Negotiation */
26 #define GMAC_AN_CTRL_ANE	BIT(12)	/* Auto-Negotiation Enable */
27 #define GMAC_AN_CTRL_ELE	BIT(14)	/* External Loopback Enable */
28 #define GMAC_AN_CTRL_ECD	BIT(16)	/* Enable Comma Detect */
29 #define GMAC_AN_CTRL_LR		BIT(17)	/* Lock to Reference */
30 #define GMAC_AN_CTRL_SGMRAL	BIT(18)	/* SGMII RAL Control */
31 
32 /* AN Status defines */
33 #define GMAC_AN_STATUS_LS	BIT(2)	/* Link Status 0:down 1:up */
34 #define GMAC_AN_STATUS_ANA	BIT(3)	/* Auto-Negotiation Ability */
35 #define GMAC_AN_STATUS_ANC	BIT(5)	/* Auto-Negotiation Complete */
36 #define GMAC_AN_STATUS_ES	BIT(8)	/* Extended Status */
37 
38 /* ADV and LPA defines */
39 #define GMAC_ANE_FD		BIT(5)
40 #define GMAC_ANE_HD		BIT(6)
41 #define GMAC_ANE_PSE		GENMASK(8, 7)
42 #define GMAC_ANE_PSE_SHIFT	7
43 #define GMAC_ANE_RFE		GENMASK(13, 12)
44 #define GMAC_ANE_RFE_SHIFT	12
45 #define GMAC_ANE_ACK		BIT(14)
46 
47 /**
48  * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR
49  * @ioaddr: IO registers pointer
50  * @reg: Base address of the AN Control Register.
51  * @intr_status: GMAC core interrupt status
52  * @x: pointer to log these events as stats
53  * Description: it is the ISR for PCS events: Auto-Negotiation Completed and
54  * Link status.
55  */
56 static inline void dwmac_pcs_isr(void __iomem *ioaddr, u32 reg,
57 				 unsigned int intr_status,
58 				 struct stmmac_extra_stats *x)
59 {
60 	u32 val = readl(ioaddr + GMAC_AN_STATUS(reg));
61 
62 	if (intr_status & PCS_ANE_IRQ) {
63 		x->irq_pcs_ane_n++;
64 		if (val & GMAC_AN_STATUS_ANC)
65 			pr_info("stmmac_pcs: ANE process completed\n");
66 	}
67 
68 	if (intr_status & PCS_LINK_IRQ) {
69 		x->irq_pcs_link_n++;
70 		if (val & GMAC_AN_STATUS_LS)
71 			pr_info("stmmac_pcs: Link Up\n");
72 		else
73 			pr_info("stmmac_pcs: Link Down\n");
74 	}
75 }
76 
77 /**
78  * dwmac_ctrl_ane - To program the AN Control Register.
79  * @ioaddr: IO registers pointer
80  * @reg: Base address of the AN Control Register.
81  * @ane: to enable the auto-negotiation
82  * @srgmi_ral: to manage MAC-2-MAC SGMII connections.
83  * @loopback: to cause the PHY to loopback tx data into rx path.
84  * Description: this is the main function to configure the AN control register
85  * and init the ANE, select loopback (usually for debugging purpose) and
86  * configure SGMII RAL.
87  */
88 static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
89 				  bool srgmi_ral, bool loopback)
90 {
91 	u32 value = readl(ioaddr + GMAC_AN_CTRL(reg));
92 
93 	/* Enable and restart the Auto-Negotiation */
94 	if (ane)
95 		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
96 	else
97 		value &= ~GMAC_AN_CTRL_ANE;
98 
99 	/* In case of MAC-2-MAC connection, block is configured to operate
100 	 * according to MAC conf register.
101 	 */
102 	if (srgmi_ral)
103 		value |= GMAC_AN_CTRL_SGMRAL;
104 
105 	if (loopback)
106 		value |= GMAC_AN_CTRL_ELE;
107 
108 	writel(value, ioaddr + GMAC_AN_CTRL(reg));
109 }
110 
111 /**
112  * dwmac_get_adv_lp - Get ADV and LP cap
113  * @ioaddr: IO registers pointer
114  * @reg: Base address of the AN Control Register.
115  * @adv_lp: structure to store the adv,lp status
116  * Description: this is to expose the ANE advertisement and Link partner ability
117  * status to ethtool support.
118  */
119 static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg,
120 				    struct rgmii_adv *adv_lp)
121 {
122 	u32 value = readl(ioaddr + GMAC_ANE_ADV(reg));
123 
124 	if (value & GMAC_ANE_FD)
125 		adv_lp->duplex = DUPLEX_FULL;
126 	if (value & GMAC_ANE_HD)
127 		adv_lp->duplex |= DUPLEX_HALF;
128 
129 	adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
130 
131 	value = readl(ioaddr + GMAC_ANE_LPA(reg));
132 
133 	if (value & GMAC_ANE_FD)
134 		adv_lp->lp_duplex = DUPLEX_FULL;
135 	if (value & GMAC_ANE_HD)
136 		adv_lp->lp_duplex = DUPLEX_HALF;
137 
138 	adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
139 }
140 #endif /* __STMMAC_PCS_H__ */
141