ACS - automatic channel selection

收錄在 Ameba 的一百篇

--

前記: Android upstream - hostapd ACS offload issue


原本 Android 的 SoftAP mode , 可以選 "5.0 GHz Band" 或 "2.4 GHz" 兩個選項.
分別對應到 hostapd 的 hw_mode=a 和  hw_mode=g. 若同時設定 channel=0 時,
hostapd 會做 ACS computing

https://wireless.wiki.kernel.org/en/users/documentation/acs

Hostapd 會用到 NL80211_CMD_GET_SURVEY

在 net/wireless/nl80211.c

{
                .cmd = NL80211_CMD_GET_SURVEY,
                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
                .dumpit = nl80211_dump_survey,
 },


這邊會一路呼叫到 cfg80211 ops - dump_survey
( mac80211 ops - get_survey )

而在 Android 10 的 soft AP mode, config.xml 中, 有新增一個 config_wifi_dual_band_support,
當這個設定起來時, SoftAP mode 選項會是 "5.0GHz Band preferred" , 取代原本的 "5.0 GHz Band", 而這個選項對應到 hostapd , 會把 hw_mode 設定成 any
是一個特別的設定 : hw_mode = any, channel = 0 表示是走 ACS offload
也就是 ACS computing 計算並不是在 hostapd, 而是在 wifi driver/FW 上.
但 Android 若真的這樣假定, 變成我們會需要做 ACS offload...

我們先看原本 hostapd ACS 計算的機制
 ==

1. hostapd 計算

(1) 如果 wifi driver 沒有做 cfg80211 ops - dump_survey, hostapd 會出現:
      No Survey data received

(2) dump_survey 最主要是回答 struct survey_info

/**
 * struct survey_info - channel survey response
 *
 * @channel: the channel this survey record reports, may be %NULL for a single
 * record to report global statistics
 * @filled: bitflag of flags from &enum survey_info_flags
 * @noise: channel noise in dBm. This and all following fields are
 * optional
 * @time: amount of time in ms the radio was turn on (on the channel)
 * @time_busy: amount of time the primary channel was sensed busy
 * @time_ext_busy: amount of time the extension channel was sensed busy
 * @time_rx: amount of time the radio spent receiving data
 * @time_tx: amount of time the radio spent transmitting data
 * @time_scan: amount of time the radio spent for scanning
 * @time_bss_rx: amount of time the radio spent receiving data on a local BSS
 *
 * Used by dump_survey() to report back per-channel survey information.
 *
 * This structure can later be expanded with things like
 * channel duty cycle etc.
 */
struct survey_info {
 struct ieee80211_channel *channel;
 u64 time;
 u64 time_busy;
 u64 time_ext_busy;
 u64 time_rx;
 u64 time_tx;
 u64 time_scan;
 u64 time_bss_rx;
 u32 filled;
 s8 noise;
};
/**
 * struct ieee80211_channel - channel definition
 *
 * This structure describes a single channel for use
 * with cfg80211.
 *
 * @center_freq: center frequency in MHz
 * @hw_value: hardware-specific value for the channel
 * @flags: channel flags from &enum ieee80211_channel_flags.
 * @orig_flags: channel flags at registration time, used by regulatory
 * code to support devices with additional restrictions
 * @band: band this channel belongs to.
 * @max_antenna_gain: maximum antenna gain in dBi
 * @max_power: maximum transmission power (in dBm)
 * @max_reg_power: maximum regulatory transmission power (in dBm)
 * @beacon_found: helper to regulatory code to indicate when a beacon
 * has been found on this channel. Use regulatory_hint_found_beacon()
 * to enable this, this is useful only on 5 GHz band.
 * @orig_mag: internal use
 * @orig_mpwr: internal use
 * @dfs_state: current state of this channel. Only relevant if radar is required
 * on this channel.
 * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
 * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
 */
struct ieee80211_channel {
 enum nl80211_band band;
 u32 center_freq;
 u16 hw_value;
 u32 flags;
 int max_antenna_gain;
 int max_power;
 int max_reg_power;
 bool beacon_found;
 u32 orig_flags;
 int orig_mag, orig_mpwr;
 enum nl80211_dfs_state dfs_state;
 unsigned long dfs_state_entered;
 unsigned int dfs_cac_ms;
};
ieee80211_channel : Linux 有提供一個 ieee80211_get_channel(wiphy, freq)

(3) noise
     如果只帶 channel, 沒有其他資訊, 當然無法計算哪個 channel 訊號比較乾淨
     hostapd 第一個顯示的錯誤是: ACS: Survey is missing noise floor

     我們需要填 noise floor
     Noise floor (SURVEY_INFO_NOISE_DBM) put into NL80211_SURVEY_INFO_NOISE

   info->filled = SURVEY_INFO_NOISE_DBM;
   info->noise = -113;

   這樣就會看到: 
   nl80211: Freq Survey dump event (freq=5825 MHz noise=-113 channel_time=0 busy_time=0 tx_time=0 rx_time=0 filled=0001
   
(4) channel time
      接下來少 channel time,

       我們看 hostapd 檢查的 code

  • Channel time (SURVEY_INFO_TIME) put into NL80211_SURVEY_INFO_TIME
  • Time of channel unavailability which is one of:
    • RX time (SURVEY_INFO_TIME_RX) put into NL80211_SURVEY_INFO_TIME_RX
    • Busy time (SURVEY_INFO_TIME_BUSY) put into NL80211_SURVEY_INFO_TIME_BUSY
   info->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY;
   info->noise = -113;
   info->time = 161;
   info->time_busy = 0;

這樣就能看到 
   ACS: Ideal channel is 6 (2437 MHz) with total interference factor of 2.00951e-23
   ACS-COMPLETED freq=2437 channel=6

--

接下來我們看原問題 hw_mode=any 的 case, 
會出現:

Hardware does not support configured mode
wlan1: IEEE 802.11 Hardware does not support configured mode (4) (hw_mode in hostapd.conf)
Could not select hw_mode and channel. (-2)


我們看 hostapd 的 code, driver 必須回報: 
case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
drv->capa.flags |= WPA_DRIVER_FLAGS_ACS_OFFLOAD;

break;

        if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
      drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;


這變成 目前這 wifi offload feature 只支援 QCA 的 wifi..

後續



留言

熱門文章