| 1784 | } |
| 1785 | |
| 1786 | static void |
| 1787 | bstp_ifupdstatus(void *arg, int pending) |
| 1788 | { |
| 1789 | struct bstp_port *bp = (struct bstp_port *)arg; |
| 1790 | struct bstp_state *bs = bp->bp_bs; |
| 1791 | struct ifnet *ifp = bp->bp_ifp; |
| 1792 | struct ifmediareq ifmr; |
| 1793 | int error, changed; |
| 1794 | |
| 1795 | if (!bp->bp_active) |
| 1796 | return; |
| 1797 | |
| 1798 | bzero((char *)&ifmr, sizeof(ifmr)); |
| 1799 | error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr); |
| 1800 | |
| 1801 | BSTP_LOCK(bs); |
| 1802 | changed = 0; |
| 1803 | if ((error == 0) && (ifp->if_flags & IFF_UP)) { |
| 1804 | if (ifmr.ifm_status & IFM_ACTIVE) { |
| 1805 | /* A full-duplex link is assumed to be point to point */ |
| 1806 | if (bp->bp_flags & BSTP_PORT_AUTOPTP) { |
| 1807 | int fdx; |
| 1808 | |
| 1809 | fdx = ifmr.ifm_active & IFM_FDX ? 1 : 0; |
| 1810 | if (bp->bp_ptp_link ^ fdx) { |
| 1811 | bp->bp_ptp_link = fdx; |
| 1812 | changed = 1; |
| 1813 | } |
| 1814 | } |
| 1815 | |
| 1816 | /* Calc the cost if the link was down previously */ |
| 1817 | if (bp->bp_flags & BSTP_PORT_PNDCOST) { |
| 1818 | uint32_t cost; |
| 1819 | |
| 1820 | cost = bstp_calc_path_cost(bp); |
| 1821 | if (bp->bp_path_cost != cost) { |
| 1822 | bp->bp_path_cost = cost; |
| 1823 | changed = 1; |
| 1824 | } |
| 1825 | bp->bp_flags &= ~BSTP_PORT_PNDCOST; |
| 1826 | } |
| 1827 | |
| 1828 | if (bp->bp_role == BSTP_ROLE_DISABLED) { |
| 1829 | bstp_enable_port(bs, bp); |
| 1830 | changed = 1; |
| 1831 | } |
| 1832 | } else { |
| 1833 | if (bp->bp_role != BSTP_ROLE_DISABLED) { |
| 1834 | bstp_disable_port(bs, bp); |
| 1835 | changed = 1; |
| 1836 | if ((bp->bp_flags & BSTP_PORT_ADMEDGE) && |
| 1837 | bp->bp_protover == BSTP_PROTO_RSTP) |
| 1838 | bp->bp_operedge = 1; |
| 1839 | } |
| 1840 | } |
| 1841 | } else if (bp->bp_infois != BSTP_INFO_DISABLED) { |
| 1842 | bstp_disable_port(bs, bp); |
| 1843 | changed = 1; |
no test coverage detected