On Fri, Mar 6, 2026 at 1:44 AM Kerigan Creighton <[email protected]> wrote: > > The WCN3610 has a lot in common with the other wcn36xx > chips, so much of that code was reused. > > The WCN3610 requires specific configuration values for > stable Wi-Fi. Without these values, there's packet loss. > An extra CFG table was made so other chips are not affected. > > ENABLE_DYNAMIC_RA_START_RATE=0 was discovered from the > downstream prima driver. That brought it from 95% to 5% > packet loss. The rest of the CFG values came from my own > observations and experimentation. The current settings > allow for 0% packet loss. > > STA_POWERSAVE resulted in BMPS errors and unstable > functionality, thus it has been disabled for just this > chip. > > Tested on an Anki Vector 1.0 and 2.0 robot with 3 > different APs. Support for other WCN36xx chips has not > been affected. > > Signed-off-by: Kerigan Creighton <[email protected]>
STA_POWERSAVE is disabled, but the interface still enters BMPS mode as controlled by mac80211. If you get the opportunity, It would be useful to air-capture the power‑save entry and exit events when this occurs, so we can verify that the transitions behave as expected. Reviewed-by: Loic Poulain <[email protected]> > --- > Changes in v2: > - Move wcn36xx driver changes to the end of the patch set. > > Changes in v3: > - Describe where the CFG values came from in the wcn36xx > driver patch [Konrad]. > --- > drivers/net/wireless/ath/wcn36xx/main.c | 4 +- > drivers/net/wireless/ath/wcn36xx/smd.c | 61 +++++++++++++++++++++- > drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 + > 3 files changed, 64 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/ath/wcn36xx/main.c > b/drivers/net/wireless/ath/wcn36xx/main.c > index c3f0860873..6c90c13251 100644 > --- a/drivers/net/wireless/ath/wcn36xx/main.c > +++ b/drivers/net/wireless/ath/wcn36xx/main.c > @@ -1438,7 +1438,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) > BIT(NL80211_IFTYPE_MESH_POINT); > > wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz; > - if (wcn->rf_id != RF_IRIS_WCN3620) > + if (wcn->rf_id != RF_IRIS_WCN3620 && wcn->rf_id != RF_IRIS_WCN3610) > wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz; > > if (wcn->rf_id == RF_IRIS_WCN3680) > @@ -1535,6 +1535,8 @@ static int wcn36xx_platform_get_resources(struct > wcn36xx *wcn, > /* External RF module */ > iris_node = of_get_child_by_name(mmio_node, "iris"); > if (iris_node) { > + if (of_device_is_compatible(iris_node, "qcom,wcn3610")) > + wcn->rf_id = RF_IRIS_WCN3610; > if (of_device_is_compatible(iris_node, "qcom,wcn3620")) > wcn->rf_id = RF_IRIS_WCN3620; > if (of_device_is_compatible(iris_node, "qcom,wcn3660") || > diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c > b/drivers/net/wireless/ath/wcn36xx/smd.c > index 813553edcb..8d5a746de7 100644 > --- a/drivers/net/wireless/ath/wcn36xx/smd.c > +++ b/drivers/net/wireless/ath/wcn36xx/smd.c > @@ -83,6 +83,61 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = { > WCN36XX_CFG_VAL(LINK_FAIL_TX_CNT, 1000), > }; > > +static struct wcn36xx_cfg_val wcn3610_cfg_vals[] = { > + WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1), > + WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1), > + WCN36XX_CFG_VAL(LOW_GAIN_OVERRIDE, 0), > + WCN36XX_CFG_VAL(POWER_STATE_PER_CHAIN, 785), > + WCN36XX_CFG_VAL(CAL_PERIOD, 5), > + WCN36XX_CFG_VAL(CAL_CONTROL, 1), > + WCN36XX_CFG_VAL(PROXIMITY, 0), > + WCN36XX_CFG_VAL(NETWORK_DENSITY, 3), > + WCN36XX_CFG_VAL(MAX_MEDIUM_TIME, 6000), > + WCN36XX_CFG_VAL(MAX_MPDUS_IN_AMPDU, 64), > + WCN36XX_CFG_VAL(RTS_THRESHOLD, 2347), > + WCN36XX_CFG_VAL(SHORT_RETRY_LIMIT, 15), > + WCN36XX_CFG_VAL(LONG_RETRY_LIMIT, 15), > + WCN36XX_CFG_VAL(FRAGMENTATION_THRESHOLD, 8000), > + WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ZERO, 5), > + WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ONE, 10), > + WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_TWO, 15), > + WCN36XX_CFG_VAL(FIXED_RATE, 0), > + WCN36XX_CFG_VAL(RETRYRATE_POLICY, 4), > + WCN36XX_CFG_VAL(RETRYRATE_SECONDARY, 131), > + WCN36XX_CFG_VAL(RETRYRATE_TERTIARY, 129), > + WCN36XX_CFG_VAL(FORCE_POLICY_PROTECTION, 5), > + WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_24GHZ, 1), > + WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_5GHZ, 5), > + WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_5GHZ, 5), > + WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_24GHZ, 6), > + WCN36XX_CFG_VAL(MAX_BA_SESSIONS, 40), > + WCN36XX_CFG_VAL(PS_DATA_INACTIVITY_TIMEOUT, 200), > + WCN36XX_CFG_VAL(PS_ENABLE_BCN_FILTER, 1), > + WCN36XX_CFG_VAL(PS_ENABLE_RSSI_MONITOR, 1), > + WCN36XX_CFG_VAL(NUM_BEACON_PER_RSSI_AVERAGE, 20), > + WCN36XX_CFG_VAL(STATS_PERIOD, 10), > + WCN36XX_CFG_VAL(CFP_MAX_DURATION, 30000), > + WCN36XX_CFG_VAL(FRAME_TRANS_ENABLED, 0), > + WCN36XX_CFG_VAL(BA_THRESHOLD_HIGH, 128), > + WCN36XX_CFG_VAL(MAX_BA_BUFFERS, 2560), > + WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0), > + WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1), > + WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1), > + WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0), > + WCN36XX_CFG_VAL(BTC_EXECUTION_MODE, 2), > + WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN, 90000), > + WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN, 60000), > + WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, 30000), > + WCN36XX_CFG_VAL(BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, 120000), > + WCN36XX_CFG_VAL(BTC_FAST_WLAN_CONN_PREF, 1), > + WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 120000), > + WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 30000), > + WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10), > + WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0), > + WCN36XX_CFG_VAL(ENABLE_DYNAMIC_RA_START_RATE, 0), > + WCN36XX_CFG_VAL(LINK_FAIL_TX_CNT, 1000), > +}; > + > static struct wcn36xx_cfg_val wcn3680_cfg_vals[] = { > WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1), > WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1), > @@ -632,6 +687,9 @@ int wcn36xx_smd_start(struct wcn36xx *wcn) > if (wcn->rf_id == RF_IRIS_WCN3680) { > cfg_vals = wcn3680_cfg_vals; > cfg_elements = ARRAY_SIZE(wcn3680_cfg_vals); > + } else if (wcn->rf_id == RF_IRIS_WCN3610) { > + cfg_vals = wcn3610_cfg_vals; > + cfg_elements = ARRAY_SIZE(wcn3610_cfg_vals); > } else { > cfg_vals = wcn36xx_cfg_vals; > cfg_elements = ARRAY_SIZE(wcn36xx_cfg_vals); > @@ -2380,7 +2438,8 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx > *wcn) > mutex_lock(&wcn->hal_mutex); > INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ); > > - wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, STA_POWERSAVE); > + if (wcn->rf_id != RF_IRIS_WCN3610) > + wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, > STA_POWERSAVE); > if (wcn->rf_id == RF_IRIS_WCN3680) { > wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, DOT11AC); > wcn36xx_firmware_set_feat_caps(msg_body.feat_caps, > WLAN_CH144); > diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h > b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h > index 7ee79593cd..cb409d48f7 100644 > --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h > +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h > @@ -96,6 +96,7 @@ enum wcn36xx_ampdu_state { > #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) > > #define RF_UNKNOWN 0x0000 > +#define RF_IRIS_WCN3610 0x3610 > #define RF_IRIS_WCN3620 0x3620 > #define RF_IRIS_WCN3660 0x3660 > #define RF_IRIS_WCN3680 0x3680 > -- > 2.53.0 >

