Wi-Fi Configuration for SiWx91x#
This document decribes recommended configuration options for Wi-Fi on SiWx91x. The Zephyr Network Configuration Guide provides a great overview of the different configuration options and their effect on the networking stack.
Power Save#
Wi-Fi power save is configured using the
net_mgmt()
API NET_REQUEST_WIFI_PS passing a struct wifi_ps_params where the enabled member is one of
WIFI_PS_ENABLED or WIFI_PS_DISABLED.
Maximizing Wi-Fi Throughput#
Buffer Size Configuration#
The CONFIG_NET_BUF_RX_COUNT
and CONFIG_NET_BUF_TX_COUNT
Kconfig options can be used to configure the number of buffers available to the network stack, which
affects the TCP window size. Increasing the number of buffers generally improves throughput.
Power Save#
Disable Wi-Fi power save in high-throughput applications.
Socket Service Thread Priority#
By default, the socket service thread has a cooperative priority of -1. Under heavy receive load,
this can starve lower-layer Wi-Fi and network processing, reducing throughput.
The thread priority can be configured using
CONFIG_NET_SOCKETS_SERVICE_THREAD_PRIO,
and should be set to a positive number (preemptive priority) for maximum throughput.
Compiler Options#
Since SiWx91x does not have a data cache, it benefits from the Kconfig option
CONFIG_SILABS_SIWX91X_SLOW_FLASH_DATA=y,
which sets the -mslow-flash-data compiler option. When using this option, Thread Local Storage
must be disabled using CONFIG_THREAD_LOCAL_STORAGE=n
due to a compiler limitation in Zephyr SDK 1.0.1. See
zephyrproject-rtos/gcc#65 for details.
Code Relocation#
For maximum throughput, certain functions and read-only data should be relocated to RAM. This can be
achieved using the zephyr_code_relocate() function in the CMakeLists.txt file of the project and
setting CONFIG_CODE_DATA_RELOCATION_SRAM=y
in prj.conf.
The following snippet can be used as a reference, and is based on profiling with the zperf sample
application. Different applications with different usage patterns may benefit from relocating a
different set of functions.
set(WISECONNECT_COMPONENTS_DIR "${ZEPHYR_HAL_SILABS_MODULE_DIR}/wiseconnect/components")
set(WC_DEVICE "${WISECONNECT_COMPONENTS_DIR}/device/silabs/si91x/wireless")
set(WC_AHB "${WC_DEVICE}/ahb_interface/src")
zephyr_code_relocate(LIBRARY subsys__net__ip LOCATION RAM_RODATA NOKEEP)
zephyr_code_relocate(LIBRARY drivers__wifi LOCATION RAM_RODATA NOKEEP)
zephyr_code_relocate(LIBRARY lib__net_buf LOCATION RAM_RODATA NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/l2/ethernet/ethernet.c LOCATION RAM_TEXT NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/utils.c FILTER ".calc_chksum" LOCATION RAM)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/utils.c FILTER ".net_calc_chksum" LOCATION RAM)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/utils.c FILTER ".net_calc_chksum_ipv4" LOCATION RAM)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/connection.c FILTER ".net_conn_input" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/ipv4.c FILTER ".net_ipv4_finalize" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/ipv4.c FILTER ".net_ipv4_input" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_send" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_sendto" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".context_sendto" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_create_ipv4_new" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_get_option" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".bind_default" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_recv" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_context.c FILTER ".net_context_packet_received" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_core.c FILTER ".net_try_send_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_core.c FILTER ".net_recv_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_core.c FILTER ".net_process_rx_packet" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_if.c FILTER ".net_if_ipv4_select_src_iface" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_if.c FILTER ".net_if_ipv4_is_addr_bcast_raw" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_if.c FILTER ".net_if_try_send_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_if.c FILTER ".net_process_tx_packet" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_clone" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_cursor_operate" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_cursor_init" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_get_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_set_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_skip" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_read" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_write" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_copy" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".pkt_cursor_update" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".pkt_cursor_jump" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_alloc_buffer_raw" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_append_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_pull" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_trim_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_remove_tail" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_update_length" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_get_frag" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_frag_unref" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_ref" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_unref" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_is_contiguous" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_get_contiguous_len" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_alloc_with_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".pkt_alloc_with_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".pkt_alloc" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_alloc_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_alloc_buffer_with_reserve" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_available_payload_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".pkt_alloc_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_tx_init" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_rx_alloc_with_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_pkt.c FILTER ".net_pkt_remaining_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".net_tc_try_submit_to_tx_queue" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".tc_tx_handler" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".net_tx_priority2tc" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".net_tc_submit_to_rx_queue" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".tc_rx_handler" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/net_tc.c FILTER ".net_rx_priority2tc" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".net_tcp_input" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".th_get" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".net_tcp_queue" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_send_queued_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_send_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_out_ext" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_out" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_pkt_append" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_send" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_in" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_recv" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_setup_retransmission" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".net_tcp_finalize" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".net_tcp_tx_sem_get" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/tcp.c FILTER ".tcp_data_len" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/ip/udp.c FILTER ".net_udp_input" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/sockets/sockets.c FILTER ".z_impl_zsock_recvfrom" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/sockets/sockets_inet.c FILTER ".zsock_received_cb" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/sockets/sockets_inet.c FILTER ".zsock_recv_dgram" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/sockets/sockets_inet.c FILTER ".zsock_wait_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/sockets/sockets_service.c FILTER ".socket_service_thread" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/lib/net_buf/buf.c FILTER ".net_buf_alloc_len" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/lib/net_buf/buf.c FILTER ".net_buf_alloc_fixed" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/lib/net_buf/buf.c FILTER ".net_buf_unref" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/condvar.c FILTER ".z_impl_k_condvar_signal" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/mutex.c FILTER ".z_impl_k_mutex_lock" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/mutex.c FILTER ".z_impl_k_mutex_unlock" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".z_reschedule" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".z_reschedule_irqlock" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".z_ready_thread" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".z_pend_curr" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".z_unpend_thread" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".ready_thread" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".unready_thread" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/kernel/sched.c FILTER ".add_to_waitq_locked" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/drivers/wifi/siwx91x/siwx91x_wifi.c FILTER ".siwx91x_send" LOCATION RAM)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/drivers/wifi/siwx91x/siwx91x_wifi.c FILTER ".sl_si91x_host_process_data_frame" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_DEVICE}/memory/mem_pool_buffer_quota.c FILTER ".sli_si91x_host_allocate_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_DEVICE}/memory/mem_pool_buffer_quota.c FILTER ".sli_si91x_host_free_buffer" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_DEVICE}/memory/mem_pool_buffer_quota.c FILTER ".sl_si91x_host_get_buffer_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_DEVICE}/src/sl_rsi_utility.c FILTER ".sli_wifi_host_get_buffer_data" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WISECONNECT_COMPONENTS_DIR}/sli_wifi/src/sli_wifi_utility.c FILTER ".sli_wifi_append_to_buffer_queue" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WISECONNECT_COMPONENTS_DIR}/sli_wifi/src/sli_wifi_utility.c FILTER ".sli_wifi_set_event" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WISECONNECT_COMPONENTS_DIR}/sli_wifi_command_engine/src/sli_wifi_command_engine.c FILTER ".sli_wifi_command_engine" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WISECONNECT_COMPONENTS_DIR}/sli_si91x_wifi_event_handler/src/sli_si91x_wifi_event_handler.c FILTER ".sli_wifi_command_engine_set_event" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_AHB}/sl_si91x_bus.c FILTER ".sli_si91x_bus_write_frame" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_AHB}/rsi_hal_mcu_m4_rom.c FILTER ".sli_si91x_raise_pkt_pending_interrupt_to_ta" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_AHB}/rsi_hal_mcu_m4_rom.c FILTER ".sli_si91x_bus_read_interrupt_status" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${WC_AHB}/sli_siwx917_soc.c FILTER ".unmask_ta_interrupt" LOCATION RAM NOKEEP)
#Enable the below two zperf functions when using the zperf application
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/zperf/zperf_udp_receiver.c FILTER ".udp_svc_handler" LOCATION RAM NOKEEP)
zephyr_code_relocate(FILES ${ZEPHYR_BASE}/subsys/net/lib/zperf/zperf_udp_uploader.c FILTER ".udp_upload" LOCATION RAM NOKEEP)Throughput Measurements#
Combining the configurations described above, the following throughput was measured using zperf on
a SiWx91x-RB4338A development board using IPv4 in a shielded room:
Wi-Fi STA Throughput (Mbps) | TCP TX | TCP RX | UDP TX | UDP RX |
|---|---|---|---|---|
Executing from Flash | 10 | 14 | 19 | 28 |
With Code Relocation | 33 | 37 | 59 | 55 |
Access Point: Asus AX3000
Remote: Linux PC
CLI commands used:
# TCP TX
zperf tcp upload <ipv4 address> 5001 30 1460
# TCP RX
zperf tcp download 5001
# UDP TX
zperf udp upload <ipv4 address> 5001 30 1472 70000000
# UDP RX
zperf udp download 5001