From 5511e8730fa5c156fe1cd5d6c4355cae552d1868 Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Tue, 28 Jul 2026 15:51:43 +0800 Subject: [PATCH 1/2] feat(wifi): support fixed ampdu rate --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 4 ++-- components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld | 2 +- components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld | 2 +- components/esp_wifi/lib | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 5307f8d8258..bf4b28338b6 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -663,7 +663,7 @@ rcReachRetryLimit = 0x40001d9c; lmacProcessShortRetryFail = 0x40001da0; lmacEndRetryAMPDUFail = 0x40001da4; ppFillAMPDUBar = 0x40001da8; -rcGetRate = 0x40001dac; +//rcGetRate = 0x40001dac; ppReSendBar = 0x40001db0; lmacProcessLongRetryFail = 0x40001db4; lmacRetryTxFrame = 0x40001db8; @@ -715,7 +715,7 @@ hal_crypto_enable = 0x40001e68; wDev_Insert_KeyEntry = 0x40001e70; wDev_remove_KeyEntry = 0x40001e74; rc_enable_trc = 0x40001e78; -rc_set_per_conn_fix_rate = 0x40001e7c; +//rc_set_per_conn_fix_rate = 0x40001e7c; wdev_csi_rx_process = 0x40001e80; wDev_SnifferRxAmpdu = 0x40001e84; hal_mac_tsf_reset = 0x40001e88; diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld index e21837a02bd..5a6d93b00bb 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld @@ -242,7 +242,7 @@ rcUpSched = 0x40000f60; rcReachRetryLimit = 0x40000f64; rcGetDCMMaxRate = 0x40000f68; rcGetSMPDURate = 0x40000f6c; -rcGetRate = 0x40000f70; +//rcGetRate = 0x40000f70; rx11AXRate2AMPDULimit = 0x40000f74; rx11NRate2AMPDULimit = 0x40000f78; rssi_margin = 0x40000f7c; diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld index 0d5d62670fb..ed148275e32 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld @@ -241,7 +241,7 @@ rcUpSched = 0x40000ed4; rcReachRetryLimit = 0x40000ed8; rcGetDCMMaxRate = 0x40000edc; rcGetSMPDURate = 0x40000ee0; -rcGetRate = 0x40000ee4; +//rcGetRate = 0x40000ee4; rx11AXRate2AMPDULimit = 0x40000ee8; rx11NRate2AMPDULimit = 0x40000eec; rssi_margin = 0x40000ef0; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 8f26f1e2e0d..1029fd34ed0 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 8f26f1e2e0d7618061d3903d189227d18fe41bef +Subproject commit 1029fd34ed02a2f8ffbd9b29736f98f20290757c From 52aad1e1f3ab08e0578964932c91fd101fe4454c Mon Sep 17 00:00:00 2001 From: yinqingzhao Date: Mon, 24 Aug 2026 10:31:37 +0800 Subject: [PATCH 2/2] feat(wifi): support disable dfs channels in apsta example --- docs/en/api-guides/wifi.rst | 3 +- docs/zh_CN/api-guides/wifi.rst | 5 +- examples/wifi/softap_sta/README.md | 9 ++ .../wifi/softap_sta/main/Kconfig.projbuild | 24 ++++++ examples/wifi/softap_sta/main/softap_sta.c | 83 +++++++++++++++++++ 5 files changed, 121 insertions(+), 3 deletions(-) diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 51851d07cc0..0b9a00ac9d3 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -1817,6 +1817,7 @@ Wi-Fi Bandwidth Mode - In STA+SoftAP coexistence mode: 1. If the STA connects to an AP on a DFS channel, the SoftAP is allowed to switch to the same DFS channel using CSA (Channel Switch Announcement). 2. When the STA disconnects, the SoftAP will switch back to a non-DFS channel via CSA to remain compliant with regulations. + 3. To completely prevent the SoftAP from operating on DFS channels, call :cpp:func:`esp_wifi_set_country()` to set ``policy`` to ``WIFI_COUNTRY_POLICY_MANUAL`` and restrict ``wifi_5g_channel_mask`` to the non-DFS channels of the current country/region. ``wifi_5g_channel_mask`` takes effect only when policy is ``WIFI_COUNTRY_POLICY_MANUAL``. Note: in this case, if the target AP operates on a DFS channel, the STA cannot connect to that AP. See :component_file:`esp_wifi/regulatory/esp_wifi_regulatory.txt` for the DFS channel range of each country/region. Wi-Fi Country Code +++++++++++++++++++++++++ @@ -1947,7 +1948,7 @@ Wi-Fi Country Code * - policy - Country/region policy. When the configured country/region conflicts with that of the connected AP, this field determines which information to use. Details are explained below. * - wifi_5g_channel_mask - - Bitmask indicating allowed 5 GHz channels for the station/AP. The mapping between channel numbers and bits can be found in :cpp:enum:`wifi_5g_channel_bit_t`. + - Bitmask indicating allowed 5 GHz channels for the station/AP. The mapping between channel numbers and bits can be found in :cpp:enum:`wifi_5g_channel_bit_t`. A mask of 0 means 5 GHz channels are allowed according to local regulatory rules. The configured mask takes effect only when ``policy`` is ``WIFI_COUNTRY_POLICY_MANUAL``. To disable DFS channels, restrict the mask to the non-DFS channels of the current country/region; the STA will then be unable to connect to an AP operating on a DFS channel. A default configuration example:: diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index 9d30a375390..76c07bda0ba 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -1817,8 +1817,9 @@ Wi-Fi 带宽模式 - 在 STA 模式下,{IDF_TARGET_NAME} 可连接至位于 DFS 信道上的 AP,前提是该信道已在扫描中被识别。 - 在 SoftAP 模式下,{IDF_TARGET_NAME} 不允许使用 DFS 信道作为工作信道,以避免违反无线电监管规定。 - 在 STA+SoftAP 共存模式下: - 1. 当 STA 连接到位于 DFS 信道的 AP 时,SoftAP 允许通过 CSA(Channel Switch Announcement)切换至相同的 DFS 信道。 + 1. 当 STA 连接到位于 DFS 信道的 AP 时,SoftAP 允许通过 CSA (Channel Switch Announcement) 切换至相同的 DFS 信道。 2. 当 STA 断开连接后,SoftAP 将通过 CSA 切换回非 DFS 信道,确保符合监管要求。 + 3. 如需要完全禁止 SoftAP 工作在 DFS 信道上,可通过 :cpp:func:`esp_wifi_set_country()` 将 ``policy`` 设为 ``WIFI_COUNTRY_POLICY_MANUAL``,并将 ``wifi_5g_channel_mask`` 限制为当前国家/地区的非 DFS 信道。``wifi_5g_channel_mask`` 仅在 policy 为 ``WIFI_COUNTRY_POLICY_MANUAL`` 时生效。注意:此时若目标 AP 工作在 DFS 信道上,STA 将无法与该 AP 建立连接。各国 DFS 信道范围见 :component_file:`esp_wifi/regulatory/esp_wifi_regulatory.txt`。 Wi-Fi 国家/地区代码 +++++++++++++++++++++++++ @@ -1949,7 +1950,7 @@ Wi-Fi 国家/地区代码 * - policy - 国家/地区策略。当配置的国家/地区与连接 AP 的信息冲突时,此字段决定应使用哪一方的信息。详情见下文说明。 * - wifi_5g_channel_mask - - 表示 station/AP 在 5 GHz 频段中可使用的信道掩码。信道值与位的对应关系详见 :cpp:enum:`wifi_5g_channel_bit_t`。 + - 表示 station/AP 在 5 GHz 频段中可使用的信道掩码。信道值与位的对应关系详见 :cpp:enum:`wifi_5g_channel_bit_t`。掩码为 0 时,5 GHz 信道按当地监管规则允许使用。配置的掩码仅在 ``policy`` 为 ``WIFI_COUNTRY_POLICY_MANUAL`` 时生效。如需禁用 DFS 信道,请将掩码限制为当前国家/地区的非 DFS 信道;此时 STA 也无法连接到工作在 DFS 信道上的 AP。 默认配置示例如下:: diff --git a/examples/wifi/softap_sta/README.md b/examples/wifi/softap_sta/README.md index 8a2a0b450f5..87b0ecc4f07 100644 --- a/examples/wifi/softap_sta/README.md +++ b/examples/wifi/softap_sta/README.md @@ -23,6 +23,15 @@ In the `Example Configuration` menu: * Set `WiFi Remote AP SSID`. * Set `WiFi Remote AP Password`. +* (5 GHz capable chips only) Set the DFS channel configuration under `DFS Channel Configuration`. + * Set `Country code` to select the regulatory domain (e.g. `US` for FCC, `DE` for CE, `01` for world safe mode). + * Enable `Disable DFS channels` to forbid both the STA and the SoftAP from using any DFS channel of the + selected regulatory domain. STA will not be able to connect to an AP that operates on a DFS channel. + The non-DFS channels are looked up from the esp_wifi regulatory table for the configured country, and + the 5 GHz channel bitmask (`wifi_country_t.wifi_5g_channel_mask`) is restricted to them with the + country policy switched to manual. This is useful for certification setups (e.g. FCC, CE) where DFS + channels must be avoided. + Optional: If necessary, modify the other choices to suit your needs. ### Build and Flash diff --git a/examples/wifi/softap_sta/main/Kconfig.projbuild b/examples/wifi/softap_sta/main/Kconfig.projbuild index 32e5377d2e7..df1f411d06f 100644 --- a/examples/wifi/softap_sta/main/Kconfig.projbuild +++ b/examples/wifi/softap_sta/main/Kconfig.projbuild @@ -85,4 +85,28 @@ menu "Example Configuration" endchoice endmenu + + menu "DFS Channel Configuration" + depends on SOC_WIFI_SUPPORT_5G + comment "DFS Channel Configuration (5 GHz capable chips only)" + + config ESP_WIFI_COUNTRY_CODE + string "Country code" + default "01" + help + Country code used to configure the regulatory domain (e.g. "US" for FCC, "DE" for CE, + "01" for world safe mode). The set of DFS channels depends on this regulatory domain. + + config ESP_WIFI_DISABLE_DFS_CHANNELS + bool "Disable DFS channels" + default n + help + If enabled, the device (both STA and SoftAP) will not use any DFS channel of the + configured regulatory domain. As a result, STA cannot connect to an AP that operates + on a DFS channel. The non-DFS channels are derived by looking up the country in the + esp_wifi regulatory table, and the 5 GHz channel bitmask + (wifi_country_t.wifi_5g_channel_mask) is restricted to them with the country policy + switched to manual. This can be useful for certification setups (e.g. FCC, CE) + where DFS channels must be avoided. + endmenu endmenu diff --git a/examples/wifi/softap_sta/main/softap_sta.c b/examples/wifi/softap_sta/main/softap_sta.c index 2497f18f1ab..9c86b6e3069 100644 --- a/examples/wifi/softap_sta/main/softap_sta.c +++ b/examples/wifi/softap_sta/main/softap_sta.c @@ -166,6 +166,86 @@ esp_netif_t *wifi_init_sta(void) return esp_netif_sta; } +#if CONFIG_ESP_WIFI_DISABLE_DFS_CHANNELS +extern const wifi_regdomain_t regdomain_table[]; +extern const wifi_regulatory_t regulatory_data[]; + +static const wifi_regulatory_t *wifi_lookup_regulatory(const char *cc) +{ + for (int i = 0; regdomain_table[i].cn[0] != '#'; i++) { + if (regdomain_table[i].cn[0] == cc[0] && regdomain_table[i].cn[1] == cc[1]) { + return ®ulatory_data[regdomain_table[i].regulatory_type]; + } + } + return NULL; +} + +static uint32_t wifi_get_non_dfs_5g_channel_mask(const wifi_regulatory_t *reg) +{ + uint32_t mask = 0; + + for (int i = 0; i < reg->n_reg_rules; i++) { + const wifi_reg_rule_t *rule = ®->reg_rules[i]; + if (rule->is_dfs || rule->start_channel <= 14) { + continue; + } + for (uint8_t ch = rule->start_channel; ch <= rule->end_channel; ch += 4) { + mask |= CHANNEL_TO_BIT(ch); + } + } + return mask; +} + +// static uint32_t wifi_get_non_dfs_5g_channel_mask_by_type(uint8_t type) +// { +// return wifi_get_non_dfs_5g_channel_mask(®ulatory_data[type]); +// } + +static esp_err_t wifi_configure_country_without_dfs_channels(void) +{ + const char *cc = CONFIG_ESP_WIFI_COUNTRY_CODE; + const wifi_regulatory_t *reg = wifi_lookup_regulatory(cc); + if (!reg) { + ESP_LOGE(TAG_STA, "Unknown country code '%s'", cc); + return ESP_ERR_INVALID_ARG; + } + + wifi_country_t country = {0}; + memcpy(country.cc, cc, 2); + country.policy = WIFI_COUNTRY_POLICY_MANUAL; + uint8_t schan = 0; + uint8_t echan = 0; + for (int i = 0; i < reg->n_reg_rules; i++) { + const wifi_reg_rule_t *rule = ®->reg_rules[i]; + if (rule->start_channel > 14) { + continue; + } + if (schan == 0 || rule->start_channel < schan) { + schan = rule->start_channel; + } + if (rule->end_channel > echan) { + echan = rule->end_channel; + } + } + if (schan != 0) { + country.schan = schan; + country.nchan = echan - schan + 1; + } + + /* A zero mask does not mean "no 5 GHz channel allowed", it means "fall back to + the local regulatory rules", which would leave the DFS channels usable. Some + domains (AM for instance) mark every 5 GHz rule as DFS, so there the only way + to stay off DFS is to stay off 5 GHz altogether. */ + country.wifi_5g_channel_mask = wifi_get_non_dfs_5g_channel_mask(reg); + if (country.wifi_5g_channel_mask == 0) { + ESP_ERROR_CHECK(esp_wifi_set_band_mode(WIFI_BAND_MODE_2G_ONLY)); + ESP_LOGW(TAG_STA, "'%s' has no non-DFS 5 GHz channel, restricting to 2.4 GHz", cc); + } + ESP_ERROR_CHECK(esp_wifi_set_country(&country)); + return ESP_OK; +} +#endif /* CONFIG_ESP_WIFI_DISABLE_DFS_CHANNELS */ + void softap_set_dns_addr(esp_netif_t *esp_netif_ap,esp_netif_t *esp_netif_sta) { esp_netif_dns_info_t dns; @@ -222,6 +302,9 @@ void app_main(void) /* Start WiFi */ ESP_ERROR_CHECK(esp_wifi_start() ); +#if CONFIG_ESP_WIFI_DISABLE_DFS_CHANNELS + ESP_ERROR_CHECK(wifi_configure_country_without_dfs_channels()); +#endif /* * Wait until either the connection is established (WIFI_CONNECTED_BIT) or * connection failed for the maximum number of re-tries (WIFI_FAIL_BIT).