📄 ieee80211_wireless.c
字号:
if (mode == IEEE80211_MODE_TURBO_STATIC_A) ifr_mode = IEEE80211_MODE_11A; ifr.ifr_media |= IFM_MAKEMODE(ifr_mode); retv = ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA); if ((!retv || retv == ENETRESET) && mode != vap->iv_des_mode) { ieee80211_scan_flush(ic); /* NB: could optimize */ vap->iv_des_mode = mode; if (IS_UP_AUTO(vap)) { ieee80211_cancel_scan(vap); itr_count = 0; while((ic->ic_flags & IEEE80211_F_SCAN) != 0) { mdelay(1); if (itr_count < 100) { itr_count++; continue; } IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: Timeout cancelling current scan.\n", __func__); return -ETIMEDOUT; } ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); } retv = 0; }#ifdef ATH_SUPERG_XR /* set the same params on the xr vap device if exists */ if (vap->iv_xrvap && !(vap->iv_flags & IEEE80211_F_XR)) vap->iv_xrvap->iv_des_mode = mode;#endif return -retv;}#undef IEEE80211_MODE_TURBO_STATIC_A#ifdef ATH_SUPERG_XRstatic voidieee80211_setupxr(struct ieee80211vap *vap){ struct net_device *dev = vap->iv_dev; struct ieee80211com *ic = vap->iv_ic; if (!(vap->iv_flags & IEEE80211_F_XR)) { if ((vap->iv_ath_cap & IEEE80211_ATHC_XR) && !vap->iv_xrvap) { char name[IFNAMSIZ]; strcpy(name, dev->name); strcat(name, "-xr"); /* * create a new XR vap. if the normal VAP is already up, * bring up the XR vap aswell. */ vap->iv_ath_cap &= ~IEEE80211_ATHC_TURBOP; /* turn off turbo */ ieee80211_scan_flush(ic); /* NB: could optimize */ vap->iv_xrvap = ic->ic_vap_create(ic, name, vap->iv_unit, IEEE80211_M_HOSTAP,IEEE80211_VAP_XR | IEEE80211_CLONE_BSSID, dev); vap->iv_xrvap->iv_fragthreshold = IEEE80211_XR_FRAG_THRESHOLD; copy_des_ssid(vap->iv_xrvap, vap); vap->iv_xrvap->iv_des_mode = vap->iv_des_mode; } else if (!(vap->iv_ath_cap & IEEE80211_ATHC_XR) && vap->iv_xrvap) { /* * destroy the XR vap. if the XR VAP is up , bring * it down before destroying. */ if (vap->iv_xrvap) { ieee80211_stop(vap->iv_xrvap->iv_dev); ic->ic_vap_delete(vap->iv_xrvap); } vap->iv_xrvap = NULL; } }}#endifstatic intieee80211_setathcap(struct ieee80211vap *vap, int cap, int setting){ struct ieee80211com *ic = vap->iv_ic; int ocap; if ((ic->ic_ath_cap & cap) == 0) return -EINVAL; ocap = vap->iv_ath_cap; if (setting) vap->iv_ath_cap |= cap; else vap->iv_ath_cap &= ~cap; return (vap->iv_ath_cap != ocap ? ENETRESET : 0);}static intieee80211_set_turbo(struct net_device *dev, int flag){ struct ieee80211vap *vap = dev->priv; struct ieee80211com *ic = vap->iv_ic; struct ifreq ifr; struct ieee80211vap *tmpvap = dev->priv; int nvap = 0; TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) nvap++; if (nvap > 1 && flag ) return -EINVAL; ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media &~ IFM_MMASK; if (flag) ifr.ifr_media |= IFM_IEEE80211_TURBO; else ifr.ifr_media &= ~IFM_IEEE80211_TURBO; (void) ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA); return 0;}static intieee80211_ioctl_setparam(struct net_device *dev, struct iw_request_info *info, void *w, char *extra){ struct ieee80211vap *vap = dev->priv; struct ieee80211com *ic = vap->iv_ic; struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn; int *i = (int *) extra; int param = i[0]; /* parameter id is 1st */ int value = i[1]; /* NB: most values are TYPE_INT */ int retv = 0; int j, caps; const struct ieee80211_authenticator *auth; const struct ieee80211_aclator *acl; switch (param) { case IEEE80211_PARAM_AUTHMODE: switch (value) { case IEEE80211_AUTH_WPA: /* WPA */ case IEEE80211_AUTH_8021X: /* 802.1x */ case IEEE80211_AUTH_OPEN: /* open */ case IEEE80211_AUTH_SHARED: /* shared-key */ case IEEE80211_AUTH_AUTO: /* auto */ auth = ieee80211_authenticator_get(value); if (auth == NULL) return -EINVAL; break; default: return -EINVAL; } switch (value) { case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ value = IEEE80211_AUTH_8021X; break; case IEEE80211_AUTH_OPEN: /* open */ vap->iv_flags &= ~(IEEE80211_F_WPA); break; case IEEE80211_AUTH_SHARED: /* shared-key */ case IEEE80211_AUTH_AUTO: /* auto */ case IEEE80211_AUTH_8021X: /* 802.1x */ vap->iv_flags &= ~IEEE80211_F_WPA; break; } /* NB: authenticator attach/detach happens on state change */ vap->iv_bss->ni_authmode = value; /* XXX mixed/mode/usage? */ vap->iv_auth = auth; retv = ENETRESET; break; case IEEE80211_PARAM_PROTMODE: if (value > IEEE80211_PROT_RTSCTS) return -EINVAL; ic->ic_protmode = value; /* NB: if not operating in 11g this can wait */ if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) retv = ENETRESET; break; case IEEE80211_PARAM_MCASTCIPHER: if ((vap->iv_caps & cipher2cap(value)) == 0 && !ieee80211_crypto_available(value)) return -EINVAL; rsn->rsn_mcastcipher = value; if (vap->iv_flags & IEEE80211_F_WPA) retv = ENETRESET; break; case IEEE80211_PARAM_MCASTKEYLEN: if (!(0 < value && value < IEEE80211_KEYBUF_SIZE)) return -EINVAL; /* XXX no way to verify driver capability */ rsn->rsn_mcastkeylen = value; if (vap->iv_flags & IEEE80211_F_WPA) retv = ENETRESET; break; case IEEE80211_PARAM_UCASTCIPHERS: /* * Convert cipher set to equivalent capabilities. * NB: this logic intentionally ignores unknown and * unsupported ciphers so folks can specify 0xff or * similar and get all available ciphers. */ caps = 0; for (j = 1; j < 32; j++) /* NB: skip WEP */ if ((value & (1 << j)) && ((vap->iv_caps & cipher2cap(j)) || ieee80211_crypto_available(j))) caps |= 1 << j; if (caps == 0) /* nothing available */ return -EINVAL; /* XXX verify ciphers ok for unicast use? */ /* XXX disallow if running as it'll have no effect */ rsn->rsn_ucastcipherset = caps; if (vap->iv_flags & IEEE80211_F_WPA) retv = ENETRESET; break; case IEEE80211_PARAM_UCASTCIPHER: if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0) return -EINVAL; rsn->rsn_ucastcipher = value; break; case IEEE80211_PARAM_UCASTKEYLEN: if (!(0 < value && value < IEEE80211_KEYBUF_SIZE)) return -EINVAL; /* XXX no way to verify driver capability */ rsn->rsn_ucastkeylen = value; break; case IEEE80211_PARAM_KEYMGTALGS: /* XXX check */ rsn->rsn_keymgmtset = value; if (vap->iv_flags & IEEE80211_F_WPA) retv = ENETRESET; break; case IEEE80211_PARAM_RSNCAPS: /* XXX check */ rsn->rsn_caps = value; if (vap->iv_flags & IEEE80211_F_WPA) retv = ENETRESET; break; case IEEE80211_PARAM_WPA: if (value > 3) return -EINVAL; /* XXX verify ciphers available */ vap->iv_flags &= ~IEEE80211_F_WPA; switch (value) { case 1: vap->iv_flags |= IEEE80211_F_WPA1; break; case 2: vap->iv_flags |= IEEE80211_F_WPA2; break; case 3: vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; break; } retv = ENETRESET; /* XXX? */ break; case IEEE80211_PARAM_ROAMING: if (!(IEEE80211_ROAMING_DEVICE <= value && value <= IEEE80211_ROAMING_MANUAL)) return -EINVAL; ic->ic_roaming = value; break; case IEEE80211_PARAM_PRIVACY: if (value) { /* XXX check for key state? */ vap->iv_flags |= IEEE80211_F_PRIVACY; } else vap->iv_flags &= ~IEEE80211_F_PRIVACY; break; case IEEE80211_PARAM_DROPUNENCRYPTED: if (value) vap->iv_flags |= IEEE80211_F_DROPUNENC; else vap->iv_flags &= ~IEEE80211_F_DROPUNENC; break; case IEEE80211_PARAM_DROPUNENC_EAPOL: if (value) IEEE80211_VAP_DROPUNENC_EAPOL_ENABLE(vap); else IEEE80211_VAP_DROPUNENC_EAPOL_DISABLE(vap); break; case IEEE80211_PARAM_COUNTERMEASURES: if (value) { if ((vap->iv_flags & IEEE80211_F_WPA) == 0) return -EINVAL; vap->iv_flags |= IEEE80211_F_COUNTERM; } else vap->iv_flags &= ~IEEE80211_F_COUNTERM; break; case IEEE80211_PARAM_DRIVER_CAPS: vap->iv_caps = value; /* NB: for testing */ break; case IEEE80211_PARAM_MACCMD: acl = vap->iv_acl; switch (value) { case IEEE80211_MACCMD_POLICY_OPEN: case IEEE80211_MACCMD_POLICY_ALLOW: case IEEE80211_MACCMD_POLICY_DENY: if (acl == NULL) { acl = ieee80211_aclator_get("mac"); if (acl == NULL || !acl->iac_attach(vap)) return -EINVAL; vap->iv_acl = acl; } acl->iac_setpolicy(vap, value); break; case IEEE80211_MACCMD_FLUSH: if (acl != NULL) acl->iac_flush(vap); /* NB: silently ignore when not in use */ break; case IEEE80211_MACCMD_DETACH: if (acl != NULL) { vap->iv_acl = NULL; acl->iac_detach(vap); } break; } break; case IEEE80211_PARAM_WMM: if (ic->ic_caps & IEEE80211_C_WME){ if (value) { vap->iv_flags |= IEEE80211_F_WME; vap->iv_ic->ic_flags |= IEEE80211_F_WME; /* XXX needed by ic_reset */ } else { vap->iv_flags &= ~IEEE80211_F_WME; vap->iv_ic->ic_flags &= ~IEEE80211_F_WME; /* XXX needed by ic_reset */ } retv = ENETRESET; /* Renegotiate for capabilities */ } break; case IEEE80211_PARAM_HIDESSID: if (value) vap->iv_flags |= IEEE80211_F_HIDESSID; else vap->iv_flags &= ~IEEE80211_F_HIDESSID; retv = ENETRESET; break; case IEEE80211_PARAM_APBRIDGE: if (value == 0) vap->iv_flags |= IEEE80211_F_NOBRIDGE; else vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; break; case IEEE80211_PARAM_INACT: vap->iv_inact_run = value / IEEE80211_INACT_WAIT; break; case IEEE80211_PARAM_INACT_AUTH: vap->iv_inact_auth = value / IEEE80211_INACT_WAIT; break; case IEEE80211_PARAM_INACT_INIT: vap->iv_inact_init = value / IEEE80211_INACT_WAIT; break; case IEEE80211_PARAM_ABOLT: caps = 0; /* * Map abolt settings to capability bits; * this also strips unknown/unwanted bits. */ if (value & IEEE80211_ABOLT_TURBO_PRIME) caps |= IEEE80211_ATHC_TURBOP; if (value & IEEE80211_ABOLT_COMPRESSION) caps |= IEEE80211_ATHC_COMP; if (value & IEEE80211_ABOLT_FAST_FRAME) caps |= IEEE80211_ATHC_FF; if (value & IEEE80211_ABOLT_XR) caps |= IEEE80211_ATHC_XR; if (value & IEEE80211_ABOLT_AR) caps |= IEEE80211_ATHC_AR; if (value & IEEE80211_ABOLT_BURST) caps |= IEEE80211_ATHC_BURST; /* verify requested capabilities are supported */ if ((caps & ic->ic_ath_cap) != caps) return -EINVAL; if (vap->iv_ath_cap != caps) { if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) { /* no turbo and XR at the same time */ if ((caps & IEEE80211_ATHC_TURBOP) && (caps & IEEE80211_ATHC_XR)) return -EINVAL; if (ieee80211_set_turbo(dev, caps & IEEE80211_ATHC_TURBOP)) return -EINVAL; ieee80211_scan_flush(ic); } vap->iv_ath_cap = caps;#ifdef ATH_SUPERG_XR ieee80211_setupxr(vap);#endif retv = ENETRESET; } break; case IEEE80211_PARAM_DTIM_PERIOD: if (vap->iv_opmode != IEEE80211_M_HOSTAP && vap->iv_opmode != IEEE80211_M_IBSS) return -EINVAL; if (IEEE80211_DTIM_MIN <= value && value <= IEEE80211_DTIM_MAX) { vap->iv_dtim_period = value; retv = ENETRESET; /* requires restart */ } else retv = EINVAL; break; case IEEE80211_PARAM_BEACON_INTERVAL: if (vap->iv_opmode != IEEE80211_M_HOSTAP && vap->iv_opmode != IEEE80211_M_IBSS) return -EINVAL; if (IEEE80211_BINTVAL_MIN <= value && value <= IEEE80211_BINTVAL_MAX) { ic->ic_lintval = value; /* XXX multi-bss */ retv = ENETRESET; /* requires restart */ } else retv = EINVAL; break; case IEEE80211_PARAM_DOTH: if (value) ic->ic_flags |= IEEE80211_F_DOTH; else ic->ic_flags &= ~IEEE80211_F_DOTH; retv = ENETRESET; /* XXX: need something this drastic? */ break; case IEEE80211_PARAM_PWRTARGET: ic->ic_curchanmaxpwr = value; break; case IEEE80211_PARAM_GENREASSOC: IEEE80211_SEND_MGMT(vap->iv_bss, IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0); break; case IEEE80211_PARAM_COMPRESSION: retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value); break; case IEEE80211_PARAM_FF: retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value); break; case IEEE80211_PARAM_TURBO: retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value); if (retv == ENETRESET) { /* no turbo and XR at the same time */ if ((vap->iv_ath_cap & IEEE80211_ATHC_XR) && value) return -EINVAL; if (ieee80211_set_turbo(dev,value)) return -EINVAL; ieee80211_scan_flush(ic); } break; case IEEE80211_PARAM_XR: /* no turbo and XR at the same time */ if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && value) return -EINVAL; retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);#ifdef ATH_SUPERG_XR ieee80211_setupxr(vap);#endif break; case IEEE80211_PARAM_BURST: retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value); break; case IEEE80211_PARAM_AR: retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value); break; case IEEE80211_PARAM_PUREG: if (value) vap->iv_flags |= IEEE80211_F_PUREG; else vap->iv_flags &= ~IEEE80211_F_PUREG; /* NB: reset only if we're operating on an 11g channel */ if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) retv = ENETRESET; break; case IEEE80211_PARAM_WDS: if (value) vap->iv_flags_ext |= IEEE80211_FEXT_WDS; else vap->iv_f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -