Index: dev/iwi/if_iwi.c =================================================================== RCS file: /home/ncvs/src/sys/dev/iwi/if_iwi.c,v retrieving revision 1.80 diff -u -r1.80 if_iwi.c --- dev/iwi/if_iwi.c 17 Dec 2011 10:23:17 -0000 1.80 +++ dev/iwi/if_iwi.c 6 Mar 2012 13:48:31 -0000 @@ -168,8 +168,11 @@ struct ieee80211_node *, int); static int iwi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); +static void iwi_update_mcast(struct ifnet *); static void iwi_start_locked(struct ifnet *); static void iwi_start(struct ifnet *); +static int iwi_transmit(struct ifnet *ifp, struct mbuf *m); +static void iwi_qflush(struct ifnet *ifp); static void iwi_watchdog(void *); static int iwi_ioctl(struct ifnet *, u_long, caddr_t); static void iwi_stop_master(struct iwi_softc *); @@ -367,6 +370,10 @@ ifp->if_init = iwi_init; ifp->if_ioctl = iwi_ioctl; ifp->if_start = iwi_start; +#if __FreeBSD_version >= 800000 + ifp->if_transmit = iwi_transmit; + ifp->if_qflush = iwi_qflush; +#endif IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; IFQ_SET_READY(&ifp->if_snd); @@ -413,6 +420,7 @@ sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = iwi_node_free; ic->ic_raw_xmit = iwi_raw_xmit; + ic->ic_update_mcast = iwi_update_mcast; ic->ic_scan_start = iwi_scan_start; ic->ic_scan_end = iwi_scan_end; ic->ic_set_channel = iwi_set_channel; @@ -1357,8 +1365,8 @@ frm += 2; wme = NULL; - while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1], return); + while (efrm - frm > 1) { + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); switch (*frm) { case IEEE80211_ELEMID_VENDOR: if (iswmeoui(frm)) @@ -1953,6 +1961,12 @@ } static void +iwi_update_mcast(struct ifnet *ifp) +{ + /* Ignore */ +} + +static void iwi_start_locked(struct ifnet *ifp) { struct iwi_softc *sc = ifp->if_softc; @@ -2000,6 +2014,60 @@ IWI_UNLOCK(sc); } +#if __FreeBSD_version >= 800000 +static int +iwi_transmit(struct ifnet *ifp, struct mbuf *m) +{ + struct iwi_softc *sc = ifp->if_softc; + struct ieee80211_node *ni; + int ac; + int rc = 0; + + IWI_LOCK_DECL; + + IWI_LOCK(sc); + ac = M_WME_GETAC(m); + if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) { + /* there is no place left in this ring; tail drop */ + /* XXX tail drop */ + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + rc = -1; + goto iwi_transmit_exit; + } + + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + if ((rc = iwi_tx_start(ifp, m, ni, ac)) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + goto iwi_transmit_exit; + } + + sc->sc_tx_timer = 5; + +iwi_transmit_exit: + IWI_UNLOCK(sc); + return (rc); +} + +static void +iwi_qflush(struct ifnet *ifp) +{ + struct iwi_softc *sc = ifp->if_softc; + int i; + + IWI_LOCK_DECL; + + IWI_LOCK(sc); + for (i = 0; i < 4; i++) { + iwi_reset_tx_ring(sc, &sc->txq[i]); + } + + if_qflush(ifp); + IWI_UNLOCK(sc); +} +#endif + static void iwi_watchdog(void *arg) {