From owner-p4-projects@FreeBSD.ORG Mon Feb 18 23:51:19 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4CAF216A41A; Mon, 18 Feb 2008 23:51:19 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 119E016A418 for ; Mon, 18 Feb 2008 23:51:19 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0612913C442 for ; Mon, 18 Feb 2008 23:51:19 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m1INpI5q004213 for ; Mon, 18 Feb 2008 23:51:18 GMT (envelope-from thompsa@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m1INpIlj004210 for perforce@freebsd.org; Mon, 18 Feb 2008 23:51:18 GMT (envelope-from thompsa@freebsd.org) Date: Mon, 18 Feb 2008 23:51:18 GMT Message-Id: <200802182351.m1INpIlj004210@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to thompsa@freebsd.org using -f From: Andrew Thompson To: Perforce Change Reviews Cc: Subject: PERFORCE change 135686 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Feb 2008 23:51:19 -0000 http://perforce.freebsd.org/chv.cgi?CH=135686 Change 135686 by thompsa@thompsa_heff on 2008/02/18 23:50:54 MF //depot/user/benjsc/wpi/sys/dev/wpi/if_wpi.c@131089 1. ic->ic_bsschan is the bss channel, not ni->ni_cha; it's well-defined in RUN state so use it (other times it may be set to ANY) 2. remove watchdog_cnt since it does nothing bug duplicate sc_tx_timer 3. good drivers should never set channel state; remove code on SCAN_START 4. rewrite wpi_tx_start 5. calculate 802.11 header length correctly in wpi_tx_start 6. take ssid info from scan state, not ieee80211com; when a scan is issued by a user application it may be differnt (if not now, then in the future) o Place some debug code in wpi_scan under debug o Minor style changes (Note these don't include all the style changes provded by sam - they'll be committed in a separate commit) o Correct assoc state to fall through when not in RUN state Applied from a slightly modified version originally submitted by Submitted By: sam@ (With many thanks!) Affected files ... .. //depot/projects/wifi/sys/dev/wpi/if_wpi.c#9 edit Differences ... ==== //depot/projects/wifi/sys/dev/wpi/if_wpi.c#9 (text+ko) ==== @@ -1339,8 +1339,8 @@ switch (nstate) { case IEEE80211_S_SCAN: - DPRINTF(("NEWSTATE:SCAN\n")); - /* Scanning is handled in net80211 via the scan_start, + /* + * Scanning is handled in net80211 via the scan_start, * scan_end, scan_curchan functions. Hence all we do when * changing to the SCAN state is update the leds */ @@ -1352,11 +1352,10 @@ case IEEE80211_S_ASSOC: DPRINTF(("NEWSTATE:ASSOC\n")); if (ic->ic_state != IEEE80211_S_RUN) - break; + break; /* FALLTHROUGH */ case IEEE80211_S_AUTH: - DPRINTF(("NEWSTATE:AUTH\n")); sc->flags |= WPI_FLAG_AUTH; sc->config.associd = 0; sc->config.filter &= ~htole32(WPI_FILTER_BSS); @@ -1365,7 +1364,6 @@ break; case IEEE80211_S_RUN: - DPRINTF(("NEWSTATE:RUN\n")); if (ic->ic_opmode == IEEE80211_M_MONITOR) { /* link LED blinks while monitoring */ wpi_set_led(sc, WPI_LED_LINK, 5, 5); @@ -1409,7 +1407,7 @@ return error; } - if ((error = wpi_set_txpower(sc, ic->ic_bss->ni_chan, 1)) != 0) { + if ((error = wpi_set_txpower(sc, ic->ic_bsschan, 1)) != 0) { device_printf(sc->sc_dev, "could set txpower\n"); return error; @@ -1428,9 +1426,6 @@ break; case IEEE80211_S_INIT: - DPRINTF(("NEWSTATE:INIT\n")); - break; - default: break; } @@ -1595,7 +1590,6 @@ struct wpi_rx_head *head; struct wpi_rx_tail *tail; struct wpi_rbuf *rbuf; - struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m, *mnew; WPI_LOCK_DECL; @@ -1688,12 +1682,11 @@ bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); } - wh = mtod(m, struct ieee80211_frame *); WPI_UNLOCK(sc); /* XXX frame length > sizeof(struct ieee80211_frame_min)? */ /* grab a reference to the source node */ - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); /* send the frame to the 802.11 layer */ ieee80211_input(ic, m, ni, stat->rssi, 0, 0); @@ -1746,7 +1739,6 @@ ring->queued--; sc->sc_tx_timer = 0; - sc->watchdog_cnt = 0; callout_stop(&sc->watchdog_to); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; wpi_start(ifp); @@ -1855,9 +1847,6 @@ DPRINTFN(WPI_DEBUG_SCANNING, ("scanning channel %d status %x\n", scan->chan, le32toh(scan->status))); - - /* fix current channel */ - ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan]; break; } case WPI_STOP_SCAN: @@ -1877,7 +1866,8 @@ struct wpi_missed_beacon *beacon = (struct wpi_missed_beacon *)(desc + 1); - if (le32toh(beacon->consecutive) >= ic->ic_bmissthreshold) { + if (le32toh(beacon->consecutive) >= + ic->ic_bmissthreshold) { DPRINTF(("Beacon miss: %u >= %u\n", le32toh(beacon->consecutive), ic->ic_bmissthreshold)); @@ -1892,7 +1882,6 @@ /* tell the firmware what we have processed */ hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1; WPI_WRITE(sc, WPI_RX_WIDX, hw & ~7); - } static void @@ -1977,6 +1966,7 @@ int ac) { struct ieee80211com *ic = &sc->sc_ic; + const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; struct wpi_tx_ring *ring = &sc->txq[ac]; struct wpi_tx_desc *desc; struct wpi_tx_data *data; @@ -1984,9 +1974,8 @@ struct wpi_cmd_data *tx; struct ieee80211_frame *wh; struct ieee80211_key *k; - const struct chanAccParams *cap; struct mbuf *mnew; - int i, error, nsegs, rate, hdrlen, noack = 0; + int i, error, nsegs, rate, hdrlen, ismcast; bus_dma_segment_t segs[WPI_MAX_SCATTER]; desc = &ring->desc[ring->cur]; @@ -1994,60 +1983,19 @@ wh = mtod(m0, struct ieee80211_frame *); - if (IEEE80211_QOS_HAS_SEQ(wh)) { - hdrlen = sizeof (struct ieee80211_qosframe); - cap = &ic->ic_wme.wme_chanParams; - noack = cap->cap_wmeParams[ac].wmep_noackPolicy; - } else - hdrlen = sizeof (struct ieee80211_frame); + hdrlen = ieee80211_hdrsize(wh); + ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - if ((k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) { + k = ieee80211_crypto_encap(ic, ni, m0); + if (k == NULL){ m_freem(m0); return ENOBUFS; } - /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } - /* pickup a rate */ - if (IEEE80211_IS_MULTICAST(wh->i_addr1)|| - ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT)) { - /* - * mgmt/multicast frames are sent at the lowest available - * bit-rate - */ - rate = ni->ni_rates.rs_rates[0]; - } else { - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - } - rate &= IEEE80211_RATE_VAL; - -#ifndef WPI_CURRENT - if (sc->sc_drvbpf != NULL) { -#else - if (bpf_peers_present(sc->sc_drvbpf)) { -#endif - - struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); - tap->wt_rate = rate; - tap->wt_hwqueue = ac; - if (wh->i_fc[1] & IEEE80211_FC1_WEP) - tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; - - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); - } - cmd = &ring->cmd[ring->cur]; cmd->code = WPI_CMD_TX_DATA; cmd->flags = 0; @@ -2055,45 +2003,67 @@ cmd->idx = ring->cur; tx = (struct wpi_cmd_data *)cmd->data; - tx->flags = 0; + tx->flags = htole32(WPI_TX_AUTO_SEQ); + tx->timeout= htole16(0); + tx->ofdm_mask = 0xff; + tx->cck_mask = 0x0f; + tx->lifetime = htole32(WPI_LIFETIME_INFINITE); + tx->id = ismcast ? WPI_ID_BROADCAST : WPI_ID_BSS; + tx->len = htole16( m0->m_pkthdr.len); - if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { - tx->flags |= htole32(WPI_TX_NEED_ACK); - } else if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) { - tx->flags |= htole32(WPI_TX_NEED_RTS | WPI_TX_FULL_TXOP); + if (ismcast) { + if ((ni->ni_flags & IEEE80211_NODE_QOS) == 0 || + !cap->cap_wmeParams[ac].wmep_noackPolicy) + tx->flags |= htole32(WPI_TX_NEED_ACK); + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) { + tx->flags |= htole32(WPI_TX_NEED_RTS|WPI_TX_FULL_TXOP); + tx->rts_ntries = 7; + } } - tx->flags |= htole32(WPI_TX_AUTO_SEQ); - - tx->id = IEEE80211_IS_MULTICAST(wh->i_addr1) ? WPI_ID_BROADCAST : - WPI_ID_BSS; - - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { + /* pick a rate */ + if((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MASK){ uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; /* tell h/w to set timestamp in probe responses */ if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) - tx->flags |= htole32(WPI_TX_INSERT_TSTAMP); + tx->flags |= htole32(WPI_TX_INSERT_TSTAMP); if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ || - subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) + subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) tx->timeout = htole16(3); else tx->timeout = htole16(2); - } else - tx->timeout = htole16(0); + rate = ni->ni_rates.rs_rates[0] & IEEE80211_RATE_VAL; + } else if (ismcast ){ + rate = ic->ic_mcast_rate; + } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE){ + rate = ic->ic_fixed_rate; + } else { + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + rate &= IEEE80211_RATE_VAL; + } tx->rate = wpi_plcp_signal(rate); /* be very persistant at sending frames out */ - tx->rts_ntries = 7; - tx->data_ntries = 15; + tx->data_ntries = 15; /* XXX Way too high */ - tx->ofdm_mask = 0xff; - tx->cck_mask = 0x0f; - tx->lifetime = htole32(WPI_LIFETIME_INFINITE); +#ifndef WPI_CURRENT + if (sc->sc_drvbpf != NULL ){ +#else + if (bpf_peers_present(sc->sc_drvbpf)){ +#endif + struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; + tap->wt_flags = 0; + tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); + tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); + tap->wt_rate = rate; + tap->wt_hwqueue = ac; + if (wh->i_fc[1] & IEEE80211_FC1_WEP) + tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; - tx->len = htole16(m0->m_pkthdr.len); + bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + } /* save and trim IEEE802.11 header */ m_copydata(m0, 0, hdrlen, (caddr_t)&tx->wh); @@ -2227,10 +2197,7 @@ continue; } - /* no QoS encapsulation for EAPOL frames */ - ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ? - M_WME_GETAC(m0) : WME_AC_BE; - + ac = M_WME_GETAC(m0); if (sc->txq[ac].queued > sc->txq[ac].count - 8) { /* there is no place left in this ring */ IFQ_DRV_PREPEND(&ifp->if_snd, m0); @@ -2262,7 +2229,6 @@ } sc->sc_tx_timer = 5; - sc->watchdog_cnt = 5; ic->ic_lastdata = ticks; } @@ -2277,17 +2243,12 @@ WPI_LOCK(sc); - DPRINTFN(WPI_DEBUG_WATCHDOG, ("watchdog_cnt: %d\n", sc->watchdog_cnt)); - - if (sc->watchdog_cnt == 0 || --sc->watchdog_cnt) - goto done; - - if (--sc->sc_tx_timer != 0) { + DPRINTFN(WPI_DEBUG_WATCHDOG, ("tx_timer: %d\n", sc->sc_tx_timer)); + if (sc->sc_tx_timer && --sc->sc_tx_timer != 0) { device_printf(sc->sc_dev,"device timeout\n"); ifp->if_oerrors++; taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); } -done: WPI_UNLOCK(sc); } @@ -2685,6 +2646,7 @@ wpi_scan(struct wpi_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_scan_state *ss = ic->ic_scan; struct wpi_tx_ring *ring = &sc->cmdq; struct wpi_tx_desc *desc; struct wpi_tx_data *data; @@ -2696,7 +2658,7 @@ struct ieee80211_channel *c; enum ieee80211_phymode mode; uint8_t *frm; - int nrates, pktlen, error; + int nrates, pktlen, error, i, nssid; bus_addr_t physaddr; struct ifnet *ifp = ic->ic_ifp; @@ -2743,17 +2705,21 @@ hdr->tx.flags = htole32(WPI_TX_AUTO_SEQ); /*XXX Need to cater for multiple essids */ - memset(&hdr->scan_essids[0], 0, 4 * sizeof(hdr->scan_essids[0])); - hdr->scan_essids[0].id = IEEE80211_ELEMID_SSID; - hdr->scan_essids[0].esslen = ic->ic_des_ssid[0].len; - memcpy(hdr->scan_essids[0].essid, ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - - if (wpi_debug & WPI_DEBUG_SCANNING) { + memset(&hdr->scan_essids, 0, sizeof(hdr->scan_essids)); + nssid = MIN(ss->ss_nssid, WPI_SCAN_MAX_ESSIDS); + for(i = 0; i < nssid; i++ ){ + hdr->scan_essids[i].id = IEEE80211_ELEMID_SSID; + hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, 32); + memcpy(hdr->scan_essids[i].essid, ss->ss_ssid[i].ssid, + hdr->scan_essids[i].esslen); +#ifdef WPI_DEBUG + if (wpi_debug & WPI_DEBUG_SCANNING) { printf("Scanning Essid: "); - ieee80211_print_essid(ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); + ieee80211_print_essid(ic->ic_des_ssid[i].ssid, + ic->ic_des_ssid[i].len); printf("\n"); + } +#endif } /* @@ -3259,7 +3225,7 @@ uint32_t tmp; int ac; - sc->watchdog_cnt = sc->sc_tx_timer = 0; + sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* disable interrupts */ @@ -3905,7 +3871,7 @@ default: KASSERT(1, ("Unknown Command: %d\n", cmd)); - return "UNKNOWN CMD"; // Make the compiler happy + return "UNKNOWN CMD"; /* Make the compiler happy */ } } #endif