/* * Handling of a single switch port * * Copyright (c) 2017 Savoir-faire Linux Inc. * Vivien Didelot * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include "dsa_priv.h" int dsa_port_set_state(struct dsa_port *dp, u8 state, struct switchdev_trans *trans) { struct dsa_switch *ds = dp->ds; int port = dp->index; if (switchdev_trans_ph_prepare(trans)) return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP; if (ds->ops->port_stp_state_set) ds->ops->port_stp_state_set(ds, port, state); if (ds->ops->port_fast_age) { /* Fast age FDB entries or flush appropriate forwarding database * for the given port, if we are moving it from Learning or * Forwarding state, to Disabled or Blocking or Listening state. */ if ((dp->stp_state == BR_STATE_LEARNING || dp->stp_state == BR_STATE_FORWARDING) && (state == BR_STATE_DISABLED || state == BR_STATE_BLOCKING || state == BR_STATE_LISTENING)) ds->ops->port_fast_age(ds, port); } dp->stp_state = state; return 0; } void dsa_port_set_state_now(struct dsa_port *dp, u8 state) { int err; err = dsa_port_set_state(dp, state, NULL); if (err) pr_err("DSA: failed to set STP state %u (%d)\n", state, err); }