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:
parent
f1c599147f
commit
d1a5f43855
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129834
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user