stopping ndis caused fatal trap 12
Andrew Thompson
thompsa at FreeBSD.org
Fri Jul 20 00:10:45 UTC 2007
On Wed, Jul 18, 2007 at 06:07:37PM -0500, Scot Hetzel wrote:
> On 7/15/07, Andrew Thompson <thompsa at freebsd.org> wrote:
> >On Sun, Jul 15, 2007 at 05:32:32AM -0500, Scot Hetzel wrote:
> >> hp010# uname -a
> >> FreeBSD hp010 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Sat Jul 14 02:20:09
> >> CDT 2007 root at hp010:/usr/src/7x/sys-p4/amd64/compile/GENERIC.debug
> >> amd64
> >>
> >> I was testing wpa_supplicant at work, and couldn't get it to associate
> >> with the network (open, no encryption), and so I had hardcoded the
> >> network. When I went home and booted the system, it still had the
> >> hardcoded wireless network configured. I then did a netif stop ndis0,
> >> made the change to set ndis to "WPA DHCP", then when I used 'netif
> >> start ndis0', it didn't obtain an IP. So I performed an 'netif stop
> >> ndis0' and received the following panic:
> >>
> >So back to the ndis association problem. Did the card find the access
> >point? you can list the scan cache from 'ifconfig ndis0 list scan'.
> >
>
> ifconfig ndis0 scan ; ifconfig ndis0 list scan don't return with any
> results, but if I run wpa_cli, and do a scan and scan_results it lists
> the APs.
Can you (and anyone else having ndis assosciate problems) please try
these two patches.
ndis_scan9.diff applies in sys/dev/if_ndis, and scan_sta1.diff applies
in sys/net80211. I have kept them seperate as Sephe is due to commit
scan_sta1.diff shortly and may have already done so before you get to
test.
cheers,
Andrew
-------------- next part --------------
Index: if_ndis.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/if_ndis/if_ndis.c,v
retrieving revision 1.123
diff -u -p -r1.123 if_ndis.c
--- if_ndis.c 12 Jul 2007 02:54:05 -0000 1.123
+++ if_ndis.c 19 Jul 2007 23:57:59 -0000
@@ -48,9 +48,7 @@ __FBSDID("$FreeBSD: src/sys/dev/if_ndis/
#include <sys/queue.h>
#include <sys/module.h>
#include <sys/proc.h>
-#if __FreeBSD_version < 502113
#include <sys/sysctl.h>
-#endif
#include <sys/kthread.h>
#include <sys/taskqueue.h>
@@ -89,8 +87,12 @@ __FBSDID("$FreeBSD: src/sys/dev/if_ndis/
#include <compat/ndis/ndis_var.h>
#include <dev/if_ndis/if_ndisvar.h>
+#define NDIS_DEBUG
#ifdef NDIS_DEBUG
-#define DPRINTF(x) printf x
+#define DPRINTF(x) do { if (ndis_debug > 0) printf x; } while (0)
+int ndis_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, ndis, CTLFLAG_RW, &ndis_debug, 0,
+ "if_ndis debug level");
#else
#define DPRINTF(x)
#endif
@@ -752,11 +754,16 @@ ndis_attach(dev)
setbit(&bands, IEEE80211_MODE_11G);
break;
default:
+ device_printf(dev, "Unknown nettype %d\n",
+ ntl->ntl_type[i]);
break;
}
}
free(ntl, M_DEVBUF);
nonettypes:
+ /* Default to 11b channels if the card did not supply any */
+ if (bands == 0)
+ setbit(&bands, IEEE80211_MODE_11B);
len = sizeof(rates);
bzero((char *)&rates, len);
r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES,
@@ -2739,7 +2746,6 @@ ndis_getstate_80211(sc)
if (ic->ic_curchan == NULL)
ic->ic_curchan = &ic->ic_channels[0];
ic->ic_bss->ni_chan = ic->ic_curchan;
- ic->ic_des_chan = ic->ic_curchan;
ic->ic_bsschan = ic->ic_curchan;
free(bs, M_TEMP);
@@ -3502,12 +3508,37 @@ ndis_scan(void *arg, int npending)
{
struct ndis_softc *sc = arg;
struct ieee80211com *ic = (void *)&sc->ic;
+ struct ieee80211_scan_state *ss = ic->ic_scan;
+ ndis_80211_ssid ssid;
int error, len;
+ if (!NDIS_INITIALIZED(sc)) {
+ DPRINTF(("%s: scan aborted\n", __func__));
+ ieee80211_cancel_scan(ic);
+ return;
+ }
+
+ if (ss->ss_nssid != 0) {
+ len = sizeof(ssid);
+ bzero((char *)&ssid, len);
+ ssid.ns_ssidlen = ss->ss_ssid[0].len;
+ bcopy(ss->ss_ssid[0].ssid, ssid.ns_ssid, ssid.ns_ssidlen);
+
+ error = ndis_set_info(sc, OID_802_11_SSID, &ssid, &len);
+ if (error)
+ DPRINTF(("%s: set ESSID failed\n", __func__));
+ }
+
len = 0;
error = ndis_set_info(sc, OID_802_11_BSSID_LIST_SCAN,
NULL, &len);
- tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2);
+ if (error) {
+ DPRINTF(("%s: scan command failed\n", __func__));
+ ieee80211_cancel_scan(ic);
+ return;
+ }
+
+ tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 3);
ndis_scan_results(sc);
ieee80211_scan_done(ic);
}
@@ -3521,7 +3552,7 @@ ndis_scan_results(struct ndis_softc *sc)
struct ieee80211_scanparams sp;
struct ieee80211_frame wh;
int i, j;
- int error, len, rssi, noise;
+ int error, len, rssi, noise, freq, chanflag;
static long rstamp;
uint8_t ssid[2+IEEE80211_NWID_LEN];
uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
@@ -3535,10 +3566,12 @@ ndis_scan_results(struct ndis_softc *sc)
bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len);
if (error) {
+ DPRINTF(("%s: failed to read\n", __func__));
free(bl, M_DEVBUF);
return;;
}
+ DPRINTF(("%s: %d results\n", __func__, bl->nblx_items));
rstamp++;
wb = &bl->nblx_bssid[0];
for (i = 0; i < bl->nblx_items; i++) {
@@ -3546,7 +3579,7 @@ ndis_scan_results(struct ndis_softc *sc)
memcpy(wh.i_addr2, wb->nwbx_macaddr, sizeof(wh.i_addr2));
memcpy(wh.i_addr3, wb->nwbx_macaddr, sizeof(wh.i_addr3));
- rssi = (wb->nwbx_rssi - noise) / (-32 - noise) * 100;
+ rssi = 100 * (wb->nwbx_rssi - noise) / (-32 - noise);
rssi = max(0, min(rssi, 100)); /* limit 0 <= rssi <= 100 */
if (wb->nwbx_privacy)
sp.capinfo |= IEEE80211_CAPINFO_PRIVACY;
@@ -3559,6 +3592,21 @@ ndis_scan_results(struct ndis_softc *sc)
sp.capinfo |= IEEE80211_CAPINFO_ESS;
break;
}
+ switch(wb->nwbx_nettype) {
+ case NDIS_80211_NETTYPE_11FH:
+ case NDIS_80211_NETTYPE_11DS:
+ chanflag = IEEE80211_CHAN_B;
+ break;
+ case NDIS_80211_NETTYPE_11OFDM5:
+ chanflag = IEEE80211_CHAN_A;
+ break;
+ case NDIS_80211_NETTYPE_11OFDM24:
+ chanflag = IEEE80211_CHAN_G;
+ break;
+ default:
+ chanflag = IEEE80211_CHAN_B;
+ break;
+ }
sp.rates = &rates[0];
for (j = 0; j < IEEE80211_RATE_MAXSIZE; j++) {
/* XXX - check units */
@@ -3573,11 +3621,9 @@ ndis_scan_results(struct ndis_softc *sc)
wb->nwbx_ssid.ns_ssidlen);
sp.ssid[1] = wb->nwbx_ssid.ns_ssidlen;
- sp.bchan = ieee80211_mhz2ieee(
- wb->nwbx_config.nc_dsconfig / 1000, 0);
- sp.curchan = ieee80211_find_channel(ic,
- ieee80211_ieee2mhz(sp.bchan, IEEE80211_CHAN_B),
- IEEE80211_CHAN_B);
+ freq = wb->nwbx_config.nc_dsconfig / 1000;
+ sp.bchan = ieee80211_mhz2ieee( freq, chanflag);
+ sp.curchan = ieee80211_find_channel(ic, freq, chanflag);
if (sp.curchan == NULL)
sp.curchan = &ic->ic_channels[0];
@@ -3607,9 +3653,13 @@ ndis_scan_results(struct ndis_softc *sc)
}
}
done:
+ DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n",
+ ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag,
+ rssi));
ieee80211_add_scan(ic, &sp, &wh, 0, rssi, noise, rstamp);
wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len);
}
+ free(bl, M_DEVBUF);
}
static void
-------------- next part --------------
==== //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#24 - /opt/sam_wifi/sys/net80211/ieee80211_scan_sta.c ====
--- /tmp/tmp.610.42 2007-07-18 19:26:45.000000000 +0800
+++ /opt/sam_wifi/sys/net80211/ieee80211_scan_sta.c 2007-07-18 19:26:15.000000000 +0800
@@ -376,17 +376,23 @@ add_channels(struct ieee80211com *ic,
break;
c = ieee80211_find_channel(ic, freq[i], modeflags);
- if (c == NULL || isexcluded(ic, c))
+ if (c != NULL && isexcluded(ic, c))
continue;
if (mode == IEEE80211_MODE_AUTO) {
/*
* XXX special-case 11b/g channels so we select
- * the g channel if both are present.
+ * the g channel if both are present or there
+ * are only g channels.
*/
- if (IEEE80211_IS_CHAN_B(c) &&
- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
- c = cg;
+ if (c == NULL || IEEE80211_IS_CHAN_B(c)) {
+ cg = find11gchannel(ic, i, freq[i]);
+ if (cg != NULL)
+ c = cg;
+ }
}
+ if (c == NULL)
+ continue;
+
ss->ss_chans[ss->ss_last++] = c;
}
#undef N
More information about the freebsd-current
mailing list