In subr_ndis.c, when searching for keys in our make-pretend registry,

make the key name matching case-insensitive. There are some drivers
and .inf files that have mismatched cases, e.g. the driver will look
for "AdhocBand" whereas the .inf file specifies a registry key to be
created called "AdHocBand." The mismatch is probably a typo that went
undetected (so much for QA), but since Windows seems to be case-insensitive,
we should be too.

In if_ndis.c, initialize rates and channels correctly so that specify
frequences correctly when trying to set channels in the 5Ghz band, and
so that 802.11b rates show up for some a/b/g cards (which otherwise
appear to have no 802.11b modes).

Also, when setting OID_802_11_CONFIGURATION in ndis_80211_setstate(),
provide default values for the beacon interval, ATIM window and dwelltime.
The Atheros "Aries" driver will crash if you try to select ad-hoc mode
and leave the beacon interval set to 0: it blindly uses this value and
does a division by 0 in the interrupt handler, causing an integer
divide trap.
This commit is contained in:
Bill Paul 2004-05-29 06:41:17 +00:00
parent f1c599147f
commit d1a5f43855
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129834
2 changed files with 71 additions and 5 deletions

View File

@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
*/
#include <sys/ctype.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
@ -554,6 +555,22 @@ ndis_encode_parm(block, oid, type, parm)
return(NDIS_STATUS_SUCCESS);
}
static int
my_strcasecmp(s1, s2, len)
const char *s1;
const char *s2;
int len;
{
int i;
for (i = 0; i < len; i++) {
if (toupper(s1[i]) != toupper(s2[i]))
return(1);
}
return(0);
}
__stdcall static void
ndis_read_cfg(status, parm, cfg, key, type)
ndis_status *status;
@ -589,7 +606,8 @@ ndis_read_cfg(status, parm, cfg, key, type)
*/
TAILQ_FOREACH(e, &sc->ndis_ctx, link) {
oidp = e->entry;
if (strcmp(oidp->oid_name, keystr) == 0) {
if (my_strcasecmp(oidp->oid_name,
keystr, strlen(keystr)) == 0) {
if (strcmp((char *)oidp->oid_arg1, "UNSET") == 0) {
free(keystr, M_DEVBUF);
*status = NDIS_STATUS_FAILURE;
@ -685,7 +703,8 @@ ndis_write_cfg(status, cfg, key, parm)
TAILQ_FOREACH(e, &sc->ndis_ctx, link) {
oidp = e->entry;
if (strcmp(oidp->oid_name, keystr) == 0) {
if (my_strcasecmp(oidp->oid_name,
keystr, strlen(keystr)) == 0) {
/* Found it, set the value. */
strcpy((char *)oidp->oid_arg1, val);
free(keystr, M_DEVBUF);

View File

@ -484,7 +484,7 @@ ndis_attach(dev)
/* Do media setup */
if (sc->ndis_80211) {
struct ieee80211com *ic = (void *)ifp;
ndis_80211_rates_ex rates;
ndis_80211_rates/*_ex*/ rates;
struct ndis_80211_nettype_list *ntl;
uint32_t arg;
int r;
@ -510,8 +510,6 @@ ndis_attach(dev)
for (i = 0; i < ntl->ntl_items; i++) {
switch (ntl->ntl_type[i]) {
case NDIS_80211_NETTYPE_11FH:
ic->ic_modecaps |= (1<<IEEE80211_MODE_11B);
break;
case NDIS_80211_NETTYPE_11DS:
ic->ic_modecaps |= (1<<IEEE80211_MODE_11B);
break;
@ -602,6 +600,12 @@ ndis_attach(dev)
* just cheat here. Just how in the heck do
* we detect turbo modes, though?
*/
if (ic->ic_modecaps & (1<<IEEE80211_MODE_11B)) {
TESTSETRATE(IEEE80211_MODE_11B, 2);
TESTSETRATE(IEEE80211_MODE_11B, 4);
TESTSETRATE(IEEE80211_MODE_11B, 11);
TESTSETRATE(IEEE80211_MODE_11B, 22);
}
if (ic->ic_modecaps & (1<<IEEE80211_MODE_11G)) {
TESTSETRATE(IEEE80211_MODE_11G, 47);
TESTSETRATE(IEEE80211_MODE_11G, 72);
@ -626,6 +630,8 @@ ndis_attach(dev)
chanflag |= IEEE80211_CHAN_G;
if (i <= 14)
chanflag |= IEEE80211_CHAN_B;
if (i > 14)
chanflag = IEEE80211_CHAN_A;
if (chanflag == 0)
break;
ic->ic_channels[i].ic_freq =
@ -1508,12 +1514,53 @@ ndis_setstate_80211(sc)
device_printf (sc->ndis_dev, "set auth failed: %d\n", rval);
#endif
#ifdef notyet
/* Set network type. */
arg = 0;
switch (ic->ic_curmode) {
case IEEE80211_MODE_11A:
arg = NDIS_80211_NETTYPE_11OFDM5;
break;
case IEEE80211_MODE_11B:
arg = NDIS_80211_NETTYPE_11DS;
break;
case IEEE80211_MODE_11G:
arg = NDIS_80211_NETTYPE_11OFDM24;
break;
default:
device_printf(sc->ndis_dev, "unknown mode: %d\n",
ic->ic_curmode);
}
#endif
if (arg) {
len = sizeof(arg);
rval = ndis_set_info(sc, OID_802_11_NETWORK_TYPE_IN_USE,
&arg, &len);
if (rval)
device_printf (sc->ndis_dev,
"set nettype failed: %d\n", rval);
}
len = sizeof(config);
bzero((char *)&config, len);
config.nc_length = len;
config.nc_fhconfig.ncf_length = sizeof(ndis_80211_config_fh);
rval = ndis_get_info(sc, OID_802_11_CONFIGURATION, &config, &len);
/*
* Some drivers expect us to initialize these values, so
* provide some defaults.
*/
if (config.nc_beaconperiod == 0)
config.nc_beaconperiod = 100;
if (config.nc_atimwin == 0)
config.nc_atimwin = 100;
if (config.nc_fhconfig.ncf_dwelltime == 0)
config.nc_fhconfig.ncf_dwelltime = 200;
if (rval == 0 && ic->ic_ibss_chan != IEEE80211_CHAN_ANYC) {
int chan, chanflag;