| | 54 | #define AP_PURGE_SCANS 2 /* age for purging entries (scans) */ |
|---|
| | 55 | #define RSSI_LPF_LEN 10 |
|---|
| | 56 | #define RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ |
|---|
| | 57 | #define RSSI_IN(x) ((x) * RSSI_EP_MULTIPLIER) |
|---|
| | 58 | #define LPF_RSSI(x, y, len) (((x) * ((len) - 1) + (y)) / (len)) |
|---|
| | 59 | #define RSSI_LPF(x, y) do { \ |
|---|
| | 60 | if ((y) >= -20) \ |
|---|
| | 61 | x = LPF_RSSI((x), RSSI_IN((y)), RSSI_LPF_LEN); \ |
|---|
| | 62 | } while (0) |
|---|
| | 63 | #define EP_RND(x, mul) \ |
|---|
| | 64 | ((((x)%(mul)) >= ((mul)/2)) ? howmany(x, mul) : (x)/(mul)) |
|---|
| | 65 | #define RSSI_GET(x) EP_RND(x, RSSI_EP_MULTIPLIER) |
|---|
| | 66 | #define AP_HASHSIZE 32 |
|---|
| | 67 | /* simple hash is enough for variation of macaddr */ |
|---|
| | 68 | #define AP_HASH(addr) \ |
|---|
| | 69 | (((const u_int8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % AP_HASHSIZE) |
|---|
| | 70 | #define SCAN_AP_LOCK_INIT(_st, _name) \ |
|---|
| | 71 | spin_lock_init(&(_st)->as_lock) |
|---|
| | 72 | #define SCAN_AP_LOCK_DESTROY(_st) |
|---|
| | 73 | #define SCAN_AP_LOCK_IRQ(_st) do { \ |
|---|
| | 74 | unsigned long __stlockflags; \ |
|---|
| | 75 | spin_lock_irqsave(&(_st)->as_lock, __stlockflags); |
|---|
| | 76 | #define SCAN_AP_UNLOCK_IRQ(_st) \ |
|---|
| | 77 | spin_unlock_irqrestore(&(_st)->as_lock, __stlockflags); \ |
|---|
| | 78 | } while (0) |
|---|
| | 79 | #define SCAN_AP_UNLOCK_IRQ_EARLY(_st) \ |
|---|
| | 80 | spin_unlock_irqrestore(&(_st)->as_lock, __stlockflags); |
|---|
| | 81 | |
|---|
| | 82 | #define SCAN_AP_GEN_LOCK_INIT(_st, _name) \ |
|---|
| | 83 | spin_lock_init(&(_st)->as_scanlock) |
|---|
| | 84 | #define SCAN_AP_GEN_LOCK_DESTROY(_st) |
|---|
| | 85 | #define SCAN_AP_GEN_LOCK(_st) spin_lock(&(_st)->as_scanlock); |
|---|
| | 86 | #define SCAN_AP_GEN_UNLOCK(_st) spin_unlock(&(_st)->as_scanlock); |
|---|
| | 87 | |
|---|
| | 88 | struct scan_entry { |
|---|
| | 89 | struct ieee80211_scan_entry base; |
|---|
| | 90 | TAILQ_ENTRY(scan_entry) se_list; |
|---|
| | 91 | LIST_ENTRY(scan_entry) se_hash; |
|---|
| | 92 | u_int8_t se_seen; /* seen during current scan */ |
|---|
| | 93 | u_int8_t se_notseen; /* not seen in previous scans */ |
|---|
| | 94 | u_int32_t se_avgrssi; /* LPF rssi state */ |
|---|
| | 95 | unsigned long se_lastupdate; /* time of last update */ |
|---|
| | 96 | unsigned long se_lastfail; /* time of last failure */ |
|---|
| | 97 | unsigned long se_lastassoc; /* time of last association */ |
|---|
| | 98 | u_int se_scangen; /* iterator scan gen# */ |
|---|
| | 99 | }; |
|---|
| | 100 | |
|---|
| | 122 | static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, int i, int freq); |
|---|
| | 123 | |
|---|
| | 124 | static const u_int chanflags[] = { |
|---|
| | 125 | IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ |
|---|
| | 126 | IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ |
|---|
| | 127 | IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ |
|---|
| | 128 | IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ |
|---|
| | 129 | IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ |
|---|
| | 130 | IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ |
|---|
| | 131 | IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ |
|---|
| | 132 | IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ |
|---|
| | 133 | }; |
|---|
| | 134 | |
|---|
| | 135 | static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ |
|---|
| | 136 | { 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; |
|---|
| | 137 | static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ |
|---|
| | 138 | { 5170, 5190, 5210, 5230 }; |
|---|
| | 139 | static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ |
|---|
| | 140 | { 2412, 2437, 2462, 2442, 2472 }; |
|---|
| | 141 | static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ |
|---|
| | 142 | { 5745, 5765, 5785, 5805, 5825 }; |
|---|
| | 143 | static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ |
|---|
| | 144 | { 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; |
|---|
| | 145 | static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ |
|---|
| | 146 | { 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; |
|---|
| | 147 | static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ |
|---|
| | 148 | { 2484 }; |
|---|
| | 149 | static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ |
|---|
| | 150 | { 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; |
|---|
| | 151 | static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ |
|---|
| | 152 | { 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; |
|---|
| | 153 | #ifdef ATH_TURBO_SCAN |
|---|
| | 154 | static const u_int16_t rcl5[] = /* 3 static turbo channels */ |
|---|
| | 155 | { 5210, 5250, 5290 }; |
|---|
| | 156 | static const u_int16_t rcl6[] = /* 2 static turbo channels */ |
|---|
| | 157 | { 5760, 5800 }; |
|---|
| | 158 | static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ |
|---|
| | 159 | { 5540, 5580, 5620, 5660 }; |
|---|
| | 160 | static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ |
|---|
| | 161 | { 2437 }; |
|---|
| | 162 | static const u_int16_t rcl13[] = /* dynamic Turbo channels */ |
|---|
| | 163 | { 5200, 5240, 5280, 5765, 5805 }; |
|---|
| | 164 | #endif /* ATH_TURBO_SCAN */ |
|---|
| | 165 | |
|---|
| | 166 | struct scanlist { |
|---|
| | 167 | u_int16_t mode; |
|---|
| | 168 | u_int16_t count; |
|---|
| | 169 | const u_int16_t *list; |
|---|
| | 170 | }; |
|---|
| | 171 | |
|---|
| | 172 | #define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX |
|---|
| | 173 | #define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a |
|---|
| | 174 | |
|---|
| | 175 | static const struct scanlist staScanTable[] = { |
|---|
| | 176 | { IEEE80211_MODE_11B, X(rcl3) }, |
|---|
| | 177 | { IEEE80211_MODE_11A, X(rcl1) }, |
|---|
| | 178 | { IEEE80211_MODE_11A, X(rcl2) }, |
|---|
| | 179 | { IEEE80211_MODE_11B, X(rcl8) }, |
|---|
| | 180 | { IEEE80211_MODE_11B, X(rcl9) }, |
|---|
| | 181 | { IEEE80211_MODE_11A, X(rcl4) }, |
|---|
| | 182 | #ifdef ATH_TURBO_SCAN |
|---|
| | 183 | { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, |
|---|
| | 184 | { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, |
|---|
| | 185 | { IEEE80211_MODE_TURBO_A, X(rcl6x) }, |
|---|
| | 186 | { IEEE80211_MODE_TURBO_A, X(rcl13) }, |
|---|
| | 187 | #endif /* ATH_TURBO_SCAN */ |
|---|
| | 188 | { IEEE80211_MODE_11A, X(rcl7) }, |
|---|
| | 189 | { IEEE80211_MODE_11B, X(rcl10) }, |
|---|
| | 190 | { IEEE80211_MODE_11A, X(rcl11) }, |
|---|
| | 191 | #ifdef ATH_TURBO_SCAN |
|---|
| | 192 | { IEEE80211_MODE_TURBO_G, X(rcl12) }, |
|---|
| | 193 | #endif /* ATH_TURBO_SCAN */ |
|---|
| | 194 | { .list = NULL } |
|---|
| | 195 | }; |
|---|
| | 196 | |
|---|
| | 197 | #undef X |
|---|
| | 198 | /* This function must be invoked with locks acquired */ |
|---|
| | 199 | static void |
|---|
| | 200 | add_channels(struct ieee80211com *ic, |
|---|
| | 201 | struct ieee80211_scan_state *ss, |
|---|
| | 202 | enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) |
|---|
| | 203 | { |
|---|
| | 204 | #define N(a) (sizeof(a) / sizeof(a[0])) |
|---|
| | 205 | struct ieee80211_channel *c, *cg; |
|---|
| | 206 | u_int modeflags; |
|---|
| | 207 | int i; |
|---|
| | 208 | |
|---|
| | 209 | KASSERT(mode < N(chanflags), ("Unexpected mode %u", mode)); |
|---|
| | 210 | modeflags = chanflags[mode]; |
|---|
| | 211 | for (i = 0; i < nfreq; i++) { |
|---|
| | 212 | c = ieee80211_find_channel(ic, freq[i], modeflags); |
|---|
| | 213 | if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) |
|---|
| | 214 | continue; |
|---|
| | 215 | if (mode == IEEE80211_MODE_AUTO) { |
|---|
| | 216 | /* |
|---|
| | 217 | * XXX special-case 11b/g channels so we select |
|---|
| | 218 | * the g channel if both are present. |
|---|
| | 219 | */ |
|---|
| | 220 | if (IEEE80211_IS_CHAN_B(c) && |
|---|
| | 221 | (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) |
|---|
| | 222 | c = cg; |
|---|
| | 223 | } |
|---|
| | 224 | if (ss->ss_last >= IEEE80211_SCAN_MAX) |
|---|
| | 225 | break; |
|---|
| | 226 | ss->ss_chans[ss->ss_last++] = c; |
|---|
| | 227 | } |
|---|
| | 228 | #undef N |
|---|
| | 229 | } |
|---|
| | 230 | |
|---|
| | 231 | /* This function must be invoked with locks acquired */ |
|---|
| | 232 | static int |
|---|
| | 233 | checktable(const struct scanlist *scan, const struct ieee80211_channel *c) |
|---|
| | 234 | { |
|---|
| | 235 | int i; |
|---|
| | 236 | |
|---|
| | 237 | for (; scan->list != NULL; scan++) { |
|---|
| | 238 | for (i = 0; i < scan->count; i++) |
|---|
| | 239 | if (scan->list[i] == c->ic_freq) |
|---|
| | 240 | return 1; |
|---|
| | 241 | } |
|---|
| | 242 | return 0; |
|---|
| | 243 | } |
|---|
| 145 | | if (vap->iv_des_mode == IEEE80211_MODE_AUTO) { |
|---|
| 146 | | for (i = 0; i < ic->ic_nchans; i++) { |
|---|
| 147 | | c = &ic->ic_channels[i]; |
|---|
| 148 | | if (IEEE80211_IS_CHAN_TURBO(c)) { |
|---|
| 149 | | /* XR is not supported on turbo channels */ |
|---|
| 150 | | if (vap->iv_ath_cap & IEEE80211_ATHC_XR) |
|---|
| 151 | | continue; |
|---|
| 152 | | /* dynamic channels are scanned in base mode */ |
|---|
| 153 | | if (!IEEE80211_IS_CHAN_ST(c)) |
|---|
| 154 | | continue; |
|---|
| 155 | | } else { |
|---|
| 156 | | /* |
|---|
| 157 | | * Use any 11g channel instead of 11b one. |
|---|
| 158 | | */ |
|---|
| 159 | | if (IEEE80211_IS_CHAN_B(c) && |
|---|
| 160 | | find11gchannel(ic, i, c->ic_freq)) |
|---|
| 161 | | continue; |
|---|
| 162 | | } |
|---|
| 163 | | if (c->ic_flags & IEEE80211_CHAN_RADAR) |
|---|
| 164 | | continue; |
|---|
| 165 | | if (ss->ss_last >= IEEE80211_SCAN_MAX) |
|---|
| 166 | | break; |
|---|
| 167 | | ss->ss_chans[ss->ss_last++] = c; |
|---|
| 168 | | } |
|---|
| 169 | | } else { |
|---|
| 170 | | static const u_int chanflags[] = { |
|---|
| 171 | | 0, /* IEEE80211_MODE_AUTO */ |
|---|
| 172 | | IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ |
|---|
| 173 | | IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ |
|---|
| 174 | | IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ |
|---|
| 175 | | IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ |
|---|
| 176 | | IEEE80211_CHAN_108A, /* IEEE80211_MODE_TURBO_A */ |
|---|
| 177 | | IEEE80211_CHAN_108G, /* IEEE80211_MODE_TURBO_G */ |
|---|
| 178 | | IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ |
|---|
| 179 | | }; |
|---|
| 180 | | u_int modeflags; |
|---|
| 181 | | |
|---|
| 182 | | modeflags = chanflags[vap->iv_des_mode]; |
|---|
| 183 | | if (vap->iv_ath_cap & IEEE80211_ATHC_TURBOP && modeflags != IEEE80211_CHAN_ST) { |
|---|
| 184 | | if (vap->iv_des_mode == IEEE80211_MODE_11G) |
|---|
| 185 | | modeflags = IEEE80211_CHAN_108G; |
|---|
| 186 | | else |
|---|
| 187 | | modeflags = IEEE80211_CHAN_108A; |
|---|
| 188 | | } |
|---|
| 189 | | for (i = 0; i < ic->ic_nchans; i++) { |
|---|
| 190 | | c = &ic->ic_channels[i]; |
|---|
| 191 | | if ((c->ic_flags & modeflags) != modeflags) |
|---|
| 192 | | continue; |
|---|
| 193 | | /* XR is not supported on turbo channels */ |
|---|
| 194 | | if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_ath_cap & IEEE80211_ATHC_XR) |
|---|
| 195 | | continue; |
|---|
| 196 | | if (ss->ss_last >= IEEE80211_SCAN_MAX) |
|---|
| 197 | | break; |
|---|
| 198 | | /* |
|---|
| 199 | | * do not select static turbo channels if the mode is not |
|---|
| 200 | | * static turbo . |
|---|
| 201 | | */ |
|---|
| 202 | | if (IEEE80211_IS_CHAN_STURBO(c) && vap->iv_des_mode != IEEE80211_MODE_MAX ) |
|---|
| 203 | | continue; |
|---|
| 204 | | /* No dfs interference detected channels */ |
|---|
| 205 | | if (c->ic_flags & IEEE80211_CHAN_RADAR) |
|---|
| 206 | | continue; |
|---|
| 207 | | ss->ss_chans[ss->ss_last++] = c; |
|---|
| 208 | | } |
|---|
| | 373 | /* Use the table of ordered channels to construct the list |
|---|
| | 374 | * of channels for scanning. Any channels in the ordered |
|---|
| | 375 | * list not in the master list will be discarded. */ |
|---|
| | 376 | for (sl = staScanTable; sl->list != NULL; sl++) { |
|---|
| | 377 | mode = sl->mode; |
|---|
| | 378 | /* The scan table marks 2.4Ghz channels as b |
|---|
| | 379 | * so if the desired mode is 11g, then use |
|---|
| | 380 | * the 11b channel list but upgrade the mode. */ |
|---|
| | 381 | if (as->as_vap_desired_mode && |
|---|
| | 382 | as->as_vap_desired_mode != mode && |
|---|
| | 383 | as->as_vap_desired_mode == IEEE80211_MODE_11G && |
|---|
| | 384 | mode == IEEE80211_MODE_11B) |
|---|
| | 385 | mode = IEEE80211_MODE_11G; |
|---|
| | 386 | /* If we are in "AUTO" mode, upgrade the mode to auto. |
|---|
| | 387 | * This lets add_channels upgrade an 11b channel to |
|---|
| | 388 | * 11g if available. */ |
|---|
| | 389 | if(!as->as_vap_desired_mode && mode == IEEE80211_MODE_11B) |
|---|
| | 390 | mode = IEEE80211_MODE_AUTO; |
|---|
| | 391 | /* Add the list of the channels; any that are not |
|---|
| | 392 | * in the master channel list will be discarded. */ |
|---|
| | 393 | add_channels(ic, ss, mode, sl->list, sl->count); |
|---|
| | 394 | } |
|---|
| | 395 | |
|---|
| | 396 | /* |
|---|
| | 397 | * Add the channels from the ic (from HAL) that are not present |
|---|
| | 398 | * in the staScanTable, assuming they pass the sanity checks... |
|---|
| | 399 | */ |
|---|
| | 400 | for (i = 0; i < ic->ic_nchans; i++) { |
|---|
| | 401 | c = &ic->ic_channels[i]; |
|---|
| | 402 | /* XR is not supported on turbo channels */ |
|---|
| | 403 | if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR) |
|---|
| | 404 | continue; |
|---|
| | 405 | |
|---|
| | 406 | /* Dynamic channels are scanned in base mode */ |
|---|
| | 407 | if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c)) |
|---|
| | 408 | continue; |
|---|
| | 409 | |
|---|
| | 410 | /* Use any 11g channel instead of 11b one. */ |
|---|
| | 411 | if (vap->iv_des_mode == IEEE80211_MODE_AUTO && |
|---|
| | 412 | IEEE80211_IS_CHAN_B(c) && |
|---|
| | 413 | find11gchannel(ic, i, c->ic_freq)) |
|---|
| | 414 | continue; |
|---|
| | 415 | |
|---|
| | 416 | /* Do not add channels already put into the scan list by the |
|---|
| | 417 | * scan table - these have already been filtered by mode |
|---|
| | 418 | * and for whether they are in the active channel list. */ |
|---|
| | 419 | if (checktable(staScanTable, c)) |
|---|
| | 420 | continue; |
|---|
| | 421 | |
|---|
| | 422 | /* Make sure the channel is active */ |
|---|
| | 423 | if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) |
|---|
| | 424 | continue; |
|---|
| | 425 | |
|---|
| | 426 | /* Don't overrun */ |
|---|
| | 427 | if (ss->ss_last >= IEEE80211_SCAN_MAX) |
|---|
| | 428 | break; |
|---|
| | 429 | |
|---|
| | 430 | ss->ss_chans[ss->ss_last++] = c; |
|---|
| 265 | | /* XXX interference, turbo requirements */ |
|---|
| | 494 | vap = ss->ss_vap; |
|---|
| | 495 | ic = vap->iv_ic; |
|---|
| | 496 | hash = AP_HASH(macaddr); |
|---|
| | 497 | chan = ieee80211_chan2ieee(ic, ic->ic_curchan); |
|---|
| | 498 | LIST_FOREACH(se, &as->as_hash[hash], se_hash) |
|---|
| | 499 | if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) && |
|---|
| | 500 | sp->ssid[1] == se->base.se_ssid[1] && |
|---|
| | 501 | !memcmp(se->base.se_ssid+2, sp->ssid+2, se->base.se_ssid[1])) |
|---|
| | 502 | goto found; |
|---|
| | 503 | |
|---|
| | 504 | MALLOC(se, struct scan_entry *, sizeof(struct scan_entry), |
|---|
| | 505 | M_80211_SCAN, M_NOWAIT | M_ZERO); |
|---|
| | 506 | if (se == NULL) { |
|---|
| | 507 | SCAN_AP_UNLOCK_IRQ_EARLY(as); |
|---|
| | 508 | return 0; |
|---|
| | 509 | } |
|---|
| | 510 | se->se_scangen = as->as_scangen-1; |
|---|
| | 511 | IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr); |
|---|
| | 512 | TAILQ_INSERT_TAIL(&as->as_entry, se, se_list); |
|---|
| | 513 | LIST_INSERT_HEAD(&as->as_hash[hash], se, se_hash); |
|---|
| | 514 | found: |
|---|
| | 515 | ise = &se->base; |
|---|
| | 516 | /* XXX ap beaconing multiple ssid w/ same bssid */ |
|---|
| | 517 | if (sp->ssid[1] != 0 && |
|---|
| | 518 | ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) || ise->se_ssid[1] == 0)) |
|---|
| | 519 | { |
|---|
| | 520 | memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]); |
|---|
| | 521 | } |
|---|
| | 522 | KASSERT(sp->rates[1] <= IEEE80211_RATE_MAXSIZE, |
|---|
| | 523 | ("rate set too large: %u", sp->rates[1])); |
|---|
| | 524 | memcpy(ise->se_rates, sp->rates, 2 + sp->rates[1]); |
|---|
| | 525 | if (sp->xrates != NULL) { |
|---|
| | 526 | /* XXX validate xrates[1] */ |
|---|
| | 527 | KASSERT(sp->xrates[1] <= IEEE80211_RATE_MAXSIZE, |
|---|
| | 528 | ("xrate set too large: %u", sp->xrates[1])); |
|---|
| | 529 | memcpy(ise->se_xrates, sp->xrates, 2 + sp->xrates[1]); |
|---|
| | 530 | } else |
|---|
| | 531 | ise->se_xrates[1] = 0; |
|---|
| | 532 | IEEE80211_ADDR_COPY(ise->se_bssid, wh->i_addr3); |
|---|
| | 533 | /* |
|---|
| | 534 | * Record rssi data using extended precision LPF filter. |
|---|
| | 535 | */ |
|---|
| | 536 | if (se->se_lastupdate == 0) /* first sample */ |
|---|
| | 537 | se->se_avgrssi = RSSI_IN(rssi); |
|---|
| | 538 | else /* avg w/ previous samples */ |
|---|
| | 539 | RSSI_LPF(se->se_avgrssi, rssi); |
|---|
| | 540 | se->base.se_rssi = RSSI_GET(se->se_avgrssi); |
|---|
| | 541 | ise->se_rtsf = rtsf; |
|---|
| | 542 | memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); |
|---|
| | 543 | ise->se_intval = sp->bintval; |
|---|
| | 544 | ise->se_capinfo = sp->capinfo; |
|---|
| | 545 | ise->se_chan = ic->ic_curchan; |
|---|
| | 546 | ise->se_fhdwell = sp->fhdwell; |
|---|
| | 547 | ise->se_fhindex = sp->fhindex; |
|---|
| | 548 | ise->se_erp = sp->erp; |
|---|
| | 549 | ise->se_timoff = sp->timoff; |
|---|
| | 550 | if (sp->tim != NULL) { |
|---|
| | 551 | const struct ieee80211_tim_ie *tim = |
|---|
| | 552 | (const struct ieee80211_tim_ie *) sp->tim; |
|---|
| | 553 | ise->se_dtimperiod = tim->tim_period; |
|---|
| | 554 | } |
|---|
| | 555 | saveie(&ise->se_wme_ie, sp->wme); |
|---|
| | 556 | saveie(&ise->se_wpa_ie, sp->wpa); |
|---|
| | 557 | saveie(&ise->se_rsn_ie, sp->rsn); |
|---|
| | 558 | saveie(&ise->se_ath_ie, sp->ath); |
|---|
| | 559 | |
|---|
| | 560 | se->se_lastupdate = jiffies; /* update time */ |
|---|
| | 561 | se->se_seen = 1; |
|---|
| | 562 | se->se_notseen = 0; |
|---|
| | 563 | |
|---|
| | 564 | SCAN_AP_UNLOCK_IRQ(as); |
|---|
| | 565 | |
|---|