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]>
---
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


Reply via email to