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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
From e0f33a88243329da1aa5a90fe10ab25c9fb0a091 Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@arm.linux.org.uk>
Date: Sun, 20 Sep 2015 11:28:39 +0100
Subject: [PATCH 712/744] phy: generate swphy registers on the fly
Generate software phy registers as and when requested, rather than
duplicating the state in fixed_phy. This allows us to eliminate
the duplicate storage of of the same data, which is only different
in format.
As fixed_phy_update_regs() no longer updates register state, rename
it to fixed_phy_update().
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
drivers/net/phy/fixed_phy.c | 31 +++++-------------------------
drivers/net/phy/swphy.c | 47 ++++++++++++++++++++++++++++++++-------------
drivers/net/phy/swphy.h | 2 +-
3 files changed, 40 insertions(+), 40 deletions(-)
--- a/drivers/net/phy/fixed_phy.c
+++ b/drivers/net/phy/fixed_phy.c
@@ -26,8 +26,6 @@
#include "swphy.h"
-#define MII_REGS_NUM 29
-
struct fixed_mdio_bus {
int irqs[PHY_MAX_ADDR];
struct mii_bus *mii_bus;
@@ -36,7 +34,6 @@ struct fixed_mdio_bus {
struct fixed_phy {
int addr;
- u16 regs[MII_REGS_NUM];
struct phy_device *phydev;
struct fixed_phy_status status;
int (*link_update)(struct net_device *, struct fixed_phy_status *);
@@ -49,12 +46,10 @@ static struct fixed_mdio_bus platform_fm
.phys = LIST_HEAD_INIT(platform_fmb.phys),
};
-static void fixed_phy_update_regs(struct fixed_phy *fp)
+static void fixed_phy_update(struct fixed_phy *fp)
{
if (gpio_is_valid(fp->link_gpio))
fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
-
- swphy_update_regs(fp->regs, &fp->status);
}
static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
@@ -62,29 +57,15 @@ static int fixed_mdio_read(struct mii_bu
struct fixed_mdio_bus *fmb = bus->priv;
struct fixed_phy *fp;
- if (reg_num >= MII_REGS_NUM)
- return -1;
-
- /* We do not support emulating Clause 45 over Clause 22 register reads
- * return an error instead of bogus data.
- */
- switch (reg_num) {
- case MII_MMD_CTRL:
- case MII_MMD_DATA:
- return -1;
- default:
- break;
- }
-
list_for_each_entry(fp, &fmb->phys, node) {
if (fp->addr == phy_addr) {
/* Issue callback if user registered it. */
if (fp->link_update) {
fp->link_update(fp->phydev->attached_dev,
&fp->status);
- fixed_phy_update_regs(fp);
+ fixed_phy_update(fp);
}
- return fp->regs[reg_num];
+ return swphy_read_reg(reg_num, &fp->status);
}
}
@@ -144,7 +125,7 @@ int fixed_phy_update_state(struct phy_de
_UPD(pause);
_UPD(asym_pause);
#undef _UPD
- fixed_phy_update_regs(fp);
+ fixed_phy_update(fp);
return 0;
}
}
@@ -169,8 +150,6 @@ int fixed_phy_add(unsigned int irq, int
if (!fp)
return -ENOMEM;
- memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM);
-
fmb->irqs[phy_addr] = irq;
fp->addr = phy_addr;
@@ -184,7 +163,7 @@ int fixed_phy_add(unsigned int irq, int
goto err_regs;
}
- fixed_phy_update_regs(fp);
+ fixed_phy_update(fp);
list_add_tail(&fp->node, &fmb->phys);
--- a/drivers/net/phy/swphy.c
+++ b/drivers/net/phy/swphy.c
@@ -20,6 +20,8 @@
#include "swphy.h"
+#define MII_REGS_NUM 29
+
struct swmii_regs {
u16 bmcr;
u16 bmsr;
@@ -110,14 +112,13 @@ int swphy_validate_state(const struct fi
EXPORT_SYMBOL_GPL(swphy_validate_state);
/**
- * swphy_update_regs - update MII register array with fixed phy state
- * @regs: array of 32 registers to update
+ * swphy_read_reg - return a MII register from the fixed phy state
+ * @reg: MII register
* @state: fixed phy status
*
- * Update the array of MII registers with the fixed phy link, speed,
- * duplex and pause mode settings.
+ * Return the MII @reg register generated from the fixed phy state @state.
*/
-void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
+int swphy_read_reg(int reg, const struct fixed_phy_status *state)
{
int speed_index, duplex_index;
u16 bmsr = BMSR_ANEGCAPABLE;
@@ -125,9 +126,12 @@ void swphy_update_regs(u16 *regs, const
u16 lpagb = 0;
u16 lpa = 0;
+ if (reg > MII_REGS_NUM)
+ return -1;
+
speed_index = swphy_decode_speed(state->speed);
if (WARN_ON(speed_index < 0))
- return;
+ return 0;
duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
@@ -147,12 +151,29 @@ void swphy_update_regs(u16 *regs, const
lpa |= LPA_PAUSE_ASYM;
}
- regs[MII_PHYSID1] = 0;
- regs[MII_PHYSID2] = 0;
+ switch (reg) {
+ case MII_BMCR:
+ return bmcr;
+ case MII_BMSR:
+ return bmsr;
+ case MII_PHYSID1:
+ case MII_PHYSID2:
+ return 0;
+ case MII_LPA:
+ return lpa;
+ case MII_STAT1000:
+ return lpagb;
+
+ /*
+ * We do not support emulating Clause 45 over Clause 22 register
+ * reads. Return an error instead of bogus data.
+ */
+ case MII_MMD_CTRL:
+ case MII_MMD_DATA:
+ return -1;
- regs[MII_BMSR] = bmsr;
- regs[MII_BMCR] = bmcr;
- regs[MII_LPA] = lpa;
- regs[MII_STAT1000] = lpagb;
+ default:
+ return 0xffff;
+ }
}
-EXPORT_SYMBOL_GPL(swphy_update_regs);
+EXPORT_SYMBOL_GPL(swphy_read_reg);
--- a/drivers/net/phy/swphy.h
+++ b/drivers/net/phy/swphy.h
@@ -4,6 +4,6 @@
struct fixed_phy_status;
int swphy_validate_state(const struct fixed_phy_status *state);
-void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
+int swphy_read_reg(int reg, const struct fixed_phy_status *state);
#endif
|