1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <linux/if_bridge.h> 4 5 #include "lan966x_main.h" 6 7 static void lan966x_lag_set_aggr_pgids(struct lan966x *lan966x) 8 { 9 u32 visited = GENMASK(lan966x->num_phys_ports - 1, 0); 10 int p, lag, i; 11 12 /* Reset destination and aggregation PGIDS */ 13 for (p = 0; p < lan966x->num_phys_ports; ++p) 14 lan_wr(ANA_PGID_PGID_SET(BIT(p)), 15 lan966x, ANA_PGID(p)); 16 17 for (p = PGID_AGGR; p < PGID_SRC; ++p) 18 lan_wr(ANA_PGID_PGID_SET(visited), 19 lan966x, ANA_PGID(p)); 20 21 /* The visited ports bitmask holds the list of ports offloading any 22 * bonding interface. Initially we mark all these ports as unvisited, 23 * then every time we visit a port in this bitmask, we know that it is 24 * the lowest numbered port, i.e. the one whose logical ID == physical 25 * port ID == LAG ID. So we mark as visited all further ports in the 26 * bitmask that are offloading the same bonding interface. This way, 27 * we set up the aggregation PGIDs only once per bonding interface. 28 */ 29 for (p = 0; p < lan966x->num_phys_ports; ++p) { 30 struct lan966x_port *port = lan966x->ports[p]; 31 32 if (!port || !port->bond) 33 continue; 34 35 visited &= ~BIT(p); 36 } 37 38 /* Now, set PGIDs for each active LAG */ 39 for (lag = 0; lag < lan966x->num_phys_ports; ++lag) { 40 struct net_device *bond = lan966x->ports[lag]->bond; 41 int num_active_ports = 0; 42 unsigned long bond_mask; 43 u8 aggr_idx[16]; 44 45 if (!bond || (visited & BIT(lag))) 46 continue; 47 48 bond_mask = lan966x_lag_get_mask(lan966x, bond); 49 50 for_each_set_bit(p, &bond_mask, lan966x->num_phys_ports) { 51 struct lan966x_port *port = lan966x->ports[p]; 52 53 lan_wr(ANA_PGID_PGID_SET(bond_mask), 54 lan966x, ANA_PGID(p)); 55 if (port->lag_tx_active) 56 aggr_idx[num_active_ports++] = p; 57 } 58 59 for (i = PGID_AGGR; i < PGID_SRC; ++i) { 60 u32 ac; 61 62 ac = lan_rd(lan966x, ANA_PGID(i)); 63 ac &= ~bond_mask; 64 /* Don't do division by zero if there was no active 65 * port. Just make all aggregation codes zero. 66 */ 67 if (num_active_ports) 68 ac |= BIT(aggr_idx[i % num_active_ports]); 69 lan_wr(ANA_PGID_PGID_SET(ac), 70 lan966x, ANA_PGID(i)); 71 } 72 73 /* Mark all ports in the same LAG as visited to avoid applying 74 * the same config again. 75 */ 76 for (p = lag; p < lan966x->num_phys_ports; p++) { 77 struct lan966x_port *port = lan966x->ports[p]; 78 79 if (!port) 80 continue; 81 82 if (port->bond == bond) 83 visited |= BIT(p); 84 } 85 } 86 } 87 88 static void lan966x_lag_set_port_ids(struct lan966x *lan966x) 89 { 90 struct lan966x_port *port; 91 u32 bond_mask; 92 u32 lag_id; 93 int p; 94 95 for (p = 0; p < lan966x->num_phys_ports; ++p) { 96 port = lan966x->ports[p]; 97 if (!port) 98 continue; 99 100 lag_id = port->chip_port; 101 102 bond_mask = lan966x_lag_get_mask(lan966x, port->bond); 103 if (bond_mask) 104 lag_id = __ffs(bond_mask); 105 106 lan_rmw(ANA_PORT_CFG_PORTID_VAL_SET(lag_id), 107 ANA_PORT_CFG_PORTID_VAL, 108 lan966x, ANA_PORT_CFG(port->chip_port)); 109 } 110 } 111 112 static void lan966x_lag_update_ids(struct lan966x *lan966x) 113 { 114 lan966x_lag_set_port_ids(lan966x); 115 lan966x_update_fwd_mask(lan966x); 116 lan966x_lag_set_aggr_pgids(lan966x); 117 } 118 119 int lan966x_lag_port_join(struct lan966x_port *port, 120 struct net_device *brport_dev, 121 struct net_device *bond, 122 struct netlink_ext_ack *extack) 123 { 124 struct lan966x *lan966x = port->lan966x; 125 struct net_device *dev = port->dev; 126 u32 lag_id = -1; 127 u32 bond_mask; 128 int err; 129 130 bond_mask = lan966x_lag_get_mask(lan966x, bond); 131 if (bond_mask) 132 lag_id = __ffs(bond_mask); 133 134 port->bond = bond; 135 lan966x_lag_update_ids(lan966x); 136 137 err = switchdev_bridge_port_offload(brport_dev, dev, port, 138 &lan966x_switchdev_nb, 139 &lan966x_switchdev_blocking_nb, 140 false, extack); 141 if (err) 142 goto out; 143 144 lan966x_port_stp_state_set(port, br_port_get_stp_state(brport_dev)); 145 146 if (lan966x_lag_first_port(port->bond, port->dev) && 147 lag_id != -1) 148 lan966x_mac_lag_replace_port_entry(lan966x, 149 lan966x->ports[lag_id], 150 port); 151 152 return 0; 153 154 out: 155 port->bond = NULL; 156 lan966x_lag_update_ids(lan966x); 157 158 return err; 159 } 160 161 void lan966x_lag_port_leave(struct lan966x_port *port, struct net_device *bond) 162 { 163 struct lan966x *lan966x = port->lan966x; 164 u32 bond_mask; 165 u32 lag_id; 166 167 if (lan966x_lag_first_port(port->bond, port->dev)) { 168 bond_mask = lan966x_lag_get_mask(lan966x, port->bond); 169 bond_mask &= ~BIT(port->chip_port); 170 if (bond_mask) { 171 lag_id = __ffs(bond_mask); 172 lan966x_mac_lag_replace_port_entry(lan966x, port, 173 lan966x->ports[lag_id]); 174 } else { 175 lan966x_mac_lag_remove_port_entry(lan966x, port); 176 } 177 } 178 179 port->bond = NULL; 180 lan966x_lag_update_ids(lan966x); 181 lan966x_port_stp_state_set(port, BR_STATE_FORWARDING); 182 } 183 184 static bool lan966x_lag_port_check_hash_types(struct lan966x *lan966x, 185 enum netdev_lag_hash hash_type) 186 { 187 int p; 188 189 for (p = 0; p < lan966x->num_phys_ports; ++p) { 190 struct lan966x_port *port = lan966x->ports[p]; 191 192 if (!port || !port->bond) 193 continue; 194 195 if (port->hash_type != hash_type) 196 return false; 197 } 198 199 return true; 200 } 201 202 int lan966x_lag_port_prechangeupper(struct net_device *dev, 203 struct netdev_notifier_changeupper_info *info) 204 { 205 struct lan966x_port *port = netdev_priv(dev); 206 struct lan966x *lan966x = port->lan966x; 207 struct netdev_lag_upper_info *lui; 208 struct netlink_ext_ack *extack; 209 210 extack = netdev_notifier_info_to_extack(&info->info); 211 lui = info->upper_info; 212 if (!lui) { 213 port->hash_type = NETDEV_LAG_HASH_NONE; 214 return NOTIFY_DONE; 215 } 216 217 if (lui->tx_type != NETDEV_LAG_TX_TYPE_HASH) { 218 NL_SET_ERR_MSG_MOD(extack, 219 "LAG device using unsupported Tx type"); 220 return -EINVAL; 221 } 222 223 if (!lan966x_lag_port_check_hash_types(lan966x, lui->hash_type)) { 224 NL_SET_ERR_MSG_MOD(extack, 225 "LAG devices can have only the same hash_type"); 226 return -EINVAL; 227 } 228 229 switch (lui->hash_type) { 230 case NETDEV_LAG_HASH_L2: 231 lan_wr(ANA_AGGR_CFG_AC_DMAC_ENA_SET(1) | 232 ANA_AGGR_CFG_AC_SMAC_ENA_SET(1), 233 lan966x, ANA_AGGR_CFG); 234 break; 235 case NETDEV_LAG_HASH_L34: 236 lan_wr(ANA_AGGR_CFG_AC_IP6_TCPUDP_ENA_SET(1) | 237 ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA_SET(1) | 238 ANA_AGGR_CFG_AC_IP4_SIPDIP_ENA_SET(1), 239 lan966x, ANA_AGGR_CFG); 240 break; 241 case NETDEV_LAG_HASH_L23: 242 lan_wr(ANA_AGGR_CFG_AC_DMAC_ENA_SET(1) | 243 ANA_AGGR_CFG_AC_SMAC_ENA_SET(1) | 244 ANA_AGGR_CFG_AC_IP6_TCPUDP_ENA_SET(1) | 245 ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA_SET(1), 246 lan966x, ANA_AGGR_CFG); 247 break; 248 default: 249 NL_SET_ERR_MSG_MOD(extack, 250 "LAG device using unsupported hash type"); 251 return -EINVAL; 252 } 253 254 port->hash_type = lui->hash_type; 255 256 return NOTIFY_OK; 257 } 258 259 int lan966x_lag_port_changelowerstate(struct net_device *dev, 260 struct netdev_notifier_changelowerstate_info *info) 261 { 262 struct netdev_lag_lower_state_info *lag = info->lower_state_info; 263 struct lan966x_port *port = netdev_priv(dev); 264 struct lan966x *lan966x = port->lan966x; 265 bool is_active; 266 267 if (!port->bond) 268 return NOTIFY_DONE; 269 270 is_active = lag->link_up && lag->tx_enabled; 271 if (port->lag_tx_active == is_active) 272 return NOTIFY_DONE; 273 274 port->lag_tx_active = is_active; 275 lan966x_lag_set_aggr_pgids(lan966x); 276 277 return NOTIFY_OK; 278 } 279 280 int lan966x_lag_netdev_prechangeupper(struct net_device *dev, 281 struct netdev_notifier_changeupper_info *info) 282 { 283 struct lan966x_port *port; 284 struct net_device *lower; 285 struct list_head *iter; 286 int err; 287 288 netdev_for_each_lower_dev(dev, lower, iter) { 289 if (!lan966x_netdevice_check(lower)) 290 continue; 291 292 port = netdev_priv(lower); 293 if (port->bond != dev) 294 continue; 295 296 err = lan966x_port_prechangeupper(lower, dev, info); 297 if (err) 298 return err; 299 } 300 301 return NOTIFY_DONE; 302 } 303 304 int lan966x_lag_netdev_changeupper(struct net_device *dev, 305 struct netdev_notifier_changeupper_info *info) 306 { 307 struct lan966x_port *port; 308 struct net_device *lower; 309 struct list_head *iter; 310 int err; 311 312 netdev_for_each_lower_dev(dev, lower, iter) { 313 if (!lan966x_netdevice_check(lower)) 314 continue; 315 316 port = netdev_priv(lower); 317 if (port->bond != dev) 318 continue; 319 320 err = lan966x_port_changeupper(lower, dev, info); 321 if (err) 322 return err; 323 } 324 325 return NOTIFY_DONE; 326 } 327 328 bool lan966x_lag_first_port(struct net_device *lag, struct net_device *dev) 329 { 330 struct lan966x_port *port = netdev_priv(dev); 331 struct lan966x *lan966x = port->lan966x; 332 unsigned long bond_mask; 333 334 if (port->bond != lag) 335 return false; 336 337 bond_mask = lan966x_lag_get_mask(lan966x, lag); 338 if (bond_mask && port->chip_port == __ffs(bond_mask)) 339 return true; 340 341 return false; 342 } 343 344 u32 lan966x_lag_get_mask(struct lan966x *lan966x, struct net_device *bond) 345 { 346 struct lan966x_port *port; 347 u32 mask = 0; 348 int p; 349 350 if (!bond) 351 return mask; 352 353 for (p = 0; p < lan966x->num_phys_ports; p++) { 354 port = lan966x->ports[p]; 355 if (!port) 356 continue; 357 358 if (port->bond == bond) 359 mask |= BIT(p); 360 } 361 362 return mask; 363 } 364