forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c
....@@ -1,15 +1,16 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * Linux roam cache
43 *
5
- * Copyright (C) 1999-2019, Broadcom Corporation
6
- *
4
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
5
+ *
6
+ * Copyright (C) 1999-2017, Broadcom Corporation
7
+ *
78 * Unless you and Broadcom execute a separate written software license
89 * agreement governing use of this software, this software is licensed to you
910 * under the terms of the GNU General Public License version 2 (the "GPL"),
1011 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1112 * following added to such license:
12
- *
13
+ *
1314 * As a special exception, the copyright holders of this software give you
1415 * permission to link this software with independent modules, and to copy and
1516 * distribute the resulting executable under terms of your choice, provided that
....@@ -17,7 +18,7 @@
1718 * the license of that module. An independent module is a module which is not
1819 * derived from this software. The special exception does not apply to any
1920 * modifications of the software.
20
- *
21
+ *
2122 * Notwithstanding the above, under no circumstances may you combine this
2223 * software in any way with any other Broadcom software provided under a license
2324 * other than the GPL, without Broadcom's express prior written consent.
....@@ -25,5 +26,511 @@
2526 *
2627 * <<Broadcom-WL-IPTag/Open:>>
2728 *
28
- * $Id: wl_roam.c 589977 2015-10-01 07:03:40Z $
29
+ * $Id: wl_roam.c 798173 2019-01-07 09:23:21Z $
2930 */
31
+
32
+#include <typedefs.h>
33
+#include <osl.h>
34
+#include <bcmwifi_channels.h>
35
+#include <wlioctl.h>
36
+#include <bcmutils.h>
37
+#ifdef WL_CFG80211
38
+#include <wl_cfg80211.h>
39
+#endif // endif
40
+#include <wldev_common.h>
41
+#include <bcmstdlib_s.h>
42
+
43
+#ifdef ESCAN_CHANNEL_CACHE
44
+#define MAX_ROAM_CACHE 200
45
+#define MAX_SSID_BUFSIZE 36
46
+
47
+#define ROAMSCAN_MODE_NORMAL 0
48
+#define ROAMSCAN_MODE_WES 1
49
+
50
+typedef struct {
51
+ chanspec_t chanspec;
52
+ int ssid_len;
53
+ char ssid[MAX_SSID_BUFSIZE];
54
+} roam_channel_cache;
55
+
56
+static int n_roam_cache = 0;
57
+static int roam_band = WLC_BAND_AUTO;
58
+static roam_channel_cache roam_cache[MAX_ROAM_CACHE];
59
+static uint band2G, band5G, band6G, band_bw;
60
+
61
+#ifdef WES_SUPPORT
62
+static int roamscan_mode = ROAMSCAN_MODE_NORMAL;
63
+#endif /* WES_SUPPORT */
64
+
65
+#ifdef ROAM_CHANNEL_CACHE
66
+int init_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver)
67
+{
68
+ int err;
69
+ struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
70
+ s32 mode;
71
+
72
+ /* Check support in firmware */
73
+ err = wldev_iovar_getint(dev, "roamscan_mode", &mode);
74
+ if (err && (err == BCME_UNSUPPORTED)) {
75
+ /* If firmware doesn't support, return error. Else proceed */
76
+ WL_ERR(("roamscan_mode iovar failed. %d\n", err));
77
+ return err;
78
+ }
79
+
80
+#ifdef D11AC_IOTYPES
81
+ if (ioctl_ver == 1) {
82
+ /* legacy chanspec */
83
+ band2G = WL_LCHANSPEC_BAND_2G;
84
+ band5G = WL_LCHANSPEC_BAND_5G;
85
+ band_bw = WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE;
86
+ } else {
87
+ band2G = WL_CHANSPEC_BAND_2G;
88
+ band5G = WL_CHANSPEC_BAND_5G;
89
+ band6G = WL_CHANSPEC_BAND_6G;
90
+ band_bw = WL_CHANSPEC_BW_20;
91
+ }
92
+#else
93
+ band2G = WL_CHANSPEC_BAND_2G;
94
+ band5G = WL_CHANSPEC_BAND_5G;
95
+ band6G = WL_CHANSPEC_BAND_6G;
96
+ band_bw = WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
97
+#endif /* D11AC_IOTYPES */
98
+
99
+ n_roam_cache = 0;
100
+ roam_band = WLC_BAND_AUTO;
101
+#ifdef WES_SUPPORT
102
+ roamscan_mode = ROAMSCAN_MODE_NORMAL;
103
+#endif /* WES_SUPPORT */
104
+
105
+ return 0;
106
+}
107
+#endif /* ROAM_CHANNEL_CACHE */
108
+
109
+#ifdef WES_SUPPORT
110
+int get_roamscan_mode(struct net_device *dev, int *mode)
111
+{
112
+ *mode = roamscan_mode;
113
+
114
+ return 0;
115
+}
116
+
117
+int set_roamscan_mode(struct net_device *dev, int mode)
118
+{
119
+ int error = 0;
120
+ roamscan_mode = mode;
121
+ n_roam_cache = 0;
122
+
123
+ error = wldev_iovar_setint(dev, "roamscan_mode", mode);
124
+ if (error) {
125
+ WL_ERR(("Failed to set roamscan mode to %d, error = %d\n", mode, error));
126
+ }
127
+
128
+ return error;
129
+}
130
+
131
+int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[],
132
+ int n_channels)
133
+{
134
+ int n = 0;
135
+ int max_channel_number = MIN(n_channels, n_roam_cache);
136
+
137
+ if (roamscan_mode == ROAMSCAN_MODE_WES) {
138
+ for (n = 0; n < max_channel_number; n++) {
139
+ channels[n] = roam_cache[n].chanspec & WL_CHANSPEC_CHAN_MASK;
140
+
141
+ WL_DBG(("channel[%d] - [%02d] \n", n, channels[n]));
142
+ }
143
+ }
144
+
145
+ return n;
146
+}
147
+
148
+int set_roamscan_channel_list(struct net_device *dev,
149
+ unsigned char n, unsigned char channels[], int ioctl_ver)
150
+{
151
+ int i;
152
+ int error;
153
+ wl_roam_channel_list_t channel_list;
154
+ char iobuf[WLC_IOCTL_SMLEN];
155
+ roamscan_mode = ROAMSCAN_MODE_WES;
156
+
157
+ if (n > MAX_ROAM_CHANNEL)
158
+ n = MAX_ROAM_CHANNEL;
159
+
160
+ for (i = 0; i < n; i++) {
161
+ chanspec_t chanspec;
162
+
163
+ if (channels[i] <= CH_MAX_2G_CHANNEL) {
164
+ chanspec = band2G | band_bw | channels[i];
165
+ } else {
166
+ chanspec = band5G | band_bw | channels[i];
167
+ }
168
+ roam_cache[i].chanspec = chanspec;
169
+ channel_list.channels[i] = chanspec;
170
+
171
+ WL_DBG(("channel[%d] - [%02d] \n", i, channels[i]));
172
+ }
173
+
174
+ n_roam_cache = n;
175
+ channel_list.n = n;
176
+
177
+ /* need to set ROAMSCAN_MODE_NORMAL to update roamscan_channels,
178
+ * otherwise, it won't be updated
179
+ */
180
+ error = wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_NORMAL);
181
+ if (error) {
182
+ WL_ERR(("Failed to set roamscan mode to %d, error = %d\n",
183
+ ROAMSCAN_MODE_NORMAL, error));
184
+ return error;
185
+ }
186
+ error = wldev_iovar_setbuf(dev, "roamscan_channels", &channel_list,
187
+ sizeof(channel_list), iobuf, sizeof(iobuf), NULL);
188
+ if (error) {
189
+ WL_ERR(("Failed to set roamscan channels, error = %d\n", error));
190
+ return error;
191
+ }
192
+ error = wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_WES);
193
+ if (error) {
194
+ WL_ERR(("Failed to set roamscan mode to %d, error = %d\n",
195
+ ROAMSCAN_MODE_WES, error));
196
+ }
197
+
198
+ return error;
199
+}
200
+#endif /* WES_SUPPORT */
201
+
202
+#ifdef ESCAN_CHANNEL_CACHE
203
+void set_roam_band(int band)
204
+{
205
+ roam_band = band;
206
+}
207
+
208
+void reset_roam_cache(struct bcm_cfg80211 *cfg)
209
+{
210
+ if (!cfg->rcc_enabled) {
211
+ return;
212
+ }
213
+
214
+#ifdef WES_SUPPORT
215
+ if (roamscan_mode == ROAMSCAN_MODE_WES)
216
+ return;
217
+#endif /* WES_SUPPORT */
218
+
219
+ n_roam_cache = 0;
220
+}
221
+
222
+void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi)
223
+{
224
+ int i;
225
+ uint8 channel;
226
+ char chanbuf[CHANSPEC_STR_LEN];
227
+
228
+ if (!cfg->rcc_enabled) {
229
+ return;
230
+ }
231
+
232
+#ifdef WES_SUPPORT
233
+ if (roamscan_mode == ROAMSCAN_MODE_WES)
234
+ return;
235
+#endif /* WES_SUPPORT */
236
+
237
+ if (n_roam_cache >= MAX_ROAM_CACHE)
238
+ return;
239
+
240
+ for (i = 0; i < n_roam_cache; i++) {
241
+ if ((roam_cache[i].ssid_len == bi->SSID_len) &&
242
+ (roam_cache[i].chanspec == bi->chanspec) &&
243
+ (memcmp(roam_cache[i].ssid, bi->SSID, bi->SSID_len) == 0)) {
244
+ /* identical one found, just return */
245
+ return;
246
+ }
247
+ }
248
+
249
+ roam_cache[n_roam_cache].ssid_len = bi->SSID_len;
250
+ channel = wf_chspec_ctlchan(bi->chanspec);
251
+ WL_DBG(("CHSPEC = %s, CTL %d\n", wf_chspec_ntoa_ex(bi->chanspec, chanbuf), channel));
252
+ roam_cache[n_roam_cache].chanspec =
253
+ (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))?
254
+ band6G : (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw | channel;
255
+ (void)memcpy_s(roam_cache[n_roam_cache].ssid, bi->SSID_len, bi->SSID, bi->SSID_len);
256
+
257
+ n_roam_cache++;
258
+}
259
+
260
+static bool is_duplicated_channel(const chanspec_t *channels, int n_channels, chanspec_t new)
261
+{
262
+ int i;
263
+
264
+ for (i = 0; i < n_channels; i++) {
265
+ if (channels[i] == new)
266
+ return TRUE;
267
+ }
268
+
269
+ return FALSE;
270
+}
271
+
272
+int get_roam_channel_list(int target_chan,
273
+ chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver,
274
+ struct ieee80211_channel *chan)
275
+{
276
+ int i, n = 1;
277
+ char chanbuf[CHANSPEC_STR_LEN];
278
+
279
+ /* first index is filled with the given target channel */
280
+ if (target_chan) {
281
+ channels[0] = (target_chan & WL_CHANSPEC_CHAN_MASK) |
282
+ (chan->center_freq > FREQ_START_6G_CHANNEL ?
283
+ band6G : (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw;
284
+ } else {
285
+ /* If target channel is not provided, set the index to 0 */
286
+ n = 0;
287
+ }
288
+
289
+ WL_DBG((" %s: %03d 0x%04X\n", __FUNCTION__, target_chan, channels[0]));
290
+
291
+#ifdef WES_SUPPORT
292
+ if (roamscan_mode == ROAMSCAN_MODE_WES) {
293
+ for (i = 0; i < n_roam_cache; i++) {
294
+ chanspec_t ch = roam_cache[i].chanspec;
295
+ bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
296
+ bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
297
+ bool is_6G = CHSPEC_IS6G(ch);
298
+ bool band_match = ((roam_band == WLC_BAND_AUTO) ||
299
+ ((roam_band == WLC_BAND_2G) && is_2G) ||
300
+ ((roam_band == WLC_BAND_5G) && is_5G) ||
301
+ ((roam_band == WLC_BAND_6G) && is_6G));
302
+
303
+ ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw;
304
+ ch = CHSPEC_CHANNEL(ch) |
305
+ (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
306
+ if (band_match && !is_duplicated_channel(channels, n, ch)) {
307
+ WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
308
+ wf_chspec_ntoa_ex(ch, chanbuf)));
309
+ channels[n++] = ch;
310
+ if (n >= n_channels) {
311
+ WL_ERR(("Too many roam scan channels\n"));
312
+ return n;
313
+ }
314
+ }
315
+ }
316
+
317
+ return n;
318
+ }
319
+#endif /* WES_SUPPORT */
320
+
321
+ for (i = 0; i < n_roam_cache; i++) {
322
+ chanspec_t ch = roam_cache[i].chanspec;
323
+ bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
324
+ bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
325
+ bool is_6G = CHSPEC_IS6G(ch);
326
+ bool band_match = ((roam_band == WLC_BAND_AUTO) ||
327
+ ((roam_band == WLC_BAND_2G) && is_2G) ||
328
+ ((roam_band == WLC_BAND_5G) && is_5G) ||
329
+ ((roam_band == WLC_BAND_6G) && is_6G));
330
+
331
+ ch = CHSPEC_CHANNEL(ch) | (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
332
+ if ((roam_cache[i].ssid_len == ssid->SSID_len) &&
333
+ band_match && !is_duplicated_channel(channels, n, ch) &&
334
+ (memcmp(roam_cache[i].ssid, ssid->SSID, ssid->SSID_len) == 0)) {
335
+ /* match found, add it */
336
+ WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
337
+ wf_chspec_ntoa_ex(ch, chanbuf)));
338
+ channels[n++] = ch;
339
+ if (n >= n_channels) {
340
+ WL_ERR(("Too many roam scan channels\n"));
341
+ return n;
342
+ }
343
+ }
344
+ }
345
+
346
+ return n;
347
+}
348
+#endif /* ESCAN_CHANNEL_CACHE */
349
+
350
+#ifdef ROAM_CHANNEL_CACHE
351
+void print_roam_cache(struct bcm_cfg80211 *cfg)
352
+{
353
+ int i;
354
+
355
+ if (!cfg->rcc_enabled) {
356
+ return;
357
+ }
358
+
359
+ WL_DBG((" %d cache\n", n_roam_cache));
360
+
361
+ for (i = 0; i < n_roam_cache; i++) {
362
+ roam_cache[i].ssid[roam_cache[i].ssid_len] = 0;
363
+ WL_DBG(("0x%02X %02d %s\n", roam_cache[i].chanspec,
364
+ roam_cache[i].ssid_len, roam_cache[i].ssid));
365
+ }
366
+}
367
+
368
+static void add_roamcache_channel(wl_roam_channel_list_t *channels, chanspec_t ch)
369
+{
370
+ int i;
371
+
372
+ if (channels->n >= MAX_ROAM_CHANNEL) /* buffer full */
373
+ return;
374
+
375
+ for (i = 0; i < channels->n; i++) {
376
+ if (channels->channels[i] == ch) /* already in the list */
377
+ return;
378
+ }
379
+
380
+ channels->channels[i] = ch;
381
+ channels->n++;
382
+
383
+ WL_DBG((" RCC: %02d 0x%04X\n",
384
+ ch & WL_CHANSPEC_CHAN_MASK, ch));
385
+}
386
+
387
+void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver)
388
+{
389
+ int error, i, prev_channels;
390
+ wl_roam_channel_list_t channel_list;
391
+ char iobuf[WLC_IOCTL_SMLEN];
392
+ struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
393
+ wlc_ssid_t ssid;
394
+
395
+ if (!cfg->rcc_enabled) {
396
+ return;
397
+ }
398
+
399
+#ifdef WES_SUPPORT
400
+ if (roamscan_mode == ROAMSCAN_MODE_WES) {
401
+ /* no update when ROAMSCAN_MODE_WES */
402
+ return;
403
+ }
404
+#endif /* WES_SUPPORT */
405
+
406
+ if (!wl_get_drv_status(cfg, CONNECTED, dev)) {
407
+ WL_DBG(("Not associated\n"));
408
+ return;
409
+ }
410
+
411
+ /* need to read out the current cache list
412
+ as the firmware may change dynamically
413
+ */
414
+ error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0,
415
+ (void *)&channel_list, sizeof(channel_list), NULL);
416
+ if (error) {
417
+ WL_ERR(("Failed to get roamscan channels, error = %d\n", error));
418
+ return;
419
+ }
420
+
421
+ error = wldev_get_ssid(dev, &ssid);
422
+ if (error) {
423
+ WL_ERR(("Failed to get SSID, err=%d\n", error));
424
+ return;
425
+ }
426
+
427
+ prev_channels = channel_list.n;
428
+ for (i = 0; i < n_roam_cache; i++) {
429
+ chanspec_t ch = roam_cache[i].chanspec;
430
+ bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
431
+ bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
432
+ bool is_6G = CHSPEC_IS6G(ch);
433
+ bool band_match = ((roam_band == WLC_BAND_AUTO) ||
434
+ ((roam_band == WLC_BAND_2G) && is_2G) ||
435
+ ((roam_band == WLC_BAND_5G) && is_5G) ||
436
+ ((roam_band == WLC_BAND_6G) && is_6G));
437
+
438
+ if ((roam_cache[i].ssid_len == ssid.SSID_len) &&
439
+ band_match && (memcmp(roam_cache[i].ssid, ssid.SSID, ssid.SSID_len) == 0)) {
440
+ /* match found, add it */
441
+ ch = CHSPEC_CHANNEL(ch) |
442
+ (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
443
+ add_roamcache_channel(&channel_list, ch);
444
+ }
445
+ }
446
+ if (prev_channels != channel_list.n) {
447
+ /* channel list updated */
448
+ error = wldev_iovar_setbuf(dev, "roamscan_channels", &channel_list,
449
+ sizeof(channel_list), iobuf, sizeof(iobuf), NULL);
450
+ if (error) {
451
+ WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
452
+ }
453
+ }
454
+
455
+ WL_DBG(("%d AP, %d cache item(s), err=%d\n", n_roam_cache, channel_list.n, error));
456
+}
457
+
458
+void wl_update_roamscan_cache_by_band(struct net_device *dev, int band)
459
+{
460
+ int i, error, ioctl_ver, wes_mode;
461
+ wl_roam_channel_list_t chanlist_before, chanlist_after;
462
+ char iobuf[WLC_IOCTL_SMLEN];
463
+
464
+ roam_band = band;
465
+
466
+ error = wldev_iovar_getint(dev, "roamscan_mode", &wes_mode);
467
+ if (error) {
468
+ WL_ERR(("Failed to get roamscan mode, error = %d\n", error));
469
+ return;
470
+ }
471
+
472
+ ioctl_ver = wl_cfg80211_get_ioctl_version();
473
+ /* in case of WES mode, update channel list by band based on the cache in DHD */
474
+ if (wes_mode) {
475
+ int n = 0;
476
+ chanlist_before.n = n_roam_cache;
477
+
478
+ for (n = 0; n < n_roam_cache; n++) {
479
+ chanspec_t ch = roam_cache[n].chanspec;
480
+ bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
481
+ bool is_6G = CHSPEC_IS6G(ch);
482
+ chanlist_before.channels[n] = CHSPEC_CHANNEL(ch) |
483
+ (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
484
+ }
485
+ } else {
486
+ if (band == WLC_BAND_AUTO) {
487
+ return;
488
+ }
489
+ error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0,
490
+ (void *)&chanlist_before, sizeof(wl_roam_channel_list_t), NULL);
491
+ if (error) {
492
+ WL_ERR(("Failed to get roamscan channels, error = %d\n", error));
493
+ return;
494
+ }
495
+ }
496
+ chanlist_after.n = 0;
497
+ /* filtering by the given band */
498
+ for (i = 0; i < chanlist_before.n; i++) {
499
+ chanspec_t chspec = chanlist_before.channels[i];
500
+ bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(chspec) : CHSPEC_IS2G(chspec);
501
+ bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(chspec) : CHSPEC_IS5G(chspec);
502
+ bool is_6G = CHSPEC_IS6G(chspec);
503
+ bool band_match = ((band == WLC_BAND_AUTO) ||
504
+ ((band == WLC_BAND_2G) && is_2G) ||
505
+ ((band == WLC_BAND_5G) && is_5G) ||
506
+ ((band == WLC_BAND_6G) && is_6G));
507
+ if (band_match) {
508
+ chanlist_after.channels[chanlist_after.n++] = chspec;
509
+ }
510
+ }
511
+
512
+ if (wes_mode) {
513
+ /* need to set ROAMSCAN_MODE_NORMAL to update roamscan_channels,
514
+ * otherwise, it won't be updated
515
+ */
516
+ wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_NORMAL);
517
+
518
+ error = wldev_iovar_setbuf(dev, "roamscan_channels", &chanlist_after,
519
+ sizeof(wl_roam_channel_list_t), iobuf, sizeof(iobuf), NULL);
520
+ if (error) {
521
+ WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
522
+ }
523
+ wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_WES);
524
+ } else {
525
+ if (chanlist_before.n == chanlist_after.n) {
526
+ return;
527
+ }
528
+ error = wldev_iovar_setbuf(dev, "roamscan_channels", &chanlist_after,
529
+ sizeof(wl_roam_channel_list_t), iobuf, sizeof(iobuf), NULL);
530
+ if (error) {
531
+ WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
532
+ }
533
+ }
534
+}
535
+#endif /* ROAM_CHANNEL_CACHE */
536
+#endif /* ESCAN_CHANNEL_CACHE */