Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Feb 2008 23:51:18 GMT
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 135686 for review
Message-ID:  <200802182351.m1INpIlj004210@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802182351.m1INpIlj004210>