| 1 | --- a/net80211/ieee80211.c |
| 2 | +++ b/net80211/ieee80211.c |
| 3 | @@ -355,6 +355,8 @@ ieee80211_ifattach(struct ieee80211com * |
| 4 | /* Arbitrarily pick the first channel */ |
| 5 | ic->ic_curchan = &ic->ic_channels[0]; |
| 6 | |
| 7 | + ic->ic_inact_tick = IEEE80211_INACT_WAIT; |
| 8 | + |
| 9 | /* Enable marking of dfs by default */ |
| 10 | ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS; |
| 11 | |
| 12 | --- a/net80211/ieee80211_var.h |
| 13 | +++ b/net80211/ieee80211_var.h |
| 14 | @@ -350,6 +350,7 @@ struct ieee80211com { |
| 15 | u_int8_t ic_protmode_rssi; /* rssi threshold for protection mode */ |
| 16 | u_int64_t ic_protmode_lasttrig; /* last trigger for protection mode */ |
| 17 | u_int16_t ic_protmode_timeout; /* protection mode timeout */ |
| 18 | + u_int16_t ic_inact_tick; /* inact timer tick interval (seconds) */ |
| 19 | |
| 20 | /* Channel state: |
| 21 | * |
| 22 | --- a/net80211/ieee80211_ioctl.h |
| 23 | +++ b/net80211/ieee80211_ioctl.h |
| 24 | @@ -591,6 +591,7 @@ enum { |
| 25 | IEEE80211_PARAM_INACT_AUTH = 24, /* station auth inact timeout */ |
| 26 | IEEE80211_PARAM_INACT_INIT = 25, /* station init inact timeout */ |
| 27 | IEEE80211_PARAM_ABOLT = 26, /* Atheros Adv. Capabilities */ |
| 28 | + IEEE80211_PARAM_INACT_TICK = 27, /* station inactivity timer tick (seconds) */ |
| 29 | IEEE80211_PARAM_DTIM_PERIOD = 28, /* DTIM period (beacons) */ |
| 30 | IEEE80211_PARAM_BEACON_INTERVAL = 29, /* beacon interval (ms) */ |
| 31 | IEEE80211_PARAM_DOTH = 30, /* 11.h is on/off */ |
| 32 | --- a/net80211/ieee80211_wireless.c |
| 33 | +++ b/net80211/ieee80211_wireless.c |
| 34 | @@ -2504,13 +2504,18 @@ ieee80211_ioctl_setparam(struct net_devi |
| 35 | vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; |
| 36 | break; |
| 37 | case IEEE80211_PARAM_INACT: |
| 38 | - vap->iv_inact_run = value / IEEE80211_INACT_WAIT; |
| 39 | + vap->iv_inact_run = value / ic->ic_inact_tick; |
| 40 | + break; |
| 41 | + case IEEE80211_PARAM_INACT_TICK: |
| 42 | + if (value <= 0) |
| 43 | + return -EINVAL; |
| 44 | + ic->ic_inact_tick = value; |
| 45 | break; |
| 46 | case IEEE80211_PARAM_INACT_AUTH: |
| 47 | - vap->iv_inact_auth = value / IEEE80211_INACT_WAIT; |
| 48 | + vap->iv_inact_auth = value / ic->ic_inact_tick; |
| 49 | break; |
| 50 | case IEEE80211_PARAM_INACT_INIT: |
| 51 | - vap->iv_inact_init = value / IEEE80211_INACT_WAIT; |
| 52 | + vap->iv_inact_init = value / ic->ic_inact_tick; |
| 53 | break; |
| 54 | case IEEE80211_PARAM_ABOLT: |
| 55 | caps = 0; |
| 56 | @@ -3050,13 +3055,16 @@ ieee80211_ioctl_getparam(struct net_devi |
| 57 | param[0] = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0; |
| 58 | break; |
| 59 | case IEEE80211_PARAM_INACT: |
| 60 | - param[0] = vap->iv_inact_run * IEEE80211_INACT_WAIT; |
| 61 | + param[0] = vap->iv_inact_run * ic->ic_inact_tick; |
| 62 | break; |
| 63 | case IEEE80211_PARAM_INACT_AUTH: |
| 64 | - param[0] = vap->iv_inact_auth * IEEE80211_INACT_WAIT; |
| 65 | + param[0] = vap->iv_inact_auth * ic->ic_inact_tick; |
| 66 | break; |
| 67 | case IEEE80211_PARAM_INACT_INIT: |
| 68 | - param[0] = vap->iv_inact_init * IEEE80211_INACT_WAIT; |
| 69 | + param[0] = vap->iv_inact_init * ic->ic_inact_tick; |
| 70 | + break; |
| 71 | + case IEEE80211_PARAM_INACT_TICK: |
| 72 | + param[0] = ic->ic_inact_tick; |
| 73 | break; |
| 74 | case IEEE80211_PARAM_ABOLT: |
| 75 | /* |
| 76 | @@ -4557,14 +4565,7 @@ get_sta_info(void *arg, struct ieee80211 |
| 77 | si->isi_opmode = IEEE80211_STA_OPMODE_XR; |
| 78 | else |
| 79 | si->isi_opmode = IEEE80211_STA_OPMODE_NORMAL; |
| 80 | - /* NB: leave all cases in case we relax ni_associd == 0 check */ |
| 81 | - if (ieee80211_node_is_authorized(ni)) |
| 82 | - si->isi_inact = vap->iv_inact_run; |
| 83 | - else if (ni->ni_associd != 0) |
| 84 | - si->isi_inact = vap->iv_inact_auth; |
| 85 | - else |
| 86 | - si->isi_inact = vap->iv_inact_init; |
| 87 | - si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; |
| 88 | + si->isi_inact = (ni->ni_inact_reload - ni->ni_inact) * ic->ic_inact_tick; |
| 89 | |
| 90 | cp = (u_int8_t *)(si+1); |
| 91 | if (ni->ni_rsn_ie != NULL) { |
| 92 | @@ -5597,6 +5598,10 @@ static const struct iw_priv_args ieee802 |
| 93 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inact_init" }, |
| 94 | { IEEE80211_PARAM_INACT_INIT, |
| 95 | 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_inact_init" }, |
| 96 | + { IEEE80211_PARAM_INACT_TICK, |
| 97 | + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inact_tick" }, |
| 98 | + { IEEE80211_PARAM_INACT_TICK, |
| 99 | + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_inact_tick" }, |
| 100 | { IEEE80211_PARAM_ABOLT, |
| 101 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "abolt" }, |
| 102 | { IEEE80211_PARAM_ABOLT, |
| 103 | --- a/net80211/ieee80211_node.c |
| 104 | +++ b/net80211/ieee80211_node.c |
| 105 | @@ -137,7 +137,7 @@ ieee80211_node_attach(struct ieee80211co |
| 106 | init_timer(&ic->ic_inact); |
| 107 | ic->ic_inact.function = ieee80211_node_timeout; |
| 108 | ic->ic_inact.data = (unsigned long) ic; |
| 109 | - ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ; |
| 110 | + ic->ic_inact.expires = jiffies + ic->ic_inact_tick * HZ; |
| 111 | add_timer(&ic->ic_inact); |
| 112 | |
| 113 | #ifdef IEEE80211_DEBUG_REFCNT |
| 114 | @@ -261,7 +261,7 @@ void |
| 115 | ieee80211_node_authorize(struct ieee80211_node *ni) |
| 116 | { |
| 117 | ni->ni_flags |= IEEE80211_NODE_AUTH; |
| 118 | - ni->ni_inact_reload = ni->ni_vap->iv_inact_run; |
| 119 | + ni->ni_inact = ni->ni_inact_reload = ni->ni_vap->iv_inact_run; |
| 120 | } |
| 121 | EXPORT_SYMBOL(ieee80211_node_authorize); |
| 122 | |
| 123 | @@ -1819,7 +1819,7 @@ ieee80211_node_timeout(unsigned long arg |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | - ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ; |
| 128 | + ic->ic_inact.expires = jiffies + ic->ic_inact_tick * HZ; |
| 129 | add_timer(&ic->ic_inact); |
| 130 | } |
| 131 | |
| 132 | --- a/net80211/ieee80211_power.c |
| 133 | +++ b/net80211/ieee80211_power.c |
| 134 | @@ -148,7 +148,7 @@ ieee80211_node_saveq_age(struct ieee8021 |
| 135 | |
| 136 | IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni); |
| 137 | while ((skb = skb_peek(&ni->ni_savedq)) != NULL && |
| 138 | - M_AGE_GET(skb) < IEEE80211_INACT_WAIT) { |
| 139 | + M_AGE_GET(skb) < ni->ni_vap->iv_ic->ic_inact_tick) { |
| 140 | IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, |
| 141 | "discard frame, age %u", M_AGE_GET(skb)); |
| 142 | |
| 143 | @@ -159,7 +159,7 @@ ieee80211_node_saveq_age(struct ieee8021 |
| 144 | discard++; |
| 145 | } |
| 146 | if (skb != NULL) |
| 147 | - M_AGE_SUB(skb, IEEE80211_INACT_WAIT); |
| 148 | + M_AGE_SUB(skb, ni->ni_vap->iv_ic->ic_inact_tick); |
| 149 | IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni); |
| 150 | |
| 151 | IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, |
| 152 | |