Skip to content

Commit 719655a

Browse files
lunndavem330
authored andcommitted
net: phy: Replace phy driver features u32 with link_mode bitmap
This is one step in allowing phylib to make use of link_mode bitmaps, instead of u32 for supported and advertised features. Convert the phy drivers to use bitmaps to indicates the features they support. Build bitmap equivalents of the u32 values at runtime, and have the drivers point to the appropriate bitmap. These bitmaps are shared, and we don't want a driver to modify them. So mark them __ro_after_init. Within phylib, the features bitmap is currently turned back into a u32. This will be removed once the whole of phylib, and the drivers are converted to use bitmaps. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d0939c2 commit 719655a

File tree

9 files changed

+198
-39
lines changed

9 files changed

+198
-39
lines changed

drivers/net/ethernet/marvell/pxa168_eth.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,8 @@ static int pxa168_init_phy(struct net_device *dev)
988988
cmd.base.phy_address = pep->phy_addr;
989989
cmd.base.speed = pep->phy_speed;
990990
cmd.base.duplex = pep->phy_duplex;
991-
ethtool_convert_legacy_u32_to_link_mode(cmd.link_modes.advertising,
992-
PHY_BASIC_FEATURES);
991+
bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES,
992+
__ETHTOOL_LINK_MODE_MASK_NBITS);
993993
cmd.base.autoneg = AUTONEG_ENABLE;
994994

995995
if (cmd.base.speed != 0)

drivers/net/phy/aquantia.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static struct phy_driver aquantia_driver[] = {
115115
.phy_id = PHY_ID_AQ1202,
116116
.phy_id_mask = 0xfffffff0,
117117
.name = "Aquantia AQ1202",
118-
.features = PHY_AQUANTIA_FEATURES,
118+
.features = PHY_10GBIT_FULL_FEATURES,
119119
.flags = PHY_HAS_INTERRUPT,
120120
.aneg_done = genphy_c45_aneg_done,
121121
.config_aneg = aquantia_config_aneg,
@@ -127,7 +127,7 @@ static struct phy_driver aquantia_driver[] = {
127127
.phy_id = PHY_ID_AQ2104,
128128
.phy_id_mask = 0xfffffff0,
129129
.name = "Aquantia AQ2104",
130-
.features = PHY_AQUANTIA_FEATURES,
130+
.features = PHY_10GBIT_FULL_FEATURES,
131131
.flags = PHY_HAS_INTERRUPT,
132132
.aneg_done = genphy_c45_aneg_done,
133133
.config_aneg = aquantia_config_aneg,
@@ -139,7 +139,7 @@ static struct phy_driver aquantia_driver[] = {
139139
.phy_id = PHY_ID_AQR105,
140140
.phy_id_mask = 0xfffffff0,
141141
.name = "Aquantia AQR105",
142-
.features = PHY_AQUANTIA_FEATURES,
142+
.features = PHY_10GBIT_FULL_FEATURES,
143143
.flags = PHY_HAS_INTERRUPT,
144144
.aneg_done = genphy_c45_aneg_done,
145145
.config_aneg = aquantia_config_aneg,
@@ -151,7 +151,7 @@ static struct phy_driver aquantia_driver[] = {
151151
.phy_id = PHY_ID_AQR106,
152152
.phy_id_mask = 0xfffffff0,
153153
.name = "Aquantia AQR106",
154-
.features = PHY_AQUANTIA_FEATURES,
154+
.features = PHY_10GBIT_FULL_FEATURES,
155155
.flags = PHY_HAS_INTERRUPT,
156156
.aneg_done = genphy_c45_aneg_done,
157157
.config_aneg = aquantia_config_aneg,
@@ -163,7 +163,7 @@ static struct phy_driver aquantia_driver[] = {
163163
.phy_id = PHY_ID_AQR107,
164164
.phy_id_mask = 0xfffffff0,
165165
.name = "Aquantia AQR107",
166-
.features = PHY_AQUANTIA_FEATURES,
166+
.features = PHY_10GBIT_FULL_FEATURES,
167167
.flags = PHY_HAS_INTERRUPT,
168168
.aneg_done = genphy_c45_aneg_done,
169169
.config_aneg = aquantia_config_aneg,
@@ -175,7 +175,7 @@ static struct phy_driver aquantia_driver[] = {
175175
.phy_id = PHY_ID_AQR405,
176176
.phy_id_mask = 0xfffffff0,
177177
.name = "Aquantia AQR405",
178-
.features = PHY_AQUANTIA_FEATURES,
178+
.features = PHY_10GBIT_FULL_FEATURES,
179179
.flags = PHY_HAS_INTERRUPT,
180180
.aneg_done = genphy_c45_aneg_done,
181181
.config_aneg = aquantia_config_aneg,

drivers/net/phy/bcm63xx.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ static int bcm63xx_config_init(struct phy_device *phydev)
4242
{
4343
int reg, err;
4444

45+
/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
46+
phydev->supported |= SUPPORTED_Pause;
47+
4548
reg = phy_read(phydev, MII_BCM63XX_IR);
4649
if (reg < 0)
4750
return reg;
@@ -65,8 +68,7 @@ static struct phy_driver bcm63xx_driver[] = {
6568
.phy_id = 0x00406000,
6669
.phy_id_mask = 0xfffffc00,
6770
.name = "Broadcom BCM63XX (1)",
68-
/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
69-
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
71+
.features = PHY_BASIC_FEATURES,
7072
.flags = PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
7173
.config_init = bcm63xx_config_init,
7274
.ack_interrupt = bcm_phy_ack_intr,
@@ -75,8 +77,7 @@ static struct phy_driver bcm63xx_driver[] = {
7577
/* same phy as above, with just a different OUI */
7678
.phy_id = 0x002bdc00,
7779
.phy_id_mask = 0xfffffc00,
78-
.name = "Broadcom BCM63XX (2)",
79-
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
80+
.features = PHY_BASIC_FEATURES,
8081
.flags = PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
8182
.config_init = bcm63xx_config_init,
8283
.ack_interrupt = bcm_phy_ack_intr,

drivers/net/phy/marvell.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,7 @@ static struct phy_driver marvell_drivers[] = {
22012201
.phy_id = MARVELL_PHY_ID_88E1510,
22022202
.phy_id_mask = MARVELL_PHY_ID_MASK,
22032203
.name = "Marvell 88E1510",
2204-
.features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE,
2204+
.features = PHY_GBIT_FIBRE_FEATURES,
22052205
.flags = PHY_HAS_INTERRUPT,
22062206
.probe = &m88e1510_probe,
22072207
.config_init = &m88e1510_config_init,

drivers/net/phy/marvell10g.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -535,16 +535,7 @@ static struct phy_driver mv3310_drivers[] = {
535535
.phy_id = 0x002b09aa,
536536
.phy_id_mask = MARVELL_PHY_ID_MASK,
537537
.name = "mv88x3310",
538-
.features = SUPPORTED_10baseT_Full |
539-
SUPPORTED_10baseT_Half |
540-
SUPPORTED_100baseT_Full |
541-
SUPPORTED_100baseT_Half |
542-
SUPPORTED_1000baseT_Full |
543-
SUPPORTED_Autoneg |
544-
SUPPORTED_TP |
545-
SUPPORTED_FIBRE |
546-
SUPPORTED_10000baseT_Full |
547-
SUPPORTED_Backplane,
538+
.features = PHY_10GBIT_FEATURES,
548539
.soft_reset = gen10g_no_soft_reset,
549540
.config_init = mv3310_config_init,
550541
.probe = mv3310_probe,

drivers/net/phy/microchip_t1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static struct phy_driver microchip_t1_phy_driver[] = {
4646
.phy_id_mask = 0xfffffff0,
4747
.name = "Microchip LAN87xx T1",
4848

49-
.features = SUPPORTED_100baseT_Full,
49+
.features = PHY_BASIC_T1_FEATURES,
5050
.flags = PHY_HAS_INTERRUPT,
5151

5252
.config_init = genphy_config_init,

drivers/net/phy/phy_device.c

Lines changed: 157 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/module.h>
3030
#include <linux/mii.h>
3131
#include <linux/ethtool.h>
32+
#include <linux/bitmap.h>
3233
#include <linux/phy.h>
3334
#include <linux/phy_led_triggers.h>
3435
#include <linux/mdio.h>
@@ -42,6 +43,149 @@ MODULE_DESCRIPTION("PHY library");
4243
MODULE_AUTHOR("Andy Fleming");
4344
MODULE_LICENSE("GPL");
4445

46+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
47+
EXPORT_SYMBOL_GPL(phy_basic_features);
48+
49+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
50+
EXPORT_SYMBOL_GPL(phy_basic_t1_features);
51+
52+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
53+
EXPORT_SYMBOL_GPL(phy_gbit_features);
54+
55+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
56+
EXPORT_SYMBOL_GPL(phy_gbit_fibre_features);
57+
58+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
59+
EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features);
60+
61+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
62+
EXPORT_SYMBOL_GPL(phy_10gbit_features);
63+
64+
static const int phy_basic_ports_array[] = {
65+
ETHTOOL_LINK_MODE_Autoneg_BIT,
66+
ETHTOOL_LINK_MODE_TP_BIT,
67+
ETHTOOL_LINK_MODE_MII_BIT,
68+
};
69+
70+
static const int phy_fibre_port_array[] = {
71+
ETHTOOL_LINK_MODE_FIBRE_BIT,
72+
};
73+
74+
static const int phy_all_ports_features_array[] = {
75+
ETHTOOL_LINK_MODE_Autoneg_BIT,
76+
ETHTOOL_LINK_MODE_TP_BIT,
77+
ETHTOOL_LINK_MODE_MII_BIT,
78+
ETHTOOL_LINK_MODE_FIBRE_BIT,
79+
ETHTOOL_LINK_MODE_AUI_BIT,
80+
ETHTOOL_LINK_MODE_BNC_BIT,
81+
ETHTOOL_LINK_MODE_Backplane_BIT,
82+
};
83+
84+
static const int phy_10_100_features_array[] = {
85+
ETHTOOL_LINK_MODE_10baseT_Half_BIT,
86+
ETHTOOL_LINK_MODE_10baseT_Full_BIT,
87+
ETHTOOL_LINK_MODE_100baseT_Half_BIT,
88+
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
89+
};
90+
91+
static const int phy_basic_t1_features_array[] = {
92+
ETHTOOL_LINK_MODE_TP_BIT,
93+
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
94+
};
95+
96+
static const int phy_gbit_features_array[] = {
97+
ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
98+
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
99+
};
100+
101+
static const int phy_10gbit_features_array[] = {
102+
ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
103+
};
104+
105+
__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
106+
EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
107+
108+
static const int phy_10gbit_full_features_array[] = {
109+
ETHTOOL_LINK_MODE_10baseT_Full_BIT,
110+
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
111+
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
112+
ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
113+
};
114+
115+
static void features_init(void)
116+
{
117+
/* 10/100 half/full*/
118+
linkmode_set_bit_array(phy_basic_ports_array,
119+
ARRAY_SIZE(phy_basic_ports_array),
120+
phy_basic_features);
121+
linkmode_set_bit_array(phy_10_100_features_array,
122+
ARRAY_SIZE(phy_10_100_features_array),
123+
phy_basic_features);
124+
125+
/* 100 full, TP */
126+
linkmode_set_bit_array(phy_basic_t1_features_array,
127+
ARRAY_SIZE(phy_basic_t1_features_array),
128+
phy_basic_t1_features);
129+
130+
/* 10/100 half/full + 1000 half/full */
131+
linkmode_set_bit_array(phy_basic_ports_array,
132+
ARRAY_SIZE(phy_basic_ports_array),
133+
phy_gbit_features);
134+
linkmode_set_bit_array(phy_10_100_features_array,
135+
ARRAY_SIZE(phy_10_100_features_array),
136+
phy_gbit_features);
137+
linkmode_set_bit_array(phy_gbit_features_array,
138+
ARRAY_SIZE(phy_gbit_features_array),
139+
phy_gbit_features);
140+
141+
/* 10/100 half/full + 1000 half/full + fibre*/
142+
linkmode_set_bit_array(phy_basic_ports_array,
143+
ARRAY_SIZE(phy_basic_ports_array),
144+
phy_gbit_fibre_features);
145+
linkmode_set_bit_array(phy_10_100_features_array,
146+
ARRAY_SIZE(phy_10_100_features_array),
147+
phy_gbit_fibre_features);
148+
linkmode_set_bit_array(phy_gbit_features_array,
149+
ARRAY_SIZE(phy_gbit_features_array),
150+
phy_gbit_fibre_features);
151+
linkmode_set_bit_array(phy_fibre_port_array,
152+
ARRAY_SIZE(phy_fibre_port_array),
153+
phy_gbit_fibre_features);
154+
155+
/* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/
156+
linkmode_set_bit_array(phy_all_ports_features_array,
157+
ARRAY_SIZE(phy_all_ports_features_array),
158+
phy_gbit_all_ports_features);
159+
linkmode_set_bit_array(phy_10_100_features_array,
160+
ARRAY_SIZE(phy_10_100_features_array),
161+
phy_gbit_all_ports_features);
162+
linkmode_set_bit_array(phy_gbit_features_array,
163+
ARRAY_SIZE(phy_gbit_features_array),
164+
phy_gbit_all_ports_features);
165+
166+
/* 10/100 half/full + 1000 half/full + 10G full*/
167+
linkmode_set_bit_array(phy_all_ports_features_array,
168+
ARRAY_SIZE(phy_all_ports_features_array),
169+
phy_10gbit_features);
170+
linkmode_set_bit_array(phy_10_100_features_array,
171+
ARRAY_SIZE(phy_10_100_features_array),
172+
phy_10gbit_features);
173+
linkmode_set_bit_array(phy_gbit_features_array,
174+
ARRAY_SIZE(phy_gbit_features_array),
175+
phy_10gbit_features);
176+
linkmode_set_bit_array(phy_10gbit_features_array,
177+
ARRAY_SIZE(phy_10gbit_features_array),
178+
phy_10gbit_features);
179+
180+
/* 10/100/1000/10G full */
181+
linkmode_set_bit_array(phy_all_ports_features_array,
182+
ARRAY_SIZE(phy_all_ports_features_array),
183+
phy_10gbit_full_features);
184+
linkmode_set_bit_array(phy_10gbit_full_features_array,
185+
ARRAY_SIZE(phy_10gbit_full_features_array),
186+
phy_10gbit_full_features);
187+
}
188+
45189
void phy_device_free(struct phy_device *phydev)
46190
{
47191
put_device(&phydev->mdio.dev);
@@ -1936,6 +2080,7 @@ static int phy_probe(struct device *dev)
19362080
struct phy_device *phydev = to_phy_device(dev);
19372081
struct device_driver *drv = phydev->mdio.dev.driver;
19382082
struct phy_driver *phydrv = to_phy_driver(drv);
2083+
u32 features;
19392084
int err = 0;
19402085

19412086
phydev->drv = phydrv;
@@ -1956,7 +2101,8 @@ static int phy_probe(struct device *dev)
19562101
* a controller will attach, and may modify one
19572102
* or both of these values
19582103
*/
1959-
phydev->supported = phydrv->features;
2104+
ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features);
2105+
phydev->supported = features;
19602106
of_set_phy_supported(phydev);
19612107
phydev->advertising = phydev->supported;
19622108

@@ -1976,10 +2122,14 @@ static int phy_probe(struct device *dev)
19762122
* (e.g. hardware erratum) where the driver wants to set only one
19772123
* of these bits.
19782124
*/
1979-
if (phydrv->features & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)) {
2125+
if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) ||
2126+
test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) {
19802127
phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
1981-
phydev->supported |= phydrv->features &
1982-
(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
2128+
if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
2129+
phydev->supported |= SUPPORTED_Pause;
2130+
if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2131+
phydrv->features))
2132+
phydev->supported |= SUPPORTED_Asym_Pause;
19832133
} else {
19842134
phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
19852135
}
@@ -2092,9 +2242,7 @@ static struct phy_driver genphy_driver = {
20922242
.name = "Generic PHY",
20932243
.soft_reset = genphy_no_soft_reset,
20942244
.config_init = genphy_config_init,
2095-
.features = PHY_GBIT_FEATURES | SUPPORTED_MII |
2096-
SUPPORTED_AUI | SUPPORTED_FIBRE |
2097-
SUPPORTED_BNC,
2245+
.features = PHY_GBIT_ALL_PORTS_FEATURES,
20982246
.aneg_done = genphy_aneg_done,
20992247
.suspend = genphy_suspend,
21002248
.resume = genphy_resume,
@@ -2109,6 +2257,8 @@ static int __init phy_init(void)
21092257
if (rc)
21102258
return rc;
21112259

2260+
features_init();
2261+
21122262
rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE);
21132263
if (rc)
21142264
goto err_10g;

include/linux/linkmode.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ static inline void linkmode_set_bit(int nr, volatile unsigned long *addr)
4343
__set_bit(nr, addr);
4444
}
4545

46+
static inline void linkmode_set_bit_array(const int *array, int array_size,
47+
unsigned long *addr)
48+
{
49+
int i;
50+
51+
for (i = 0; i < array_size; i++)
52+
linkmode_set_bit(array[i], addr);
53+
}
54+
4655
static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr)
4756
{
4857
__clear_bit(nr, addr);

include/linux/phy.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,21 @@
4242
#define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \
4343
SUPPORTED_1000baseT_Full)
4444

45-
#define PHY_BASIC_FEATURES (PHY_10BT_FEATURES | \
46-
PHY_100BT_FEATURES | \
47-
PHY_DEFAULT_FEATURES)
48-
49-
#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
50-
PHY_1000BT_FEATURES)
51-
45+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
46+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
47+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
48+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
49+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
50+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
51+
extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
52+
53+
#define PHY_BASIC_FEATURES ((unsigned long *)&phy_basic_features)
54+
#define PHY_BASIC_T1_FEATURES ((unsigned long *)&phy_basic_t1_features)
55+
#define PHY_GBIT_FEATURES ((unsigned long *)&phy_gbit_features)
56+
#define PHY_GBIT_FIBRE_FEATURES ((unsigned long *)&phy_gbit_fibre_features)
57+
#define PHY_GBIT_ALL_PORTS_FEATURES ((unsigned long *)&phy_gbit_all_ports_features)
58+
#define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features)
59+
#define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features)
5260

5361
/*
5462
* Set phydev->irq to PHY_POLL if interrupts are not supported,
@@ -510,7 +518,7 @@ struct phy_driver {
510518
u32 phy_id;
511519
char *name;
512520
u32 phy_id_mask;
513-
u32 features;
521+
const unsigned long * const features;
514522
u32 flags;
515523
const void *driver_data;
516524

0 commit comments

Comments
 (0)