Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_pcs.h
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_rane - To restart ANE
79  * @ioaddr: IO registers pointer
80  * @reg: Base address of the AN Control Register.
81  * @restart: to restart ANE
82  * Description: this is to just restart the Auto-Negotiation.
83  */
84 static inline void dwmac_rane(void __iomem *ioaddr, u32 reg, bool restart)
85 {
86         u32 value = readl(ioaddr + GMAC_AN_CTRL(reg));
87
88         if (restart)
89                 value |= GMAC_AN_CTRL_RAN;
90
91         writel(value, ioaddr + GMAC_AN_CTRL(reg));
92 }
93
94 /**
95  * dwmac_ctrl_ane - To program the AN Control Register.
96  * @ioaddr: IO registers pointer
97  * @reg: Base address of the AN Control Register.
98  * @ane: to enable the auto-negotiation
99  * @srgmi_ral: to manage MAC-2-MAC SGMII connections.
100  * @loopback: to cause the PHY to loopback tx data into rx path.
101  * Description: this is the main function to configure the AN control register
102  * and init the ANE, select loopback (usually for debugging purpose) and
103  * configure SGMII RAL.
104  */
105 static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
106                                   bool srgmi_ral, bool loopback)
107 {
108         u32 value = readl(ioaddr + GMAC_AN_CTRL(reg));
109
110         /* Enable and restart the Auto-Negotiation */
111         if (ane)
112                 value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
113
114         /* In case of MAC-2-MAC connection, block is configured to operate
115          * according to MAC conf register.
116          */
117         if (srgmi_ral)
118                 value |= GMAC_AN_CTRL_SGMRAL;
119
120         if (loopback)
121                 value |= GMAC_AN_CTRL_ELE;
122
123         writel(value, ioaddr + GMAC_AN_CTRL(reg));
124 }
125
126 /**
127  * dwmac_get_adv_lp - Get ADV and LP cap
128  * @ioaddr: IO registers pointer
129  * @reg: Base address of the AN Control Register.
130  * @adv_lp: structure to store the adv,lp status
131  * Description: this is to expose the ANE advertisement and Link partner ability
132  * status to ethtool support.
133  */
134 static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg,
135                                     struct rgmii_adv *adv_lp)
136 {
137         u32 value = readl(ioaddr + GMAC_ANE_ADV(reg));
138
139         if (value & GMAC_ANE_FD)
140                 adv_lp->duplex = DUPLEX_FULL;
141         if (value & GMAC_ANE_HD)
142                 adv_lp->duplex |= DUPLEX_HALF;
143
144         adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
145
146         value = readl(ioaddr + GMAC_ANE_LPA(reg));
147
148         if (value & GMAC_ANE_FD)
149                 adv_lp->lp_duplex = DUPLEX_FULL;
150         if (value & GMAC_ANE_HD)
151                 adv_lp->lp_duplex = DUPLEX_HALF;
152
153         adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
154 }
155 #endif /* __STMMAC_PCS_H__ */