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