This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ACS not changing channels when in a crowded channel.

wlcore: PHY firmware version: Rev 8.2.0.0.224

wlcore: firmware booted (Rev 8.9.0.0.31)

the ACS algorithm only seems to choose channels 1 or 2 even if either or both channels are very congested.

channel=0 is set in the hostapd.conf file

Over several hours I did not see ACS changing channels. It seems that some radios choose channel 1 and others choose channel 2 only.

Also the output on channel 1 is about 3db lower than the other channels. I assume that this is due to the lower adjacent radios signals for siriusXM.

Jim Nadolski

Sr. Applications Field Engineer

Intwine connect, LLC

 

  • Hi,

    Can you share the hostapd.conf that you are using?

    Regards,
    Gigi Joseph.
  • We have been testing two different hostapd.conf files. In both configurations using the ACS setting of

    channel=0

    In both cases we did not see any change of channels over a several day period.  The TI radio seems to only choose channels 1 or 2 even with Channels (1-3) having many other AP's & clients operating in those channels, while channels above 44-11 are empty of any others beaconing APs or other ISM band signals.

    below is the basic hostapd.conf file

    interface=wlan0
    driver=nl80211
    ssid=intwine-icg
    channel=2
    hw_mode=g
    wme_enabled=1
    wmm_enabled=1
    ieee80211n=1
    ht_capab=[SHORT-GI-20]
    ieee80211d=1
    country_code=US
    preamble=1
    ap_max_inactivity=360
    obss_interval=3
    macaddr_acl=0
    auth_algs=1
    ignore_broadcast_ssid=0
    wpa=2
    wpa_passphrase=thepasswordissafe
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP

    depending on which channels, auto(ACS), SSID, etc are chosen from the webpage wifi configuration we dynamically change the hostapd.conf file. We reboot the radio firmware and driver and apply the new wifi settings to the TI radio.

    [ 212.545502] wlcore: down
    [ 213.035903] wlcore: PHY firmware version: Rev 8.2.0.0.224
    [ 213.092462] wlcore: firmware booted (Rev 8.9.0.0.31)

    we also have been using a version of the hostapd.conf file where we want to use a 40MHz BW for applications where the client supports it and we need increased throughput.

    interface=wlan0
    driver=nl80211
    ssid=intwine-icg
    channel=2
    hw_mode=g
    wme_enabled=1
    wmm_enabled=1
    ieee80211n=1
    ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]
    ieee80211d=1
    country_code=US
    preamble=1
    ap_max_inactivity=360
    obss_interval=3
    macaddr_acl=0
    auth_algs=1
    ignore_broadcast_ssid=0
    wpa=2
    wpa_passphrase=thepasswordissafe
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP

    we modify in the hostapd.conf file  the HT- or HT+ depending on channels 1-4 or 5-11 are chosen.

    we have noticed that if channels 5-11 are chosen we see the channel BW at MHz

    but if we choose channels 1-4 with the conf below

    ht_capab=[HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]

    we do not see the radio sending out beacons.

    If we chose "auto" (ACS) it seems to override the .

    ht_capab=[HT40+/-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]

    settings and we see a 20MHz BW channel centered at ch 1 or 2 with a max rate of 75MHz

    jim nadolski

  • Jim,
    Can you please re-run the same scenario with extra hostapd debug logs (add -dd after the hostapd command) and send me back the logs?
    Thanks!
    Guy
  • Hi Jim,

    Can you also please try with the attached patch?
    Also, please see the Software Specification Guide section 4.6. This gives an overview of the ACS mechanism with WiLink8

    Regards,
    Gigi Joseph.


    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/968/0001_2D00_acs_2D00_remove_2D00_redundant_2D00_ieee80211n_5F00_check_5F00_40mhz_2D00_call_2D00_SQU.patch

  • Gigi,

    I have to have our software team integrate the patch and the -dd command into a debug firmware for our gateway. As soon as they deliver the debug firmware I can test it and get back to you.

    Jim Nadolski

  • Gigi,

    I was able to add the -dd command into our script file for hostapd. I do not see any debug messages in the console window.

    The only log I see with the hostapd info is also attachedmessage-log.txt

    root@icg /var/log
    # more dmesg
    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 3.14.51-g288dfb5 (rob@baranduin) (gcc version 4.7.3
     20130226 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro
     GCC 2013.03) ) #1 Fri Oct 2 13:20:11 EDT 2015
    [    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instructio
    n cache
    [    0.000000] Machine model: TI AM335x ICG P3
    [    0.000000] cma: CMA: reserved 24 MiB at 9d800000
    [    0.000000] Memory policy: Data cache writeback
    [    0.000000] On node 0 totalpages: 130816
    [    0.000000] free_area_init_node: node 0, pgdat c07d8270, node_mem_map dfaee00
    0
    [    0.000000]   Normal zone: 1024 pages used for memmap
    [    0.000000]   Normal zone: 0 pages reserved
    [    0.000000]   Normal zone: 130816 pages, LIFO batch:31
    [    0.000000] CPU: All CPU(s) started in SVC mode.
    [    0.000000] AM335X ES2.1 (neon )
    [    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
    [    0.000000] pcpu-alloc: [0] 0
    [    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pag
    es: 129792
    [    0.000000] Kernel command line: console=ttyO0,115200n8 musb_hdrc.use_dma=n r
    oot=/dev/mmcblk0p6 ro rootfstype=ext4 rootwait
    [    0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
    [    0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
    [    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
    [    0.000000] Memory: 485744K/523264K available (5611K kernel code, 279K rwdata
    , 1856K rodata, 253K init, 224K bss, 37520K reserved, 0K highmem)
    [    0.000000] Virtual kernel memory layout:
        vector  : 0xffff0000 - 0xffff1000   (   4 kB)
        fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
        vmalloc : 0xe0800000 - 0xff000000   ( 488 MB)
        lowmem  : 0xc0000000 - 0xe0000000   ( 512 MB)
        pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
        modules : 0xbf000000 - 0xbfe00000   (  14 MB)
          .text : 0xc0008000 - 0xc0753054   (7469 kB)
          .init : 0xc0754000 - 0xc07937ec   ( 254 kB)
          .data : 0xc0794000 - 0xc07d9cd0   ( 280 kB)
           .bss : 0xc07d9cd0 - 0xc0811fe0   ( 225 kB)
    [    0.000000] NR_IRQS:16 nr_irqs:16 16
    [    0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrup
    ts
    [    0.000000] Total of 128 interrupts on 1 active controller
    [    0.000000] OMAP clockevent source: timer2 at 24000000 Hz
    [    0.000013] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 17895
    6969942ns
    [    0.000033] OMAP clocksource: timer1 at 24000000 Hz
    [    0.000280] Console: colour dummy device 80x30
    [    0.000309] Calibrating delay loop... 795.44 BogoMIPS (lpj=3977216)
    [    0.089414] pid_max: default: 32768 minimum: 301
    [    0.089511] Security Framework initialized
    [    0.089563] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
    [    0.089575] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
    [    0.096558] CPU: Testing write buffer coherency: ok
    [    0.096915] Setting up static identity map for 0x805810a0 - 0x80581110
    [    0.097799] devtmpfs: initialized
    [    0.099694] VFP support v0.3: implementor 41 architecture 3 part 30 variant c
     rev 3
    [    0.106935] omap_hwmod: tptc0 using broken dt data from edma
    [    0.107016] omap_hwmod: tptc1 using broken dt data from edma
    [    0.107090] omap_hwmod: tptc2 using broken dt data from edma
    [    0.111279] omap_hwmod: debugss: _wait_target_disable failed
    [    0.167396] pinctrl core: initialized pinctrl subsystem
    [    0.168283] regulator-dummy: no parameters
    [    0.170580] NET: Registered protocol family 16
    [    0.172533] DMA: preallocated 256 KiB pool for atomic coherent allocations
    [    0.174813] cpuidle: using governor ladder
    [    0.174830] cpuidle: using governor menu
    [    0.182099] syscon 44e10000.control_module: regmap [mem 0x44e10000-0x44e107fb
    ] registered
    [    0.183466] platform 49000000.edma: alias fck already exists
    [    0.183490] platform 49000000.edma: alias fck already exists
    [    0.183505] platform 49000000.edma: alias fck already exists
    [    0.184299] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
    [    0.184574] OMAP GPIO hardware version 0.1
    [    0.185379] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
    [    0.186338] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
    [    0.187285] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
    [    0.198606] No ATAGs?
    [    0.198628] hw-breakpoint: debug architecture 0x4 unsupported.
    [    0.220709] bio: create slab <bio-0> at 0
    [    0.235337] edma-dma-engine edma-dma-engine.0: TI EDMA DMA engine driver
    [    0.236054] of_get_named_gpiod_flags: can't parse gpios property of node '/fi
    xedregulator@0[0]'
    [    0.236347] vbat: 5000 mV
    [    0.236514] of_get_named_gpiod_flags exited with status 0
    [    0.236864] wlan-en-regulator: 1800 mV
    [    0.237009] of_get_named_gpiod_flags exited with status 0
    [    0.237313] vtt: no parameters
    [    0.240330] vgaarb: loaded
    [    0.240817] i2c-core: driver [palmas] using legacy suspend method
    [    0.240827] i2c-core: driver [palmas] using legacy resume method
    [    0.241506] SCSI subsystem initialized
    [    0.241980] libata version 3.00 loaded.
    [    0.242836] usbcore: registered new interface driver usbfs
    [    0.243008] usbcore: registered new interface driver hub
    [    0.243213] usbcore: registered new device driver usb
    [    0.244110] omap_i2c 44e0b000.i2c: could not find pctldev for node /pinmux@44
    e10800/pinmux_i2c0_pins, deferring probe
    [    0.244140] platform 44e0b000.i2c: Driver omap_i2c requests probe deferral
    [    0.244820] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 400 kHz
    [    0.245127] media: Linux media interface: v0.10
    [    0.245298] Linux video capture interface: v2.00
    [    0.245531] pps_core: LinuxPPS API ver. 1 registered
    [    0.245541] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giome
    tti <giometti@linux.it>
    [    0.245656] PTP clock support registered
    [    0.247435] omap-mailbox 480c8000.mailbox: omap mailbox rev 0x400
    [    0.249214] Switched to clocksource timer1
    [    0.267137] NET: Registered protocol family 2
    [    0.268015] TCP established hash table entries: 4096 (order: 2, 16384 bytes)
    [    0.268073] TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
    [    0.268118] TCP: Hash tables configured (established 4096 bind 4096)
    [    0.268181] TCP: reno registered
    [    0.268194] UDP hash table entries: 256 (order: 0, 4096 bytes)
    [    0.268212] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
    [    0.268377] NET: Registered protocol family 1
    [    0.268676] RPC: Registered named UNIX socket transport module.
    [    0.268687] RPC: Registered udp transport module.
    [    0.268694] RPC: Registered tcp transport module.
    [    0.268700] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.268715] PCI: CLS 0 bytes, default 64
    [    0.269760] NetWinder Floating Point Emulator V0.97 (double precision)
    [    0.269885] hw perfevents: enabled with ARMv7 Cortex-A8 PMU driver, 5 counter
    s available
    [    0.272496] futex hash table entries: 256 (order: -1, 3072 bytes)
    [    0.411643] VFS: Disk quotas dquot_6.5.2
    [    0.411710] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
    [    0.412198] NFS: Registering the id_resolver key type
    [    0.412278] Key type id_resolver registered
    [    0.412286] Key type id_legacy registered
    [    0.412325] jffs2: version 2.2. (NAND) (SUMMARY)  \xffffffc2\xffffffa9 2001-2
    006 Red Hat, Inc.
    [    0.412487] msgmni has been set to 996
    [    0.413861] NET: Registered protocol family 38
    [    0.413899] io scheduler noop registered
    [    0.413908] io scheduler deadline registered
    [    0.413931] io scheduler cfq registered (default)
    [    0.415426] pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
    [    0.420677] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
    [    0.423181] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@44e09000[0]'
    [    0.423221] omap_uart 44e09000.serial: no wakeirq for uart0
    [    0.423235] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@44e09000[0]'
    [    0.423327] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud =
    3000000) is a OMAP UART0
    [    1.081888] console [ttyO0] enabled
    [    1.086235] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@48022000[0]'
    [    1.086266] omap_uart 48022000.serial: no wakeirq for uart0
    [    1.092120] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@48022000[0]'
    [    1.092249] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89, base_baud =
    3000000) is a OMAP UART1
    [    1.102469] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@48024000[0]'
    [    1.102496] omap_uart 48024000.serial: no wakeirq for uart0
    [    1.108313] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@48024000[0]'
    [    1.108415] 48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90, base_baud =
    3000000) is a OMAP UART2
    [    1.118592] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481a6000[0]'
    [    1.118620] omap_uart 481a6000.serial: no wakeirq for uart0
    [    1.124471] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481a6000[0]'
    [    1.124572] 481a6000.serial: ttyO3 at MMIO 0x481a6000 (irq = 60, base_baud =
    3000000) is a OMAP UART3
    [    1.134733] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481a8000[0]'
    [    1.134762] omap_uart 481a8000.serial: no wakeirq for uart0
    [    1.140612] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481a8000[0]'
    [    1.140705] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61, base_baud =
    3000000) is a OMAP UART4
    [    1.150860] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481aa000[0]'
    [    1.150890] omap_uart 481aa000.serial: no wakeirq for uart0
    [    1.156707] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/serial@481aa000[0]'
    [    1.156795] 481aa000.serial: ttyO5 at MMIO 0x481aa000 (irq = 62, base_baud =
    3000000) is a OMAP UART5
    [    1.167748] omap_rng 48310000.rng: OMAP Random Number Generator ver. 20
    [    1.184763] brd: module loaded
    [    1.193183] loop: module loaded
    [    1.196749] (stk) :sysfs entries created
    [    1.200923] (stk) : debugfs entries created
    [    1.207912] mtdoops: mtd device (mtddev=name/number) must be supplied
    [    1.218452] usbcore: registered new interface driver asix
    [    1.224332] usbcore: registered new interface driver ax88179_178a
    [    1.230872] usbcore: registered new interface driver cdc_ether
    [    1.237141] usbcore: registered new interface driver smsc95xx
    [    1.243311] usbcore: registered new interface driver net1080
    [    1.249396] usbcore: registered new interface driver cdc_subset
    [    1.255711] usbcore: registered new interface driver zaurus
    [    1.261764] usbcore: registered new interface driver cdc_ncm
    [    1.268286] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
    [    1.275129] ehci-pci: EHCI PCI platform driver
    [    1.279933] ehci-omap: OMAP-EHCI Host Controller driver
    [    1.285811] usbcore: registered new interface driver cdc_wdm
    [    1.291915] usbcore: registered new interface driver usb-storage
    [    1.299196] mousedev: PS/2 mouse device common for all mice
    [    1.307815] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
    [    1.315258] 44e3e000.rtc: already running
    [    1.320209] i2c /dev entries driver
    [    1.324395] Driver for 1-wire Dallas network protocol.
    [    1.331542] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    1.340164] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@48060000[0]'
    [    1.340182] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@48060000[0]'
    [    1.340665] omap_hsmmc 48060000.mmc: unable to get vmmc regulator -517
    [    1.347579] platform 48060000.mmc: Driver omap_hsmmc requests probe deferral
    [    1.355090] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@481d8000[0]'
    [    1.355103] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@481d8000[0]'
    [    1.355292] omap_hsmmc 481d8000.mmc: unable to get vmmc regulator -517
    [    1.362191] platform 481d8000.mmc: Driver omap_hsmmc requests probe deferral
    [    1.369640] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@47810000[0]'
    [    1.369651] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@47810000[0]'
    [    1.490112] ledtrig-cpu: registered to indicate activity on CPUs
    [    1.496715] omap-aes 53500000.aes: OMAP AES hw accel rev: 3.2
    [    1.507132] omap-sham 53100000.sham: hw accel on OMAP rev 4.3
    [    1.513220] omap_hsmmc 47810000.mmc: card claims to support voltages below de
    fined range
    [    1.523148] usbcore: registered new interface driver usbhid
    [    1.528974] usbhid: USB HID core driver
    [    1.533209] platform 44d00000.wkup_m3: Driver wkup_m3 requests probe deferral
    [    1.541921] oprofile: using arm/armv7
    [    1.546021] TCP: cubic registered
    [    1.549519] Initializing XFRM netlink socket
    [    1.553995] NET: Registered protocol family 17
    [    1.558668] NET: Registered protocol family 15
    [    1.563365] 8021q: 802.1Q VLAN Support v1.8
    [    1.567803] Key type dns_resolver registered
    [    1.573062] cpu cpu0: of_pm_voltdm_notifier_register: Failed to get cpu0 regu
    lator/voltdm: -517
    [    1.582182] cpu cpu0: cpu0 clock notifier not ready, retry
    [    1.587919] platform cpufreq-cpu0.0: Driver cpufreq-cpu0 requests probe defer
    ral
    [    1.596250] PM: Voltage scaling data blob not provided from DT.
    [    1.602557] PM: bootloader does not support rtc-only!
    [    1.607849] ThumbEE CPU extension supported.
    [    1.613817] vbat: disabling
    [    1.616740] regulator-dummy: disabling
    [    1.622855] tps65910 0-002d: No interrupt support, no core IRQ
    [    1.633443] vrtc: 1800 mV
    [    1.636553] vrtc: supplied by vbat
    [    1.641842] mmc0: queuing unknown CIS tuple 0x91 (3 bytes)
    [    1.647600] vio: at 1500 mV
    [    1.650711] vio: supplied by vbat
    [    1.655570] mmc0: new high speed SDIO card at address 0001
    [    1.663049] vdd_mpu: 912 <--> 1375 mV at 1262 mV
    [    1.668050] vdd_mpu: supplied by vbat
    [    1.674034] vdd_core: 912 <--> 1150 mV at 1137 mV
    [    1.679117] vdd_core: supplied by vbat
    [    1.684446] vdd3: 5000 mV
    [    1.688668] vdig1: at 1800 mV
    [    1.691953] vdig1: supplied by vbat
    [    1.697013] vdig2: at 1800 mV
    [    1.700291] vdig2: supplied by vbat
    [    1.705341] vpll: at 1800 mV
    [    1.708506] vpll: supplied by vbat
    [    1.713506] vdac: at 1800 mV
    [    1.716674] vdac: supplied by vbat
    [    1.721653] vaux1: at 1800 mV
    [    1.724917] vaux1: supplied by vbat
    [    1.729957] vaux2: at 3300 mV
    [    1.733214] vaux2: supplied by vbat
    [    1.738264] vaux33: at 3300 mV
    [    1.741633] vaux33: supplied by vbat
    [    1.746766] vmmc: 1800 <--> 3300 mV at 3300 mV
    [    1.751592] vmmc: supplied by vbat
    [    1.757412] bq32k 0-0068: rtc core: registered bq32k as rtc1
    [    1.763861] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz
    [    1.770121] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@48060000[0]'
    [    1.770137] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@48060000[0]'
    [    1.809624] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@481d8000[0]'
    [    1.809643] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/mmc@481d8000[0]'
    [    1.849747]  remoteproc0: wkup_m3 is available
    [    1.854394]  remoteproc0: Note: remoteproc is still under development and con
    sidered experimental.
    [    1.863777]  remoteproc0: THE BINARY FORMAT IS NOT YET FINALIZED, and backwar
    d compatibility isn't yet guaranteed.
    [    1.874718]  remoteproc0: Direct firmware load failed with error -2
    [    1.881276]  remoteproc0: Falling back to user helper
    [    1.887280] cpu cpu0: of_pm_voltdm_notifier_register: Fail calculating voltag
    e latency[950000<->1260000]:-22
    [    1.953077] mmc2: BKOPS_EN bit is not set
    [    1.959235] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
    [    1.965604] davinci_mdio 4a101000.mdio: detected phy mask fffffffc
    [    1.973588] libphy: 4a101000.mdio: probed
    [    1.977787] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driv
    er RTL8211F Gigabit Ethernet
    [    1.987794] davinci_mdio 4a101000.mdio: phy[1]: device 4a101000.mdio:01, driv
    er RTL8211F Gigabit Ethernet
    [    1.998608] cpsw 4a100000.ethernet: Detected MACID = d0:5f:b8:d3:60:cd
    [    2.007235] mmc2: new high speed MMC card at address 0001
    [    2.013725] mmcblk0: mmc2:0001 P1XXXX 3.60 GiB
    [    2.018596] bq32k 0-0068: setting system clock to 2015-11-19 21:34:21 UTC (14
    47968861)
    [    2.030226] mmcblk0boot0: mmc2:0001 P1XXXX partition 1 16.0 MiB
    [    2.036614] mmcblk0boot1: mmc2:0001 P1XXXX partition 2 16.0 MiB
    [    2.045478]  mmcblk0: p1 p2 p3 p4 < p5 p6 p7 >
    [    2.054401]  mmcblk0boot1: unknown partition table
    [    2.061632]  mmcblk0boot0: unknown partition table
    [    2.075705] EXT4-fs (mmcblk0p6): mounted filesystem with ordered data mode. O
    pts: (null)
    [    2.084251] VFS: Mounted root (ext4 filesystem) readonly on device 179:6.
    [    2.096834] devtmpfs: mounted
    [    2.100298] Freeing unused kernel memory: 252K (c0754000 - c0793000)
    [    2.741707] FAT-fs (mmcblk0p2): Volume was not properly unmounted. Some data
    may be corrupt. Please run fsck.
    [    2.764172] EXT4-fs (mmcblk0p7): mounted filesystem with ordered data mode. O
    pts: (null)
    [    2.776269] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. O
    pts: (null)
    [    2.985808] udevd[823]: starting version 182
    [    3.172859] Bluetooth: Core ver 2.18
    [    3.176689] NET: Registered protocol family 31
    [    3.181391] Bluetooth: HCI device and connection manager initialized
    [    3.188048] Bluetooth: HCI socket layer initialized
    [    3.193161] Bluetooth: L2CAP socket layer initialized
    [    3.198464] Bluetooth: SCO socket layer initialized
    [    3.621823] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/usb@47400000/usb-phy@47401300[0]'
    [    3.621911] 47401300.usb-phy supply vcc not found, using dummy regulator
    [    3.759501] cryptodev: driver 1.6 loaded.
    [    3.780291] of_get_named_gpiod_flags: can't parse gpios property of node '/oc
    p/usb@47400000/usb-phy@47401b00[0]'
    [    3.780377] 47401b00.usb-phy supply vcc not found, using dummy regulator
    [    3.928442] hdev dd55f000
    [    3.972982] HCI device registered (hdev dd55f000)
    [    3.989320] hci0 dd55f000
    [    3.989350] (stc):  chnl_id list empty :4
    [    3.993447] (stk) : st_kim_start
    [    4.101348] (stk) :ldisc_install = 1
    [    4.302464]  remoteproc0: powering up wkup_m3
    [    4.307827]  remoteproc0: Booting fw image am335x-pm-firmware.elf, size 15437
    6
    [    4.315896] PM: CM3 Firmware Version = 0x190
    [    4.320526]  remoteproc0: remote processor wkup_m3 is now up
    [    4.509798] CAN device driver interface
    [    4.568547] davinci-mcasp 4803c000.mcasp: Invalid McASP version: 2
    [    4.575095] davinci-mcasp 4803c000.mcasp: register PCM failed: -22
    [    4.581602] davinci-mcasp: probe of 4803c000.mcasp failed with error -22
    [    4.631673] random: nonblocking pool is initialized
    [    4.636889] EXT4-fs (mmcblk0p6): re-mounted. Opts: (null)
    [    4.674140] c_can_platform 481cc000.can: c_can_platform device registered (re
    gs=fa1cc000, irq=68)
    [    5.099352] (stk) :ldisc installation timeout
    [    5.103743] (stk) :ldisc_install = 0
    [    5.619748] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk
     split, HB-ISO Rx, HB-ISO Tx, SoftConn)
    [    5.619771] musb-hdrc: MHDRC RTL version 2.0
    [    5.619780] musb-hdrc: setup fifo_mode 4
    [    5.619799] musb-hdrc: 28/31 max ep, 16384/16384 memory
    [    5.621819] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk
     split, HB-ISO Rx, HB-ISO Tx, SoftConn)
    [    5.621837] musb-hdrc: MHDRC RTL version 2.0
    [    5.621845] musb-hdrc: setup fifo_mode 4
    [    5.621859] musb-hdrc: 28/31 max ep, 16384/16384 memory
    [    5.621950] musb-hdrc musb-hdrc.2.auto: MUSB HDRC host driver
    [    5.639509] musb-hdrc musb-hdrc.2.auto: new USB bus registered, assigned bus
    number 1
    [    5.716661] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
    [    5.723835] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=
    1
    [    5.731393] usb usb1: Product: MUSB HDRC host driver
    [    5.736571] usb usb1: Manufacturer: Linux 3.14.51-g288dfb5 musb-hcd
    [    5.743119] usb usb1: SerialNumber: musb-hdrc.2.auto
    [    5.935074] hub 1-0:1.0: USB hub found
    [    5.953116] cfg80211: Calling CRDA to update world regulatory domain
    [    5.966476] hub 1-0:1.0: 1 port detected
    [    6.099378] (stk) : timed out waiting for ldisc to be un-installed
    [    6.212232] (stk) :ldisc_install = 1
    [    6.243065] wl18xx_driver wl18xx.0.auto: Direct firmware load failed with err
    or -2
    [    6.251042] wl18xx_driver wl18xx.0.auto: Falling back to user helper
    [    6.579370] usb 1-1: new high-speed USB device number 2 using musb-hdrc
    [    6.720148] wlcore: wl18xx HW: 183x or 180x, PG 2.2 (ROM 0x11)
    [    6.732929] wlcore: loaded
    [    6.740770] usb 1-1: New USB device found, idVendor=05e3, idProduct=0610
    [    6.747782] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
    [    6.755273] usb 1-1: Product: USB2.0 Hub
    [    6.784523] hub 1-1:1.0: USB hub found
    [    6.789275] hub 1-1:1.0: 4 ports detected
    [    7.209335] (stk) :ldisc installation timeout
    [    7.213728] (stk) :ldisc_install = 0
    

    The patch provided by TI can not be applied cleanly according to our software team. 

    The code it would modify is attached.

    A few comments:
    1) lines 770-777 look nothing like the lines in the patch
    2) If lines 811-815 are the intended target of the patch, then it looks like the patch has already been applied to our source


    /*
     * hostapd / Hardware feature query and different modes
     * Copyright 2002-2003, Instant802 Networks, Inc.
     * Copyright 2005-2006, Devicescape Software, Inc.
     * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as
     * published by the Free Software Foundation.
     *
     * Alternatively, this software may be distributed under the terms of BSD
     * license.
     *
     * See README and COPYING for more details.
     */
    
    #include "utils/includes.h"
    
    #include "utils/common.h"
    #include "utils/eloop.h"
    #include "common/ieee802_11_defs.h"
    #include "common/ieee802_11_common.h"
    #include "common/wpa_ctrl.h"
    #include "hostapd.h"
    #include "ap_config.h"
    #include "ap_drv_ops.h"
    #include "acs.h"
    #include "hw_features.h"
    
    
    void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
    			      size_t num_hw_features)
    {
    	size_t i;
    
    	if (hw_features == NULL)
    		return;
    
    	for (i = 0; i < num_hw_features; i++) {
    		os_free(hw_features[i].channels);
    		os_free(hw_features[i].rates);
    	}
    
    	os_free(hw_features);
    }
    
    
    #ifndef CONFIG_NO_STDOUT_DEBUG
    char * dfs_info(struct hostapd_channel_data *chan)
    {
    	static char info[256];
    	char *state;
    
    	switch (chan->flag & HOSTAPD_CHAN_DFS_MASK) {
    	case HOSTAPD_CHAN_DFS_UNKNOWN:
    		state = "unknown";
    		break;
    	case HOSTAPD_CHAN_DFS_USABLE:
    		state = "usable";
    		break;
    	case HOSTAPD_CHAN_DFS_UNAVAILABLE:
    		state = "unavailable";
    		break;
    	case HOSTAPD_CHAN_DFS_AVAILABLE:
    		state = "available";
    		break;
    	default:
    		return "";
    	}
    	os_snprintf(info, sizeof(info), " (DFS state = %s)", state);
    	info[sizeof(info) - 1] = '\0';
    
    	return info;
    }
    #endif /* CONFIG_NO_STDOUT_DEBUG */
    
    
    int hostapd_get_hw_features(struct hostapd_iface *iface)
    {
    	struct hostapd_data *hapd = iface->bss[0];
    	int ret = 0, i, j;
    	u16 num_modes, flags;
    	struct hostapd_hw_modes *modes;
    
    	if (hostapd_drv_none(hapd))
    		return -1;
    	modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
    	if (modes == NULL) {
    		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    			       HOSTAPD_LEVEL_DEBUG,
    			       "Fetching hardware channel/rate support not "
    			       "supported.");
    		return -1;
    	}
    
    	iface->hw_flags = flags;
    
    	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
    	iface->hw_features = modes;
    	iface->num_hw_features = num_modes;
    
    	for (i = 0; i < num_modes; i++) {
    		struct hostapd_hw_modes *feature = &modes[i];
    		int dfs_enabled = hapd->iconf->ieee80211h &&
    			(iface->drv_flags & WPA_DRIVER_FLAGS_RADAR);
    
    		/* set flag for channels we can use in current regulatory
    		 * domain */
    		for (j = 0; j < feature->num_channels; j++) {
    			int dfs = 0;
    
    			/*
    			 * Disable all channels that are marked not to allow
    			 * IBSS operation or active scanning.
    			 * Use radar channels only if the driver supports DFS.
    			 */
    			if ((feature->channels[j].flag &
    			     HOSTAPD_CHAN_RADAR) && dfs_enabled) {
    				dfs = 1;
    			} else if (feature->channels[j].flag &
    				   (HOSTAPD_CHAN_NO_IBSS |
    				    HOSTAPD_CHAN_PASSIVE_SCAN |
    				    HOSTAPD_CHAN_RADAR)) {
    				feature->channels[j].flag |=
    					HOSTAPD_CHAN_DISABLED;
    			}
    
    			if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED)
    				continue;
    
    			wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d "
    				   "chan=%d freq=%d MHz max_tx_power=%d dBm%s",
    				   feature->mode,
    				   feature->channels[j].chan,
    				   feature->channels[j].freq,
    				   feature->channels[j].max_tx_power,
    				   dfs ? dfs_info(&feature->channels[j]) : "");
    		}
    	}
    
    	return ret;
    }
    
    
    int hostapd_prepare_rates(struct hostapd_iface *iface,
    			  struct hostapd_hw_modes *mode)
    {
    	int i, num_basic_rates = 0;
    	int basic_rates_a[] = { 60, 120, 240, -1 };
    	int basic_rates_b[] = { 10, 20, -1 };
    	int basic_rates_g[] = { 10, 20, 55, 110, -1 };
    	int *basic_rates;
    
    	if (iface->conf->basic_rates)
    		basic_rates = iface->conf->basic_rates;
    	else switch (mode->mode) {
    	case HOSTAPD_MODE_IEEE80211A:
    		basic_rates = basic_rates_a;
    		break;
    	case HOSTAPD_MODE_IEEE80211B:
    		basic_rates = basic_rates_b;
    		break;
    	case HOSTAPD_MODE_IEEE80211G:
    		basic_rates = basic_rates_g;
    		break;
    	case HOSTAPD_MODE_IEEE80211AD:
    		return 0; /* No basic rates for 11ad */
    	default:
    		return -1;
    	}
    
    	i = 0;
    	while (basic_rates[i] >= 0)
    		i++;
    	if (i)
    		i++; /* -1 termination */
    	os_free(iface->basic_rates);
    	iface->basic_rates = os_malloc(i * sizeof(int));
    	if (iface->basic_rates)
    		os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int));
    
    	os_free(iface->current_rates);
    	iface->num_rates = 0;
    
    	iface->current_rates =
    		os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data));
    	if (!iface->current_rates) {
    		wpa_printf(MSG_ERROR, "Failed to allocate memory for rate "
    			   "table.");
    		return -1;
    	}
    
    	for (i = 0; i < mode->num_rates; i++) {
    		struct hostapd_rate_data *rate;
    
    		if (iface->conf->supported_rates &&
    		    !hostapd_rate_found(iface->conf->supported_rates,
    					mode->rates[i]))
    			continue;
    
    		rate = &iface->current_rates[iface->num_rates];
    		rate->rate = mode->rates[i];
    		if (hostapd_rate_found(basic_rates, rate->rate)) {
    			rate->flags |= HOSTAPD_RATE_BASIC;
    			num_basic_rates++;
    		}
    		wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x",
    			   iface->num_rates, rate->rate, rate->flags);
    		iface->num_rates++;
    	}
    
    	if ((iface->num_rates == 0 || num_basic_rates == 0) &&
    	    (!iface->conf->ieee80211n || !iface->conf->require_ht)) {
    		wpa_printf(MSG_ERROR, "No rates remaining in supported/basic "
    			   "rate sets (%d,%d).",
    			   iface->num_rates, num_basic_rates);
    		return -1;
    	}
    
    	return 0;
    }
    
    
    #ifdef CONFIG_IEEE80211N
    static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
    {
    	int sec_chan, ok, j, first;
    	int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
    			  184, 192 };
    	size_t k;
    
    	if (!iface->conf->secondary_channel)
    		return 1; /* HT40 not used */
    
    	sec_chan = iface->conf->channel + iface->conf->secondary_channel * 4;
    	wpa_printf(MSG_DEBUG, "HT40: control channel: %d  "
    		   "secondary channel: %d",
    		   iface->conf->channel, sec_chan);
    
    	/* Verify that HT40 secondary channel is an allowed 20 MHz
    	 * channel */
    	ok = 0;
    	for (j = 0; j < iface->current_mode->num_channels; j++) {
    		struct hostapd_channel_data *chan =
    			&iface->current_mode->channels[j];
    		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
    		    chan->chan == sec_chan) {
    			ok = 1;
    			break;
    		}
    	}
    	if (!ok) {
    		wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
    			   sec_chan);
    		return 0;
    	}
    
    	/*
    	 * Verify that HT40 primary,secondary channel pair is allowed per
    	 * IEEE 802.11n Annex J. This is only needed for 5 GHz band since
    	 * 2.4 GHz rules allow all cases where the secondary channel fits into
    	 * the list of allowed channels (already checked above).
    	 */
    	if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
    		return 1;
    
    	if (iface->conf->secondary_channel > 0)
    		first = iface->conf->channel;
    	else
    		first = sec_chan;
    
    	ok = 0;
    	for (k = 0; k < ARRAY_SIZE(allowed); k++) {
    		if (first == allowed[k]) {
    			ok = 1;
    			break;
    		}
    	}
    	if (!ok) {
    		wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed",
    			   iface->conf->channel,
    			   iface->conf->secondary_channel);
    		return 0;
    	}
    
    	return 1;
    }
    
    
    static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
    {
    	if (iface->conf->secondary_channel > 0) {
    		iface->conf->channel += 4;
    		iface->conf->secondary_channel = -1;
    	} else {
    		iface->conf->channel -= 4;
    		iface->conf->secondary_channel = 1;
    	}
    }
    
    
    static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res *bss,
    					int *pri_chan, int *sec_chan)
    {
    	struct ieee80211_ht_operation *oper;
    	struct ieee802_11_elems elems;
    
    	*pri_chan = *sec_chan = 0;
    
    	ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
    	if (elems.ht_operation &&
    	    elems.ht_operation_len >= sizeof(*oper)) {
    		oper = (struct ieee80211_ht_operation *) elems.ht_operation;
    		*pri_chan = oper->control_chan;
    		if (oper->ht_param & HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH) {
    			int sec = oper->ht_param &
    				HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
    			if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
    				*sec_chan = *pri_chan + 4;
    			else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
    				*sec_chan = *pri_chan - 4;
    		}
    	}
    }
    
    
    static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
    				     struct wpa_scan_results *scan_res)
    {
    	int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss;
    	int bss_pri_chan, bss_sec_chan;
    	size_t i;
    	int match;
    
    	pri_chan = iface->conf->channel;
    	sec_chan = iface->conf->secondary_channel * 4;
    	pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan);
    	if (iface->conf->secondary_channel > 0)
    		sec_freq = pri_freq + 20;
    	else
    		sec_freq = pri_freq - 20;
    
    	/*
    	 * Switch PRI/SEC channels if Beacons were detected on selected SEC
    	 * channel, but not on selected PRI channel.
    	 */
    	pri_bss = sec_bss = 0;
    	for (i = 0; i < scan_res->num; i++) {
    		struct wpa_scan_res *bss = scan_res->res[i];
    		if (bss->freq == pri_freq)
    			pri_bss++;
    		else if (bss->freq == sec_freq)
    			sec_bss++;
    	}
    	if (sec_bss && !pri_bss) {
    		wpa_printf(MSG_INFO, "Switch own primary and secondary "
    			   "channel to get secondary channel with no Beacons "
    			   "from other BSSes");
    		ieee80211n_switch_pri_sec(iface);
    	}
    
    	/*
    	 * Match PRI/SEC channel with any existing HT40 BSS on the same
    	 * channels that we are about to use (if already mixed order in
    	 * existing BSSes, use own preference).
    	 */
    	match = 0;
    	for (i = 0; i < scan_res->num; i++) {
    		struct wpa_scan_res *bss = scan_res->res[i];
    		ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
    		if (pri_chan == bss_pri_chan &&
    		    sec_chan == bss_sec_chan) {
    			match = 1;
    			break;
    		}
    	}
    	if (!match) {
    		for (i = 0; i < scan_res->num; i++) {
    			struct wpa_scan_res *bss = scan_res->res[i];
    			ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan,
    						    &bss_sec_chan);
    			if (pri_chan == bss_sec_chan &&
    			    sec_chan == bss_pri_chan) {
    				wpa_printf(MSG_INFO, "Switch own primary and "
    					   "secondary channel due to BSS "
    					   "overlap with " MACSTR,
    					   MAC2STR(bss->bssid));
    				ieee80211n_switch_pri_sec(iface);
    				break;
    			}
    		}
    	}
    
    	return 1;
    }
    
    
    static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
    				      struct wpa_scan_results *scan_res)
    {
    	int pri_freq, sec_freq;
    	int affected_start, affected_end;
    	size_t i;
    
    	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
    	if (iface->conf->secondary_channel > 0)
    		sec_freq = pri_freq + 20;
    	else
    		sec_freq = pri_freq - 20;
    	affected_start = (pri_freq + sec_freq) / 2 - 25;
    	affected_end = (pri_freq + sec_freq) / 2 + 25;
    	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
    		   affected_start, affected_end);
    	for (i = 0; i < scan_res->num; i++) {
    		struct wpa_scan_res *bss = scan_res->res[i];
    		int pri = bss->freq;
    		int sec = pri;
    		int sec_chan, pri_chan;
    
    		ieee80211n_get_pri_sec_chan(bss, &pri_chan, &sec_chan);
    
    		if (sec_chan) {
    			if (sec_chan < pri_chan)
    				sec = pri - 20;
    			else
    				sec = pri + 20;
    		}
    
    		if ((pri < affected_start || pri > affected_end) &&
    		    (sec < affected_start || sec > affected_end))
    			continue; /* not within affected channel range */
    
    		wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
    			   " freq=%d pri=%d sec=%d",
    			   MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
    
    		if (sec_chan) {
    			if (pri_freq != pri || sec_freq != sec) {
    				wpa_printf(MSG_DEBUG, "40 MHz pri/sec "
    					   "mismatch with BSS " MACSTR
    					   " <%d,%d> (chan=%d%c) vs. <%d,%d>",
    					   MAC2STR(bss->bssid),
    					   pri, sec, pri_chan,
    					   sec > pri ? '+' : '-',
    					   pri_freq, sec_freq);
    				return 0;
    			}
    		}
    
    		/* TODO: 40 MHz intolerant */
    	}
    
    	return 1;
    }
    
    
    static int ieee80211n_check_scan(struct hostapd_iface *iface,
    								struct wpa_scan_results *scan_res)
    {
    	int oper40;
    	int res;
    
    	if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
    		oper40 = ieee80211n_check_40mhz_5g(iface, scan_res);
    	else
    		oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res);
    
    	if (!oper40) {
    		wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
    			   "channel pri=%d sec=%d based on overlapping BSSes",
    			   iface->conf->channel,
    			   iface->conf->channel +
    			   iface->conf->secondary_channel * 4);
    		iface->conf->secondary_channel = 0;
    	}
    
    	res = ieee80211n_allowed_ht40_channel_pair(iface);
    	hostapd_setup_interface_complete(iface, !res);
    	return 1;
    }
    
    
    static void ieee80211n_get_res_and_check_scan(struct hostapd_iface *iface)
    {
    	struct wpa_scan_results *scan_res;
    
    	/* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
    	 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
    
    	iface->scan_cb = NULL;
    
    	scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
    
    	if (scan_res == NULL) {
    		hostapd_setup_interface_complete(iface, 1);
    		return;
    	}
    
    	ieee80211n_check_scan(iface, scan_res);
    	wpa_scan_results_free(scan_res);
    }
    
    
    static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
    					 struct wpa_driver_scan_params *params)
    {
    	/* Scan only the affected frequency range */
    	int pri_freq, sec_freq;
    	int affected_start, affected_end;
    	int i, pos;
    	struct hostapd_hw_modes *mode;
    
    	if (iface->current_mode == NULL)
    		return;
    
    	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
    	if (iface->conf->secondary_channel > 0)
    		sec_freq = pri_freq + 20;
    	else
    		sec_freq = pri_freq - 20;
    	affected_start = (pri_freq + sec_freq) / 2 - 25;
    	affected_end = (pri_freq + sec_freq) / 2 + 25;
    	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
    		   affected_start, affected_end);
    
    	mode = iface->current_mode;
    	params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
    	if (params->freqs == NULL)
    		return;
    	pos = 0;
    
    	for (i = 0; i < mode->num_channels; i++) {
    		struct hostapd_channel_data *chan = &mode->channels[i];
    		if (chan->flag & HOSTAPD_CHAN_DISABLED)
    			continue;
    		if (chan->freq < affected_start ||
    		    chan->freq > affected_end)
    			continue;
    		params->freqs[pos++] = chan->freq;
    	}
    }
    
    
    static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
    					struct wpa_driver_scan_params *params)
    {
    	/* Scan only the affected frequency range */
    	int pri_freq;
    	int affected_start, affected_end;
    	int i, pos;
    	struct hostapd_hw_modes *mode;
    
    	if (iface->current_mode == NULL)
    		return;
    
    	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
    	if (iface->conf->secondary_channel > 0) {
    		affected_start = pri_freq - 10;
    		affected_end = pri_freq + 30;
    	} else {
    		affected_start = pri_freq - 30;
    		affected_end = pri_freq + 10;
    	}
    	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
    		   affected_start, affected_end);
    
    	mode = iface->current_mode;
    	params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
    	if (params->freqs == NULL)
    		return;
    	pos = 0;
    
    	for (i = 0; i < mode->num_channels; i++) {
    		struct hostapd_channel_data *chan = &mode->channels[i];
    		if (chan->flag & HOSTAPD_CHAN_DISABLED)
    			continue;
    		if (chan->freq < affected_start ||
    		    chan->freq > affected_end)
    			continue;
    		params->freqs[pos++] = chan->freq;
    	}
    }
    
    
    static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
    {
    	struct wpa_driver_scan_params params;
    
    	if (!iface->conf->secondary_channel)
    		return 0; /* HT40 not used */
    
    	hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
    	wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
    		   "40 MHz channel");
    	os_memset(&params, 0, sizeof(params));
    	if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    		ieee80211n_scan_channels_2g4(iface, &params);
    	else
    		ieee80211n_scan_channels_5g(iface, &params);
    	if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
    		wpa_printf(MSG_ERROR, "Failed to request a scan of "
    			   "neighboring BSSes");
    		os_free(params.freqs);
    		return -1;
    	}
    	os_free(params.freqs);
    
    	iface->scan_cb = ieee80211n_get_res_and_check_scan;
    	return 1;
    }
    
    
    static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
    {
    	u16 hw = iface->current_mode->ht_capab;
    	u16 conf = iface->conf->ht_capab;
    
    	if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
    	    !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [LDPC]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
    	    !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [HT40*]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) &&
    	    (conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [SMPS-*]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
    	    !(hw & HT_CAP_INFO_GREEN_FIELD)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [GF]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
    	    !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [SHORT-GI-20]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
    	    !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [SHORT-GI-40]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [TX-STBC]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
    	    (hw & HT_CAP_INFO_RX_STBC_MASK)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [RX-STBC*]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_DELAYED_BA) &&
    	    !(hw & HT_CAP_INFO_DELAYED_BA)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [DELAYED-BA]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
    	    !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [MAX-AMSDU-7935]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
    	    !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [DSSS_CCK-40]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_PSMP_SUPP) && !(hw & HT_CAP_INFO_PSMP_SUPP)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [PSMP]");
    		return 0;
    	}
    
    	if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
    	    !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured "
    			   "HT capability [LSIG-TXOP-PROT]");
    		return 0;
    	}
    
    	return 1;
    }
    
    
    #ifdef CONFIG_IEEE80211AC
    
    static int ieee80211ac_cap_check(u32 hw, u32 conf, u32 cap, const char *name)
    {
    	u32 req_cap = conf & cap;
    
    	/*
    	 * Make sure we support all requested capabilities.
    	 * NOTE: We assume that 'cap' represents a capability mask,
    	 * not a discrete value.
    	 */
    	if ((hw & req_cap) != req_cap) {
    		wpa_printf(MSG_ERROR, "Driver does not support configured VHT capability [%s]",
    			   name);
    		return 0;
    	}
    	return 1;
    }
    
    
    static int ieee80211ac_cap_check_max(u32 hw, u32 conf, u32 cap,
    				     const char *name)
    {
    	u32 hw_max = hw & cap;
    	u32 conf_val = conf & cap;
    
    	if (conf_val > hw_max) {
    		int offset = find_first_bit(cap);
    		wpa_printf(MSG_ERROR, "Configured VHT capability [%s] exceeds max value supported by the driver (%d > %d)",
    			   name, conf_val >> offset, hw_max >> offset);
    		return 0;
    	}
    	return 1;
    }
    
    
    static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
    {
    	u32 hw = iface->current_mode->vht_capab;
    	u32 conf = iface->conf->vht_capab;
    
    	wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x",
    		   hw, conf);
    
    #define VHT_CAP_CHECK(cap) \
    	do { \
    		if (!ieee80211ac_cap_check(hw, conf, cap, #cap)) \
    			return 0; \
    	} while (0)
    
    #define VHT_CAP_CHECK_MAX(cap) \
    	do { \
    		if (!ieee80211ac_cap_check_max(hw, conf, cap, #cap)) \
    			return 0; \
    	} while (0)
    
    	VHT_CAP_CHECK_MAX(VHT_CAP_MAX_MPDU_LENGTH_MASK);
    	VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ);
    	VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
    	VHT_CAP_CHECK(VHT_CAP_RXLDPC);
    	VHT_CAP_CHECK(VHT_CAP_SHORT_GI_80);
    	VHT_CAP_CHECK(VHT_CAP_SHORT_GI_160);
    	VHT_CAP_CHECK(VHT_CAP_TXSTBC);
    	VHT_CAP_CHECK_MAX(VHT_CAP_RXSTBC_MASK);
    	VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMER_CAPABLE);
    	VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMEE_CAPABLE);
    	VHT_CAP_CHECK_MAX(VHT_CAP_BEAMFORMEE_STS_MAX);
    	VHT_CAP_CHECK_MAX(VHT_CAP_SOUNDING_DIMENSION_MAX);
    	VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMER_CAPABLE);
    	VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMEE_CAPABLE);
    	VHT_CAP_CHECK(VHT_CAP_VHT_TXOP_PS);
    	VHT_CAP_CHECK(VHT_CAP_HTC_VHT);
    	VHT_CAP_CHECK_MAX(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT);
    	VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB);
    	VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
    	VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
    	VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
    
    #undef VHT_CAP_CHECK
    #undef VHT_CAP_CHECK_MAX
    
    	return 1;
    }
    #endif /* CONFIG_IEEE80211AC */
    
    #endif /* CONFIG_IEEE80211N */
    
    
    int hostapd_check_ht_capab(struct hostapd_iface *iface,
    			   struct wpa_scan_results *scan_res)
    {
    #ifdef CONFIG_IEEE80211N
    	int ret;
    	if (!iface->conf->ieee80211n)
    		goto out;
    	if (!ieee80211n_supported_ht_capab(iface))
    		return -1;
    #ifdef CONFIG_IEEE80211AC
    	if (!ieee80211ac_supported_vht_capab(iface))
    		return -1;
    #endif /* CONFIG_IEEE80211AC */
    	if (scan_res)
    		ret = ieee80211n_check_scan(iface, scan_res);
    	else
    		ret = ieee80211n_check_40mhz(iface);
    	/* sometimes the init should proceed async or fail */
    	if (ret)
    		return ret;
    	if (!ieee80211n_allowed_ht40_channel_pair(iface))
    		return -1;
    out:
    #endif /* CONFIG_IEEE80211N */
    
    	/* we are in an async callback if we have scan results */
    	if (scan_res)
    		hostapd_setup_interface_complete(iface, 0);
    	return 0;
    }
    
    
    static int hostapd_is_usable_chan(struct hostapd_iface *iface,
    				  int channel, int primary)
    {
    	int i;
    	struct hostapd_channel_data *chan;
    
    	for (i = 0; i < iface->current_mode->num_channels; i++) {
    		chan = &iface->current_mode->channels[i];
    		if (chan->chan != channel)
    			continue;
    
    		if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
    			return 1;
    
    		wpa_printf(MSG_DEBUG,
    			   "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s%s",
    			   primary ? "" : "Configured HT40 secondary ",
    			   i, chan->chan, chan->flag,
    			   chan->flag & HOSTAPD_CHAN_NO_IBSS ? " NO-IBSS" : "",
    			   chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN ?
    			   " PASSIVE-SCAN" : "",
    			   chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
    	}
    
    	return 0;
    }
    
    
    static int hostapd_is_usable_chans(struct hostapd_iface *iface)
    {
    	if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
    		return 0;
    
    	if (!iface->conf->secondary_channel)
    		return 1;
    
    	return hostapd_is_usable_chan(iface, iface->conf->channel +
    				      iface->conf->secondary_channel * 4, 0);
    }
    
    
    static enum hostapd_chan_status
    hostapd_check_chans(struct hostapd_iface *iface)
    {
    	if (iface->conf->channel) {
    		if (hostapd_is_usable_chans(iface))
    			return HOSTAPD_CHAN_VALID;
    		else
    			return HOSTAPD_CHAN_INVALID;
    	}
    
    	/*
    	 * The user set channel=0 or channel=acs_survey
    	 * which is used to trigger ACS.
    	 */
    
    	switch (acs_init(iface)) {
    	case HOSTAPD_CHAN_ACS:
    		return HOSTAPD_CHAN_ACS;
    	case HOSTAPD_CHAN_VALID:
    	case HOSTAPD_CHAN_INVALID:
    	default:
    		return HOSTAPD_CHAN_INVALID;
    	}
    }
    
    
    static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
    {
    	hostapd_logger(iface->bss[0], NULL,
    		       HOSTAPD_MODULE_IEEE80211,
    		       HOSTAPD_LEVEL_WARNING,
    		       "Configured channel (%d) not found from the "
    		       "channel list of current mode (%d) %s",
    		       iface->conf->channel,
    		       iface->current_mode->mode,
    		       hostapd_hw_mode_txt(iface->current_mode->mode));
    	hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
    		       HOSTAPD_LEVEL_WARNING,
    		       "Hardware does not support configured channel");
    }
    
    
    int hostapd_acs_completed(struct hostapd_iface *iface, int err)
    {
    	int ret = -1;
    
    	if (err)
    		goto out;
    
    	switch (hostapd_check_chans(iface)) {
    	case HOSTAPD_CHAN_VALID:
    		wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
    			ACS_EVENT_COMPLETED "freq=%d channel=%d",
    			hostapd_hw_get_freq(iface->bss[0],
    					    iface->conf->channel),
    			iface->conf->channel);
    		break;
    	case HOSTAPD_CHAN_ACS:
    		wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
    		wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
    		hostapd_notify_bad_chans(iface);
    		goto out;
    	case HOSTAPD_CHAN_INVALID:
    	default:
    		wpa_printf(MSG_ERROR, "ACS picked unusable channels");
    		wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED);
    		hostapd_notify_bad_chans(iface);
    		goto out;
    	}
    
    	ret = hostapd_check_ht_capab(iface,NULL);
    	if (ret < 0)
    		goto out;
    	if (ret == 1) {
    		wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback");
    		return 0;
    	}
    
    	ret = 0;
    out:
    	return hostapd_setup_interface_complete(iface, ret);
    }
    
    static int valid_ap_channel(struct hostapd_iface *iface, int chan)
    {
    	int j;
    	struct hostapd_channel_data *c;
    	int *list;
    
    	/* don't allow AP on channel 14 - only JP 11b rates */
    	if (chan == 14)
    		return 0;
    
    	/* don't allow JP-only channels */
    	if (chan == 38 || chan == 42)
    		return 0;
    
    	/* don't allow channels on the the ACS blacklist */
    	if (iface->conf->acs_blacklist) {
    		list = iface->conf->acs_blacklist;
    		for (j = 0; list[j] >= 0; j++)
    			if (chan == list[j])
    				return 0;
    	}
    
    	/* only allow channels from the ACS whitelist */
    	if (iface->conf->acs_whitelist) {
    		list = iface->conf->acs_whitelist;
    		for (j = 0; list[j] >= 0; j++)
    			if (chan == list[j])
    				break;
    
    		/* channel not found */
    		if (list[j] != chan)
    			return 0;
    	}
    
    	for (j = 0; j < iface->current_mode->num_channels; j++) {
    		c = &iface->current_mode->channels[j];
    		if (c->chan == chan)
    			return (c->flag & HOSTAPD_CHAN_DISABLED) ? 0 : 1;
    	}
    
    	/* channel not found */
    	return 0;
    }
    
    
    struct oper_class_map {
    	enum hostapd_hw_mode mode;
    	u8 op_class;
    	u8 min_chan;
    	u8 max_chan;
    	u8 inc;
    	enum { BW40PLUS, BW40MINUS } bw;
    };
    
    /* this is a duplication of the table in p2p_supplicant.c.
     * all changes here must be propagated there and vice versa */
    static struct oper_class_map op_class[] = {
    #if 0 /* diallow HT40 on 2.4Ghz on purpose */
    	{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
    	{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
    #endif
    	{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
    	{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
    	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
    	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
    
    	/* acs specific - allow (japan) DFS operating classes */
    	{ HOSTAPD_MODE_IEEE80211A, 37, 52, 60, 8, BW40PLUS },
    	{ HOSTAPD_MODE_IEEE80211A, 42, 56, 64, 8, BW40MINUS },
    	{ HOSTAPD_MODE_IEEE80211A, 39, 100, 132, 8, BW40PLUS },
    	{ HOSTAPD_MODE_IEEE80211A, 44, 104, 136, 8, BW40MINUS },
    
    	{ -1, 0, 0, 0, 0, BW40PLUS } /* terminator */
    };
    
    
    
    static int channel_distance(struct hostapd_iface *iface)
    {
    	switch (iface->current_mode->mode) {
    	case HOSTAPD_MODE_IEEE80211A:
    		return 4;
    	case HOSTAPD_MODE_IEEE80211B:
    	case HOSTAPD_MODE_IEEE80211G:
    		return 1;
    	default:
    		break;
    	}
    
    	wpa_printf(MSG_ERROR, "Invalid HW mode for channel distance");
    	return 0;
    }
    
    
    
    /* Returns secondary channel (-1, 1), if possible considering the
     * user preferred secondary channel. If no HT40 operation is possible,
     * returns 0 */
    static int select_secondary_channel(struct hostapd_iface *iface,
    				    int primary_chan, int pref_sec_chan)
    {
    	int i;
    	int up_ok = 0, down_ok = 0;
    
    	for (i = 0; op_class[i].op_class; i++) {
    		struct oper_class_map *o = &op_class[i];
    		u8 ch;
    
    		if (o->mode != iface->current_mode->mode)
    			continue;
    
    		if (primary_chan < o->min_chan || primary_chan > o->max_chan)
    			continue;
    
    		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
    			if (ch == primary_chan) {
    				if (o->bw == BW40PLUS)
    					up_ok = 1;
    				else if (o->bw == BW40MINUS)
    					down_ok = 1;
    					
    				break;
    			}
    		}
    	}
    
    	if (up_ok && !valid_ap_channel(iface,
    				primary_chan + channel_distance(iface)))
    		up_ok = 0;
    	if (down_ok && !valid_ap_channel(iface,
    				primary_chan - channel_distance(iface)))
    		down_ok = 0;
    
    	if ((pref_sec_chan == 1 && up_ok) || (pref_sec_chan == -1 && down_ok))
    		return pref_sec_chan;
    
    	if (up_ok)
    		return 1;
    	else if (down_ok)
    		return -1;
    
    	/* no secondary channel possible */
    	return 0;
    }
    
    /* unreasonable number of APs to find on a channel. */
    #define MAX_AP_COUNT 10000
    
    void set_prim_sec_chan(struct hostapd_iface *iface, int *channel_cnt,
    		       int min_cnt, int default_prim_chan)
    {
    	int j, i;
    	int min_sec_cnt = MAX_AP_COUNT, min_sec_prim_chan = -1,
    		min_sec_chan_dir = -1;
    	int prim_chan, sec_chan_dir, sec_chan;
    
    	if (!iface->conf->secondary_channel)
    		goto set;
    
    	/* if a secondary channel is requested, try to select a channel that
    	 * allows HT40 from the minimal AP ones */
    	for (j = 0; j < iface->current_mode->num_channels; j++) {
    		prim_chan = iface->current_mode->channels[j].chan;
    		if (channel_cnt[j] != min_cnt)
    			continue;
    
    		sec_chan_dir = select_secondary_channel(iface, prim_chan,
    					iface->conf->secondary_channel);
    
    		if (!sec_chan_dir)
    			continue;
    
    		/* see if this secondary channel has minimal APs count */
    		sec_chan = prim_chan + sec_chan_dir * channel_distance(iface);
    		for (i = 0; i < iface->current_mode->num_channels; i++) {
    			if (iface->current_mode->channels[i].chan == sec_chan)
    				break;
    		}
    
    		if (i < iface->current_mode->num_channels &&
    		    channel_cnt[i] < min_sec_cnt) {
    			min_sec_cnt = channel_cnt[i];
    			min_sec_prim_chan = prim_chan;
    			min_sec_chan_dir = sec_chan_dir;
    		}
    	}
    
    	/* found some sec chan with minimal APs */
    	if (min_sec_cnt != MAX_AP_COUNT) {
    		iface->conf->channel = min_sec_prim_chan;
    		iface->conf->secondary_channel = min_sec_chan_dir;
    		return;
    	}
    	
    	wpa_printf(MSG_DEBUG, "Could not auto-select secondary channel");
    
    	
    set:
    	iface->conf->channel = default_prim_chan;
    	iface->conf->secondary_channel = 0;
    	iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
    }
    
    
    static void hostapd_auto_select_scan_cb(struct hostapd_iface *iface)
    {
    	struct wpa_scan_results *scan_res;
    	size_t i, j;
    	int *channel_cnt;
    	int min_cnt, min_idx;
    	struct hostapd_channel_data *chan;
    
    	iface->scan_cb = NULL;
    	
    	/* init all channel counters to 0 */
    	channel_cnt = os_calloc(iface->current_mode->num_channels, sizeof(int));
    	if (channel_cnt == NULL) {
    		hostapd_setup_interface_complete(iface, 1);
    		return;
    	}
    
    	scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
    	if (scan_res == NULL) {
    		hostapd_setup_interface_complete(iface, 1);
    		goto free_chans;
    	}
    
    	/* increment channel counters according to scan results */
    	for (i = 0; i < scan_res->num; i++) {
    		struct wpa_scan_res *bss = scan_res->res[i];
    		for (j = 0; j < iface->current_mode->num_channels; j++) {
    			chan = &iface->current_mode->channels[j];
    
    			if (bss->freq == chan->freq) {
    				channel_cnt[j]++;
    				wpa_printf(MSG_MSGDUMP, "%d BSSes on ch %d",
    					   channel_cnt[j], chan->chan);
    				break;
    			}
    		}
    	}
    
    	min_idx = -1;
    	min_cnt = MAX_AP_COUNT;
    	for (j = 0; j < iface->current_mode->num_channels; j++) {
    		chan = &iface->current_mode->channels[j];
    		if (!valid_ap_channel(iface, chan->chan)) {
    			channel_cnt[j] = MAX_AP_COUNT;
    			continue;
    		}
    
    		if (channel_cnt[j] >= min_cnt)
    			continue;
    
    		min_cnt = channel_cnt[j];
    		min_idx = j;
    	}
    
    	if (min_idx == -1) {
    		wpa_printf(MSG_ERROR,
    			   "Could not select channel automatically");
    		hostapd_setup_interface_complete(iface, 1);
    		goto free_scan;
    	}
    
    	chan = &iface->current_mode->channels[min_idx];
    	wpa_printf(MSG_DEBUG, "Min APs found in channel %d (AP count %d)",
    		   chan->chan, min_cnt);
    
    	/* Select a secondary channel and fine tune the primary one.
    	 * Basically we try to start HT40, without increasing the number
    	 * of APs on the primary channel. */
    	set_prim_sec_chan(iface, channel_cnt, min_cnt, chan->chan);
    	
    	wpa_printf(MSG_DEBUG, "Auto-selected channel: %d secondary: %d",
    		   iface->conf->channel, iface->conf->secondary_channel);
    
    	/* will complete interface setup */
    	hostapd_check_ht_capab(iface, scan_res);
    
    free_scan:
    	wpa_scan_results_free(scan_res);
    
    free_chans:
    	os_free(channel_cnt);
    }
    
    
    static int hostapd_auto_select_channel(struct hostapd_iface *iface)
    {
    
    	struct wpa_driver_scan_params params;
    
    	/* TODO: we can scan only the current HW mode */
    	wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes to select channel");
    	os_memset(&params, 0, sizeof(params));
    	if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
    		wpa_printf(MSG_ERROR, "Failed to request a scan of "
    			   "neighboring BSSes");
    		return -1;
    	}
    
    	iface->scan_cb = hostapd_auto_select_scan_cb;
    	return 0;
    }
    
    
    /**
     * hostapd_select_hw_mode - Select the hardware mode
     * @iface: Pointer to interface data.
     * Returns: 0 on success, < 0 on failure
     *
     * Sets up the hardware mode, channel, rates, and passive scanning
     * based on the configuration.
     */
    int hostapd_select_hw_mode(struct hostapd_iface *iface)
    {
    	int i;
    	struct wpa_channel_info info;
    
    	if (iface->num_hw_features < 1)
    		return -1;
    
    	iface->current_mode = NULL;
    	for (i = 0; i < iface->num_hw_features; i++) {
    		struct hostapd_hw_modes *mode = &iface->hw_features[i];
    		if (mode->mode == iface->conf->hw_mode) {
    			iface->current_mode = mode;
    			break;
    		}
    	}
    
    	if (iface->current_mode == NULL) {
    		wpa_printf(MSG_ERROR, "Hardware does not support configured "
    			   "mode");
    		hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
    			       HOSTAPD_LEVEL_WARNING,
    			       "Hardware does not support configured mode "
    			       "(%d) (hw_mode in hostapd.conf)",
    			       (int) iface->conf->hw_mode);
    		return -2;
    	}
    	
    	/*
    	 * request a scan of neighboring BSSes and select the
    	 * channel automatically
    	 */
    
    	if (iface->conf->channel == 0) {
    		if (hostapd_auto_select_channel(iface)) {
    			wpa_printf(MSG_ERROR, "Channel not configured "
    				   "(hw_mode/channel in hostapd.conf) and "
    				   "automatic channel selection failed");
    
    			return -3;
    		}
    	}
    
    	/* if we failed in querying the channel, assume no concurrent operation */
    	if (iface->conf->ap_channel_sync &&
    	    hostapd_drv_shared_ap_freq(iface->bss[0], &info) == 1) {
    		u8 chan;
    		int hw_mode = ieee80211_freq_to_chan(info.frequency, &chan);
    
    		if (hw_mode == NUM_HOSTAPD_MODES) {
    			wpa_printf(MSG_ERROR, "Shared AP freq bad channel");
    			return -3;
    		}
    
    		/* set current mode */
    		for (i = 0; i < iface->num_hw_features; i++) {
    			struct hostapd_hw_modes *mode = &iface->hw_features[i];
    
    			if (mode->mode == hw_mode) {
    				iface->current_mode = mode;
    				break;
    			}
    		}
    
    		iface->conf->channel = chan;
    		iface->conf->secondary_channel = info.sec_channel_offset;
    		wpa_printf(MSG_DEBUG, "Channel automatically synced to "
    			   "existing AP: %d (secondary: %d hw_mode: %s)",
    			   chan, info.sec_channel_offset,
    			   hostapd_hw_mode_txt(hw_mode));
    	}
    
    	switch (hostapd_check_chans(iface)) {
    	case HOSTAPD_CHAN_VALID:
    		return 0;
    	case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */
    		return 1;
    	case HOSTAPD_CHAN_INVALID:
    	default:
    		hostapd_notify_bad_chans(iface);
    		return -3;
    	}
    
    	return 0;
    }
    
    
    const char * hostapd_hw_mode_txt(int mode)
    {
    	switch (mode) {
    	case HOSTAPD_MODE_IEEE80211A:
    		return "IEEE 802.11a";
    	case HOSTAPD_MODE_IEEE80211B:
    		return "IEEE 802.11b";
    	case HOSTAPD_MODE_IEEE80211G:
    		return "IEEE 802.11g";
    	case HOSTAPD_MODE_IEEE80211AD:
    		return "IEEE 802.11ad";
    	default:
    		return "UNKNOWN";
    	}
    }
    
    
    int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
    {
    	int i;
    
    	if (!hapd->iface->current_mode)
    		return 0;
    
    	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
    		struct hostapd_channel_data *ch =
    			&hapd->iface->current_mode->channels[i];
    		if (ch->chan == chan)
    			return ch->freq;
    	}
    
    	return 0;
    }
    
    
    int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
    {
    	int i;
    
    	if (!hapd->iface->current_mode)
    		return 0;
    
    	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
    		struct hostapd_channel_data *ch =
    			&hapd->iface->current_mode->channels[i];
    		if (ch->freq == freq)
    			return ch->chan;
    	}
    
    	return 0;
    }
    

  • Hi Jim,

    Can you write the hostapd log to a file and share the same?
    To enable hostapd logging to file:

    1. Open "hostap\hostapd\android.config" and add "CONFIG_DEBUG_FILE=y"
    2. Rebuild hostapd "./build_wl18xx.sh hostapd" and copy the binary to the target.
    3. Run hostapd as "hostapd -dd -B /etc/hostapd.conf -P /var/run/hostapd.pid -f ~/hostapd.log"

    After you complete the testing, please share "~/hostapd.log"

    Regards,
    Gigi Joseph.