summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_ioctl.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-02-19 05:03:10 +0000
committersam <sam@FreeBSD.org>2009-02-19 05:03:10 +0000
commitc56d117735c50a60c1061bf389db81f0cbd8ed8b (patch)
tree00a304f4280b0256737eddb2ec25c94e6c90a5f0 /sys/net80211/ieee80211_ioctl.c
parentea09029f598e613f4bffd05be75bd5ed431d11ab (diff)
downloadFreeBSD-src-c56d117735c50a60c1061bf389db81f0cbd8ed8b.zip
FreeBSD-src-c56d117735c50a60c1061bf389db81f0cbd8ed8b.tar.gz
o looseen abi dependencies on IEEE80211_MODE_MAX by accepting smaller
parameters for IEEE80211_IOC_ROAM and IEEE80211_IOC_TXPARAMS; this lets us add more modes and still have old apps work o consolidate loops to remote assumptions about mode ordering
Diffstat (limited to 'sys/net80211/ieee80211_ioctl.c')
-rw-r--r--sys/net80211/ieee80211_ioctl.c80
1 files changed, 31 insertions, 49 deletions
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index fecef89..8c8b925 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -675,19 +675,22 @@ static __noinline int
ieee80211_ioctl_getroam(struct ieee80211vap *vap,
const struct ieee80211req *ireq)
{
- if (ireq->i_len != sizeof(vap->iv_roamparms))
- return EINVAL;
- return copyout(vap->iv_roamparms, ireq->i_data,
- sizeof(vap->iv_roamparms));
+ size_t len = ireq->i_len;
+ /* NB: accept short requests for backwards compat */
+ if (len > sizeof(vap->iv_roamparms))
+ len = sizeof(vap->iv_roamparms);
+ return copyout(vap->iv_roamparms, ireq->i_data, len);
}
static __noinline int
ieee80211_ioctl_gettxparams(struct ieee80211vap *vap,
const struct ieee80211req *ireq)
{
- if (ireq->i_len != sizeof(vap->iv_txparms))
- return EINVAL;
- return copyout(vap->iv_txparms, ireq->i_data, sizeof(vap->iv_txparms));
+ size_t len = ireq->i_len;
+ /* NB: accept short requests for backwards compat */
+ if (len > sizeof(vap->iv_txparms))
+ len = sizeof(vap->iv_txparms);
+ return copyout(vap->iv_txparms, ireq->i_data, len);
}
static __noinline int
@@ -2082,61 +2085,40 @@ ieee80211_ioctl_settxparams(struct ieee80211vap *vap,
struct ieee80211_txparams_req parms; /* XXX stack use? */
struct ieee80211_txparam *src, *dst;
const struct ieee80211_rateset *rs;
- int error, i, changed;
+ int error, mode, changed, is11n, nmodes;
- if (ireq->i_len != sizeof(parms))
+ /* NB: accept short requests for backwards compat */
+ if (ireq->i_len > sizeof(parms))
return EINVAL;
- error = copyin(ireq->i_data, &parms, sizeof(parms));
+ error = copyin(ireq->i_data, &parms, ireq->i_len);
if (error != 0)
return error;
+ nmodes = ireq->i_len / sizeof(struct ieee80211_txparam);
changed = 0;
/* validate parameters and check if anything changed */
- for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) {
- if (isclr(ic->ic_modecaps, i))
- continue;
- src = &parms.params[i];
- dst = &vap->iv_txparms[i];
- rs = &ic->ic_sup_rates[i];
- if (src->ucastrate != dst->ucastrate) {
- if (!checkrate(rs, src->ucastrate))
- return EINVAL;
- changed++;
- }
- if (src->mcastrate != dst->mcastrate) {
- if (!checkrate(rs, src->mcastrate))
- return EINVAL;
- changed++;
- }
- if (src->mgmtrate != dst->mgmtrate) {
- if (!checkrate(rs, src->mgmtrate))
- return EINVAL;
- changed++;
- }
- if (src->maxretry != dst->maxretry) /* NB: no bounds */
- changed++;
- }
- /* 11n parameters are handled differently */
- for (; i < IEEE80211_MODE_MAX; i++) {
- if (isclr(ic->ic_modecaps, i))
+ for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
+ if (isclr(ic->ic_modecaps, mode))
continue;
- src = &parms.params[i];
- dst = &vap->iv_txparms[i];
- rs = &ic->ic_sup_rates[i];
+ src = &parms.params[mode];
+ dst = &vap->iv_txparms[mode];
+ rs = &ic->ic_sup_rates[mode]; /* NB: 11n maps to legacy */
+ is11n = (mode == IEEE80211_MODE_11NA ||
+ mode == IEEE80211_MODE_11NG);
if (src->ucastrate != dst->ucastrate) {
- if (!checkmcs(src->ucastrate) &&
- !checkrate(rs, src->ucastrate))
+ if (!checkrate(rs, src->ucastrate) &&
+ (!is11n || !checkmcs(src->ucastrate)))
return EINVAL;
changed++;
}
if (src->mcastrate != dst->mcastrate) {
- if (!checkmcs(src->mcastrate) &&
- !checkrate(rs, src->mcastrate))
+ if (!checkrate(rs, src->mcastrate) &&
+ (!is11n || !checkmcs(src->mcastrate)))
return EINVAL;
changed++;
}
if (src->mgmtrate != dst->mgmtrate) {
- if (!checkmcs(src->mgmtrate) &&
- !checkrate(rs, src->mgmtrate))
+ if (!checkrate(rs, src->mgmtrate) &&
+ (!is11n || !checkmcs(src->mgmtrate)))
return EINVAL;
changed++;
}
@@ -2148,9 +2130,9 @@ ieee80211_ioctl_settxparams(struct ieee80211vap *vap,
* Copy new parameters in place and notify the
* driver so it can push state to the device.
*/
- for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) {
- if (isset(ic->ic_modecaps, i))
- vap->iv_txparms[i] = parms.params[i];
+ for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
+ if (isset(ic->ic_modecaps, mode))
+ vap->iv_txparms[mode] = parms.params[mode];
}
/* XXX could be more intelligent,
e.g. don't reset if setting not being used */
OpenPOWER on IntegriCloud