| 2147 | } |
| 2148 | |
| 2149 | static void |
| 2150 | lagg_linkstate(struct lagg_softc *sc) |
| 2151 | { |
| 2152 | struct epoch_tracker et; |
| 2153 | struct lagg_port *lp; |
| 2154 | int new_link = LINK_STATE_DOWN; |
| 2155 | uint64_t speed; |
| 2156 | |
| 2157 | LAGG_XLOCK_ASSERT(sc); |
| 2158 | |
| 2159 | /* LACP handles link state itself */ |
| 2160 | if (sc->sc_proto == LAGG_PROTO_LACP) |
| 2161 | return; |
| 2162 | |
| 2163 | /* Our link is considered up if at least one of our ports is active */ |
| 2164 | NET_EPOCH_ENTER(et); |
| 2165 | CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { |
| 2166 | if (lp->lp_ifp->if_link_state == LINK_STATE_UP) { |
| 2167 | new_link = LINK_STATE_UP; |
| 2168 | break; |
| 2169 | } |
| 2170 | } |
| 2171 | NET_EPOCH_EXIT(et); |
| 2172 | if_link_state_change(sc->sc_ifp, new_link); |
| 2173 | |
| 2174 | /* Update if_baudrate to reflect the max possible speed */ |
| 2175 | switch (sc->sc_proto) { |
| 2176 | case LAGG_PROTO_FAILOVER: |
| 2177 | sc->sc_ifp->if_baudrate = sc->sc_primary != NULL ? |
| 2178 | sc->sc_primary->lp_ifp->if_baudrate : 0; |
| 2179 | break; |
| 2180 | case LAGG_PROTO_ROUNDROBIN: |
| 2181 | case LAGG_PROTO_LOADBALANCE: |
| 2182 | case LAGG_PROTO_BROADCAST: |
| 2183 | speed = 0; |
| 2184 | NET_EPOCH_ENTER(et); |
| 2185 | CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) |
| 2186 | speed += lp->lp_ifp->if_baudrate; |
| 2187 | NET_EPOCH_EXIT(et); |
| 2188 | sc->sc_ifp->if_baudrate = speed; |
| 2189 | break; |
| 2190 | case LAGG_PROTO_LACP: |
| 2191 | /* LACP updates if_baudrate itself */ |
| 2192 | break; |
| 2193 | } |
| 2194 | } |
| 2195 | |
| 2196 | static void |
| 2197 | lagg_port_state(struct ifnet *ifp, int state) |
no test coverage detected