Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Jun 2007 21:08:00 GMT
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 122500 for review
Message-ID:  <200706282108.l5SL80Xi081508@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122500

Change 122500 by thompsa@thompsa_heff on 2007/06/28 21:07:01

	Fix wi in the new world order
	 - the channels are no longer indexed by ieee number [1]
	 - Fix scanning when the firmware can only do all chans
	 - the rate from the firmware is in different units
	 - pass IEEE80211_S_SCAN to net80211 so it can kick off scanning
	 - fix overflow in rates[] from wi_scan_result
	 - dont disard after mindwell in ieee80211_add_scan
	 - ieee80211_scanparams takes a pointer to the channel
	
	 Submitted by: Tai-hwa Liang [1]

Affected files ...

.. //depot/projects/wifi/sys/dev/wi/if_wi.c#36 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#107 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan.c#14 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan.h#9 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#20 edit

Differences ...

==== //depot/projects/wifi/sys/dev/wi/if_wi.c#36 (text+ko) ====

@@ -165,6 +165,8 @@
 static int wi_symbol_set_hcr(struct wi_softc *, int);
 
 static void wi_scan_start(struct ieee80211com *);
+static void wi_scan_curchan(struct ieee80211com *, unsigned long);
+static void wi_scan_mindwell(struct ieee80211com *);
 static void wi_scan_end(struct ieee80211com *);
 static void wi_set_channel(struct ieee80211com *);
 static void wi_update_slot(struct ifnet *);
@@ -369,8 +371,9 @@
 		val = le16toh(val);
 		ic->ic_bsschan = ieee80211_find_channel(ic,
 			ieee80211_ieee2mhz(val, IEEE80211_CHAN_B),
-			IEEE80211_MODE_AUTO);
-		/* XXX check return value */
+			IEEE80211_CHAN_B);
+		if (ic->ic_bsschan == NULL)
+			ic->ic_bsschan = &ic->ic_channels[0];
 	} else {
 		device_printf(dev,
 			"WI_RID_OWN_CHNL failed, using first channel!\n");
@@ -467,7 +470,6 @@
 				rs->rs_rates[rs->rs_nrates++] = ratebuf[2+i];
 	} else {
 		/* XXX fallback on error? */
-		rs->rs_nrates = 0;
 	}
 
 	buflen = sizeof(val);
@@ -504,6 +506,8 @@
 	ic->ic_raw_xmit = wi_raw_xmit;
 
 	ic->ic_scan_start = wi_scan_start;
+	ic->ic_scan_curchan = wi_scan_curchan;
+	ic->ic_scan_mindwell = wi_scan_mindwell;
 	ic->ic_scan_end = wi_scan_end;
 	ic->ic_set_channel = wi_set_channel;
 	ic->ic_node_alloc = wi_node_alloc;
@@ -1922,9 +1926,9 @@
 	case WI_INFO_SCAN_RESULTS:
 	case WI_INFO_HOST_SCAN_RESULTS:
 		wi_scan_result(sc, fid, le16toh(ltbuf[0]));
-		ieee80211_notify_scan_done(ic);
+		ieee80211_scan_done(ic);
 		break;
-		
+
 	default:
 		DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
 		    le16toh(ltbuf[1]), le16toh(ltbuf[0])));
@@ -2952,6 +2956,8 @@
 		return (*sc->sc_newstate)(ic, nstate, arg);
 
 	case IEEE80211_S_SCAN:
+		return (*sc->sc_newstate)(ic, nstate, arg);
+
 	case IEEE80211_S_AUTH:
 	case IEEE80211_S_ASSOC:
 		ic->ic_state = nstate;	/* NB: skip normal ieee80211 handling */
@@ -2966,8 +2972,12 @@
 		IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid);
 		buflen = sizeof(val);
 		wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
+		ni->ni_chan = ieee80211_find_channel(ic,
+		    ieee80211_ieee2mhz(val, IEEE80211_CHAN_B),
+		    IEEE80211_CHAN_B);
+		if (ni->ni_chan == NULL)
+			ni->ni_chan = &ic->ic_channels[0];
 		/* XXX validate channel */
-		ni->ni_chan = &ic->ic_channels[le16toh(val)];
 		ic->ic_curchan = ic->ic_bsschan = ni->ni_chan;
 #if NBPFILTER > 0
 		sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
@@ -3085,7 +3095,7 @@
 	memset(&ws_dat, 0, sizeof(ws_dat));
 
 	for (i = 0; i < naps; i++, ap++) {
-		uint8_t rates[2];
+		uint8_t rates[2 + IEEE80211_RATE_MAXSIZE];
 		uint16_t *bssid;
 		wi_read_bap(sc, fid, off, &ws_dat,
 		    (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf));
@@ -3102,7 +3112,7 @@
 
 		memcpy(wh.i_addr2, ws_dat.wi_bssid, sizeof(ap->bssid));
 		memcpy(wh.i_addr3, ws_dat.wi_bssid, sizeof(ap->bssid));
-		sp.chan = ap->channel = le16toh(ws_dat.wi_chid);
+		ap->channel = le16toh(ws_dat.wi_chid);
 		ap->signal  = le16toh(ws_dat.wi_signal);
 		ap->noise   = le16toh(ws_dat.wi_noise);
 		ap->quality = ap->signal - ap->noise;
@@ -3110,7 +3120,7 @@
 		sp.bintval = ap->interval = le16toh(ws_dat.wi_interval);
 		ap->rate = le16toh(ws_dat.wi_rate);
 		rates[1] = 1;
-		rates[2] = (uint8_t)ap->rate;
+		rates[2] = (uint8_t)ap->rate / 5;
 		ap->namelen = le16toh(ws_dat.wi_namelen);
 		if (ap->namelen > sizeof(ap->name))
 			ap->namelen = sizeof(ap->name);
@@ -3118,9 +3128,15 @@
 		sp.ssid = (uint8_t *)&ssid[0];
 		memcpy(sp.ssid + 2, ap->name, ap->namelen);
 		sp.ssid[1] = ap->namelen;
+		sp.chan = ieee80211_find_channel(ic,
+			ieee80211_ieee2mhz(ap->channel, IEEE80211_CHAN_B),
+			IEEE80211_CHAN_B);
+		if (sp.chan == NULL)
+			sp.chan = &ic->ic_channels[0];
 		sp.rates = &rates[0];
 		sp.tstamp = (uint8_t *)&rstamp;
-		printf("calling add_scan \n");
+		DPRINTF(("calling add_scan, bssid %s chan %d signal %d\n",
+		    ether_sprintf(ws_dat.wi_bssid), ap->channel, ap->signal));
 		ieee80211_add_scan(ic, &sp, &wh, 0, ap->signal, ap->noise, rstamp);
 	}
 done:
@@ -3536,6 +3552,18 @@
 }
 
 static void
+wi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell)
+{
+	/* The firmware is not capable of scanning a single channel */
+}
+
+static void
+wi_scan_mindwell(struct ieee80211com *ic)
+{
+	/* NB: don't try to abort scan; wait for firmware to finish */
+}
+
+static void
 wi_scan_end(struct ieee80211com *ic)
 {
 	struct ifnet *ifp = ic->ic_ifp;

==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#107 (text+ko) ====

@@ -2090,7 +2090,7 @@
 		scan.tstamp  = frm;				frm += 8;
 		scan.bintval = le16toh(*(uint16_t *)frm);	frm += 2;
 		scan.capinfo = le16toh(*(uint16_t *)frm);	frm += 2;
-		scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+		scan.bchan = ic->ic_curchan;
 		scan.chan = scan.bchan;
 
 		while (efrm - frm > 1) {

==== //depot/projects/wifi/sys/net80211/ieee80211_scan.c#14 (text+ko) ====

@@ -633,6 +633,19 @@
 }
 
 /*
+ * Public access to scan_next for drivers that are not able to scan single
+ * channels (e.g. for firmware-based devices).
+ */
+void
+ieee80211_scan_done(struct ieee80211com *ic)
+{
+	struct ieee80211_scan_state *ss = ic->ic_scan;
+
+	ss->ss_next = ss->ss_last; /* all channels are complete */
+	scan_next(ss);
+}
+
+/*
  * Scan curchan.  If this is an active scan and the channel
  * is not marked passive then send probe request frame(s).
  * Arrange for the channel change after maxdwell ticks.
@@ -833,7 +846,7 @@
 
 #ifdef IEEE80211_DEBUG
 static void
-dump_probe_beacon(uint8_t subtype, int isnew,
+dump_probe_beacon(struct ieee80211com *ic, uint8_t subtype, int isnew,
 	const uint8_t mac[IEEE80211_ADDR_LEN],
 	const struct ieee80211_scanparams *sp)
 {
@@ -841,7 +854,8 @@
 	printf("[%s] %s%s on chan %u (bss chan %u) ",
 	    ether_sprintf(mac), isnew ? "new " : "",
 	    ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
-	    sp->chan, sp->bchan);
+	    ieee80211_chan2ieee(ic, sp->chan),
+	    ieee80211_chan2ieee(ic, sp->bchan));
 	ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]);
 	printf("\n");
 
@@ -887,7 +901,7 @@
 		return;
 #ifdef IEEE80211_DEBUG
 	if (ieee80211_msg_scan(ic) && (ic->ic_flags & IEEE80211_F_SCAN))
-		dump_probe_beacon(subtype, 1, wh->i_addr2, sp);
+		dump_probe_beacon(ic, subtype, 1, wh->i_addr2, sp);
 #endif
 	if (ss->ss_ops != NULL &&
 	    ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise, rstamp)) {
@@ -903,17 +917,7 @@
 			    ieee80211_chan2ieee(ic, ic->ic_curchan),
 				channel_type(ic->ic_curchan),
 			    ticks, SCAN_PRIVATE(ss)->ss_chanmindwell);
-			/*
-			 * XXX
-			 * We want to just kick the timer and still
-			 * process frames until it fires but linux
-			 * will livelock unless we discard frames.
-			 */
-#if 0
 			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_MINDWELL;
-#else
-			SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_DISCARD;
-#endif
 			/*
 			 * NB: trigger at next clock tick or wait for the
 			 * hardware

==== //depot/projects/wifi/sys/net80211/ieee80211_scan.h#9 (text+ko) ====

@@ -89,6 +89,7 @@
 int	ieee80211_bg_scan(struct ieee80211com *);
 void	ieee80211_cancel_scan(struct ieee80211com *);
 void	ieee80211_scan_next(struct ieee80211com *);
+void	ieee80211_scan_done(struct ieee80211com *);
 
 struct ieee80211_scanparams;
 void	ieee80211_add_scan(struct ieee80211com *,
@@ -123,8 +124,8 @@
 struct ieee80211_scanparams {
 	uint16_t	capinfo;	/* 802.11 capabilities */
 	uint16_t	fhdwell;	/* FHSS dwell interval */
-	uint8_t		chan;		/* */
-	uint8_t		bchan;
+	struct ieee80211_channel *chan;
+	struct ieee80211_channel *bchan;
 	uint8_t		fhindex;
 	uint8_t		erp;
 	uint16_t	bintval;

==== //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#20 (text+ko) ====

@@ -263,7 +263,7 @@
 	memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));
 	ise->se_intval = sp->bintval;
 	ise->se_capinfo = sp->capinfo;
-	ise->se_chan = ic->ic_curchan;
+	ise->se_chan = sp->chan;
 	ise->se_fhdwell = sp->fhdwell;
 	ise->se_fhindex = sp->fhindex;
 	ise->se_erp = sp->erp;



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