Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: b53: convert to phylink_pcs

Convert B53 to use phylink_pcs for the serdes rather than hooking it
into the MAC-layer callbacks.

Fixes: 81c1681cbb9f ("net: dsa: b53: mark as non-legacy")
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Russell King (Oracle) and committed by
David S. Miller
79396934 6b292a04

+75 -72
+7 -29
drivers/net/dsa/b53/b53_common.c
··· 1354 1354 config->legacy_pre_march2020 = false; 1355 1355 } 1356 1356 1357 - int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, 1358 - struct phylink_link_state *state) 1357 + static struct phylink_pcs *b53_phylink_mac_select_pcs(struct dsa_switch *ds, 1358 + int port, 1359 + phy_interface_t interface) 1359 1360 { 1360 1361 struct b53_device *dev = ds->priv; 1361 - int ret = -EOPNOTSUPP; 1362 1362 1363 - if ((phy_interface_mode_is_8023z(state->interface) || 1364 - state->interface == PHY_INTERFACE_MODE_SGMII) && 1365 - dev->ops->serdes_link_state) 1366 - ret = dev->ops->serdes_link_state(dev, port, state); 1363 + if (!dev->ops->phylink_mac_select_pcs) 1364 + return NULL; 1367 1365 1368 - return ret; 1366 + return dev->ops->phylink_mac_select_pcs(dev, port, interface); 1369 1367 } 1370 - EXPORT_SYMBOL(b53_phylink_mac_link_state); 1371 1368 1372 1369 void b53_phylink_mac_config(struct dsa_switch *ds, int port, 1373 1370 unsigned int mode, 1374 1371 const struct phylink_link_state *state) 1375 1372 { 1376 - struct b53_device *dev = ds->priv; 1377 - 1378 - if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) 1379 - return; 1380 - 1381 - if ((phy_interface_mode_is_8023z(state->interface) || 1382 - state->interface == PHY_INTERFACE_MODE_SGMII) && 1383 - dev->ops->serdes_config) 1384 - dev->ops->serdes_config(dev, port, mode, state); 1385 1373 } 1386 1374 EXPORT_SYMBOL(b53_phylink_mac_config); 1387 - 1388 - void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port) 1389 - { 1390 - struct b53_device *dev = ds->priv; 1391 - 1392 - if (dev->ops->serdes_an_restart) 1393 - dev->ops->serdes_an_restart(dev, port); 1394 - } 1395 - EXPORT_SYMBOL(b53_phylink_mac_an_restart); 1396 1375 1397 1376 void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, 1398 1377 unsigned int mode, ··· 2248 2269 .phy_write = b53_phy_write16, 2249 2270 .adjust_link = b53_adjust_link, 2250 2271 .phylink_get_caps = b53_phylink_get_caps, 2251 - .phylink_mac_link_state = b53_phylink_mac_link_state, 2272 + .phylink_mac_select_pcs = b53_phylink_mac_select_pcs, 2252 2273 .phylink_mac_config = b53_phylink_mac_config, 2253 - .phylink_mac_an_restart = b53_phylink_mac_an_restart, 2254 2274 .phylink_mac_link_down = b53_phylink_mac_link_down, 2255 2275 .phylink_mac_link_up = b53_phylink_mac_link_up, 2256 2276 .port_enable = b53_enable_port,
+13 -11
drivers/net/dsa/b53/b53_priv.h
··· 21 21 22 22 #include <linux/kernel.h> 23 23 #include <linux/mutex.h> 24 - #include <linux/phy.h> 24 + #include <linux/phylink.h> 25 25 #include <linux/etherdevice.h> 26 26 #include <net/dsa.h> 27 27 ··· 29 29 30 30 struct b53_device; 31 31 struct net_device; 32 - struct phylink_link_state; 33 32 34 33 struct b53_io_ops { 35 34 int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); ··· 47 48 void (*irq_disable)(struct b53_device *dev, int port); 48 49 void (*phylink_get_caps)(struct b53_device *dev, int port, 49 50 struct phylink_config *config); 51 + struct phylink_pcs *(*phylink_mac_select_pcs)(struct b53_device *dev, 52 + int port, 53 + phy_interface_t interface); 50 54 u8 (*serdes_map_lane)(struct b53_device *dev, int port); 51 - int (*serdes_link_state)(struct b53_device *dev, int port, 52 - struct phylink_link_state *state); 53 - void (*serdes_config)(struct b53_device *dev, int port, 54 - unsigned int mode, 55 - const struct phylink_link_state *state); 56 - void (*serdes_an_restart)(struct b53_device *dev, int port); 57 55 void (*serdes_link_set)(struct b53_device *dev, int port, 58 56 unsigned int mode, phy_interface_t interface, 59 57 bool link_up); ··· 81 85 BCM7278_DEVICE_ID = 0x7278, 82 86 }; 83 87 88 + struct b53_pcs { 89 + struct phylink_pcs pcs; 90 + struct b53_device *dev; 91 + u8 lane; 92 + }; 93 + 84 94 #define B53_N_PORTS 9 85 95 #define B53_N_PORTS_25 6 96 + #define B53_N_PCS 2 86 97 87 98 struct b53_port { 88 99 u16 vlan_ctl_mask; ··· 146 143 bool vlan_enabled; 147 144 unsigned int num_ports; 148 145 struct b53_port *ports; 146 + 147 + struct b53_pcs pcs[B53_N_PCS]; 149 148 }; 150 149 151 150 #define b53_for_each_port(dev, i) \ ··· 341 336 struct netlink_ext_ack *extack); 342 337 int b53_setup_devlink_resources(struct dsa_switch *ds); 343 338 void b53_port_event(struct dsa_switch *ds, int port); 344 - int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, 345 - struct phylink_link_state *state); 346 339 void b53_phylink_mac_config(struct dsa_switch *ds, int port, 347 340 unsigned int mode, 348 341 const struct phylink_link_state *state); 349 - void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port); 350 342 void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, 351 343 unsigned int mode, 352 344 phy_interface_t interface);
+51 -23
drivers/net/dsa/b53/b53_serdes.c
··· 17 17 #include "b53_serdes.h" 18 18 #include "b53_regs.h" 19 19 20 + static inline struct b53_pcs *pcs_to_b53_pcs(struct phylink_pcs *pcs) 21 + { 22 + return container_of(pcs, struct b53_pcs, pcs); 23 + } 24 + 20 25 static void b53_serdes_write_blk(struct b53_device *dev, u8 offset, u16 block, 21 26 u16 value) 22 27 { ··· 65 60 return b53_serdes_read_blk(dev, offset, block); 66 61 } 67 62 68 - void b53_serdes_config(struct b53_device *dev, int port, unsigned int mode, 69 - const struct phylink_link_state *state) 63 + static int b53_serdes_config(struct phylink_pcs *pcs, unsigned int mode, 64 + phy_interface_t interface, 65 + const unsigned long *advertising, 66 + bool permit_pause_to_mac) 70 67 { 71 - u8 lane = b53_serdes_map_lane(dev, port); 68 + struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; 69 + u8 lane = pcs_to_b53_pcs(pcs)->lane; 72 70 u16 reg; 73 - 74 - if (lane == B53_INVALID_LANE) 75 - return; 76 71 77 72 reg = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), 78 73 SERDES_DIGITAL_BLK); 79 - if (state->interface == PHY_INTERFACE_MODE_1000BASEX) 74 + if (interface == PHY_INTERFACE_MODE_1000BASEX) 80 75 reg |= FIBER_MODE_1000X; 81 76 else 82 77 reg &= ~FIBER_MODE_1000X; 83 78 b53_serdes_write(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), 84 79 SERDES_DIGITAL_BLK, reg); 80 + 81 + return 0; 85 82 } 86 - EXPORT_SYMBOL(b53_serdes_config); 87 83 88 - void b53_serdes_an_restart(struct b53_device *dev, int port) 84 + static void b53_serdes_an_restart(struct phylink_pcs *pcs) 89 85 { 90 - u8 lane = b53_serdes_map_lane(dev, port); 86 + struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; 87 + u8 lane = pcs_to_b53_pcs(pcs)->lane; 91 88 u16 reg; 92 - 93 - if (lane == B53_INVALID_LANE) 94 - return; 95 89 96 90 reg = b53_serdes_read(dev, lane, B53_SERDES_MII_REG(MII_BMCR), 97 91 SERDES_MII_BLK); ··· 98 94 b53_serdes_write(dev, lane, B53_SERDES_MII_REG(MII_BMCR), 99 95 SERDES_MII_BLK, reg); 100 96 } 101 - EXPORT_SYMBOL(b53_serdes_an_restart); 102 97 103 - int b53_serdes_link_state(struct b53_device *dev, int port, 104 - struct phylink_link_state *state) 98 + static void b53_serdes_get_state(struct phylink_pcs *pcs, 99 + struct phylink_link_state *state) 105 100 { 106 - u8 lane = b53_serdes_map_lane(dev, port); 101 + struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; 102 + u8 lane = pcs_to_b53_pcs(pcs)->lane; 107 103 u16 dig, bmsr; 108 - 109 - if (lane == B53_INVALID_LANE) 110 - return 1; 111 104 112 105 dig = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_STATUS, 113 106 SERDES_DIGITAL_BLK); ··· 134 133 state->pause |= MLO_PAUSE_RX; 135 134 if (dig & PAUSE_RESOLUTION_TX_SIDE) 136 135 state->pause |= MLO_PAUSE_TX; 137 - 138 - return 0; 139 136 } 140 - EXPORT_SYMBOL(b53_serdes_link_state); 141 137 142 138 void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, 143 139 phy_interface_t interface, bool link_up) ··· 155 157 SERDES_MII_BLK, reg); 156 158 } 157 159 EXPORT_SYMBOL(b53_serdes_link_set); 160 + 161 + static const struct phylink_pcs_ops b53_pcs_ops = { 162 + .pcs_get_state = b53_serdes_get_state, 163 + .pcs_config = b53_serdes_config, 164 + .pcs_an_restart = b53_serdes_an_restart, 165 + }; 158 166 159 167 void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, 160 168 struct phylink_config *config) ··· 191 187 } 192 188 EXPORT_SYMBOL(b53_serdes_phylink_get_caps); 193 189 190 + struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev, 191 + int port, 192 + phy_interface_t interface) 193 + { 194 + u8 lane = b53_serdes_map_lane(dev, port); 195 + 196 + if (lane == B53_INVALID_LANE || lane >= B53_N_PCS || 197 + !dev->pcs[lane].dev) 198 + return NULL; 199 + 200 + if (!phy_interface_mode_is_8023z(interface) && 201 + interface != PHY_INTERFACE_MODE_SGMII) 202 + return NULL; 203 + 204 + return &dev->pcs[lane].pcs; 205 + } 206 + EXPORT_SYMBOL(b53_serdes_phylink_mac_select_pcs); 207 + 194 208 int b53_serdes_init(struct b53_device *dev, int port) 195 209 { 196 210 u8 lane = b53_serdes_map_lane(dev, port); 211 + struct b53_pcs *pcs; 197 212 u16 id0, msb, lsb; 198 213 199 214 if (lane == B53_INVALID_LANE) ··· 234 211 (id0 >> SERDES_ID0_REV_LETTER_SHIFT) + 0x41, 235 212 (id0 >> SERDES_ID0_REV_NUM_SHIFT) & SERDES_ID0_REV_NUM_MASK, 236 213 (u32)msb << 16 | lsb); 214 + 215 + pcs = &dev->pcs[lane]; 216 + pcs->dev = dev; 217 + pcs->lane = lane; 218 + pcs->pcs.ops = &b53_pcs_ops; 237 219 238 220 return 0; 239 221 }
+3 -6
drivers/net/dsa/b53/b53_serdes.h
··· 107 107 return dev->ops->serdes_map_lane(dev, port); 108 108 } 109 109 110 - int b53_serdes_get_link(struct b53_device *dev, int port); 111 - int b53_serdes_link_state(struct b53_device *dev, int port, 112 - struct phylink_link_state *state); 113 - void b53_serdes_config(struct b53_device *dev, int port, unsigned int mode, 114 - const struct phylink_link_state *state); 115 - void b53_serdes_an_restart(struct b53_device *dev, int port); 116 110 void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, 117 111 phy_interface_t interface, bool link_up); 112 + struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev, 113 + int port, 114 + phy_interface_t interface); 118 115 void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, 119 116 struct phylink_config *config); 120 117 #if IS_ENABLED(CONFIG_B53_SERDES)
+1 -3
drivers/net/dsa/b53/b53_srab.c
··· 491 491 .irq_disable = b53_srab_irq_disable, 492 492 .phylink_get_caps = b53_srab_phylink_get_caps, 493 493 #if IS_ENABLED(CONFIG_B53_SERDES) 494 + .phylink_mac_select_pcs = b53_serdes_phylink_mac_select_pcs, 494 495 .serdes_map_lane = b53_srab_serdes_map_lane, 495 - .serdes_link_state = b53_serdes_link_state, 496 - .serdes_config = b53_serdes_config, 497 - .serdes_an_restart = b53_serdes_an_restart, 498 496 .serdes_link_set = b53_serdes_link_set, 499 497 #endif 500 498 };