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 */
56static 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(addr: 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 */
84static inline void dwmac_rane(void __iomem *ioaddr, u32 reg, bool restart)
85{
86 u32 value = readl(addr: ioaddr + GMAC_AN_CTRL(reg));
87
88 if (restart)
89 value |= GMAC_AN_CTRL_RAN;
90
91 writel(val: value, addr: 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 */
105static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,
106 bool srgmi_ral, bool loopback)
107{
108 u32 value = readl(addr: 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 else
114 value &= ~GMAC_AN_CTRL_ANE;
115
116 /* In case of MAC-2-MAC connection, block is configured to operate
117 * according to MAC conf register.
118 */
119 if (srgmi_ral)
120 value |= GMAC_AN_CTRL_SGMRAL;
121
122 if (loopback)
123 value |= GMAC_AN_CTRL_ELE;
124
125 writel(val: value, addr: ioaddr + GMAC_AN_CTRL(reg));
126}
127
128/**
129 * dwmac_get_adv_lp - Get ADV and LP cap
130 * @ioaddr: IO registers pointer
131 * @reg: Base address of the AN Control Register.
132 * @adv_lp: structure to store the adv,lp status
133 * Description: this is to expose the ANE advertisement and Link partner ability
134 * status to ethtool support.
135 */
136static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg,
137 struct rgmii_adv *adv_lp)
138{
139 u32 value = readl(addr: ioaddr + GMAC_ANE_ADV(reg));
140
141 if (value & GMAC_ANE_FD)
142 adv_lp->duplex = DUPLEX_FULL;
143 if (value & GMAC_ANE_HD)
144 adv_lp->duplex |= DUPLEX_HALF;
145
146 adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
147
148 value = readl(addr: ioaddr + GMAC_ANE_LPA(reg));
149
150 if (value & GMAC_ANE_FD)
151 adv_lp->lp_duplex = DUPLEX_FULL;
152 if (value & GMAC_ANE_HD)
153 adv_lp->lp_duplex = DUPLEX_HALF;
154
155 adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
156}
157#endif /* __STMMAC_PCS_H__ */
158

source code of linux/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h