]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ath11k: Configure hash based reo destination ring selection
authorSriram R <srirrama@codeaurora.org>
Tue, 17 Mar 2020 11:37:02 +0000 (17:07 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 18 Mar 2020 11:53:37 +0000 (13:53 +0200)
Current implementation of pdev based reo destination ring
selection is replaced by hash based ring selection so as to
ensure all the available rings are utilized for better performance.

The 4 reo destination rings are selected by the HW based on the
hash value computed from the received packet based on the 5 tuple
{ip src/ip dst/src port/dst port/protocol}. Out of the 32 hash values
used by the hw, the driver assigns 8 values per reo destination ring
to each of the 4 reo destination rings.

Signed-off-by: Sriram R <srirrama@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath11k/dp.c
drivers/net/wireless/ath/ath11k/dp.h
drivers/net/wireless/ath/ath11k/hal.h
drivers/net/wireless/ath/ath11k/hal_rx.c
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/wmi.c
drivers/net/wireless/ath/ath11k/wmi.h

index a1371ab773ab938bf7c5ba540058d343a283ae31..b8875209f8266dd03e72e249e2189f2f74ae8590 100644 (file)
@@ -218,6 +218,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
        struct ath11k_dp *dp = &ab->dp;
        struct hal_srng *srng;
        int i, ret;
+       u32 ring_hash_map;
 
        ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
                                   HAL_SW2WBM_RELEASE, 0, 0,
@@ -305,7 +306,21 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
                goto err;
        }
 
-       ath11k_hal_reo_hw_setup(ab);
+       /* When hash based routing of rx packet is enabled, 32 entries to map
+        * the hash values to the ring will be configured. Each hash entry uses
+        * three bits to map to a particular ring. The ring mapping will be
+        * 0:TCL, 1:SW1, 2:SW2, 3:SW3, 4:SW4, 5:Release, 6:FW and 7:Not used.
+        */
+       ring_hash_map = HAL_HASH_ROUTING_RING_SW1 << 0 |
+                       HAL_HASH_ROUTING_RING_SW2 << 3 |
+                       HAL_HASH_ROUTING_RING_SW3 << 6 |
+                       HAL_HASH_ROUTING_RING_SW4 << 9 |
+                       HAL_HASH_ROUTING_RING_SW1 << 12 |
+                       HAL_HASH_ROUTING_RING_SW2 << 15 |
+                       HAL_HASH_ROUTING_RING_SW3 << 18 |
+                       HAL_HASH_ROUTING_RING_SW4 << 21;
+
+       ath11k_hal_reo_hw_setup(ab, ring_hash_map);
 
        return 0;
 
index f504077086da512c66be5b39fc223339fe1ba69f..3edfe92279f86725972a880b87adc69df4f27466 100644 (file)
@@ -160,7 +160,7 @@ struct ath11k_pdev_dp {
 #define DP_AVG_MPDUS_PER_TID_MAX 128
 #define DP_AVG_MSDUS_PER_MPDU 4
 
-#define DP_RX_HASH_ENABLE      0 /* Disable hash based Rx steering */
+#define DP_RX_HASH_ENABLE      1 /* Enable hash based Rx steering */
 
 #define DP_BA_WIN_SZ_MAX       256
 
index 36df37449e30756567d6471360901a8e0371cf71..7722822a0456e287b62d3ccac17fa10f165b8fcc 100644 (file)
@@ -96,6 +96,8 @@ struct ath11k_base;
 
 /* REO2SW(x) R0 ring configuration address */
 #define HAL_REO1_GEN_ENABLE                    0x00000000
+#define HAL_REO1_DEST_RING_CTRL_IX_0           0x00000004
+#define HAL_REO1_DEST_RING_CTRL_IX_1           0x00000008
 #define HAL_REO1_DEST_RING_CTRL_IX_2           0x0000000c
 #define HAL_REO1_DEST_RING_CTRL_IX_3           0x00000010
 #define HAL_REO1_RING_BASE_LSB                 0x0000029c
@@ -725,6 +727,14 @@ enum hal_ce_desc {
        HAL_CE_DESC_DST_STATUS,
 };
 
+#define HAL_HASH_ROUTING_RING_TCL 0
+#define HAL_HASH_ROUTING_RING_SW1 1
+#define HAL_HASH_ROUTING_RING_SW2 2
+#define HAL_HASH_ROUTING_RING_SW3 3
+#define HAL_HASH_ROUTING_RING_SW4 4
+#define HAL_HASH_ROUTING_RING_REL 5
+#define HAL_HASH_ROUTING_RING_FW  6
+
 struct hal_reo_status_header {
        u16 cmd_num;
        enum hal_reo_cmd_status cmd_status;
@@ -858,7 +868,7 @@ void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
                                u32 start_seq, enum hal_pn_type type);
 void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
                                  struct hal_srng *srng);
-void ath11k_hal_reo_hw_setup(struct ath11k_base *ab);
+void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map);
 void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
                                     struct hal_wbm_idle_scatter_list *sbuf,
                                     u32 nsbufs, u32 tot_link_desc,
index 3a666565cd1e8db594fed3c0fb5ba9e6f346e48b..f277c9434a25527708aea9d8daa8281bc75d53bd 100644 (file)
@@ -799,7 +799,7 @@ void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
        }
 }
 
-void ath11k_hal_reo_hw_setup(struct ath11k_base *ab)
+void ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map)
 {
        u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
        u32 val;
@@ -821,6 +821,19 @@ void ath11k_hal_reo_hw_setup(struct ath11k_base *ab)
                           HAL_DEFAULT_REO_TIMEOUT_USEC);
        ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3,
                           HAL_DEFAULT_REO_TIMEOUT_USEC);
+
+       ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0,
+                          FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
+                                     ring_hash_map));
+       ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1,
+                          FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
+                                     ring_hash_map));
+       ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2,
+                          FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
+                                     ring_hash_map));
+       ath11k_ahb_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3,
+                          FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP,
+                                     ring_hash_map));
 }
 
 static enum hal_rx_mon_status
index 4e38913172ec940284918e0ef541406006e46597..6a0d0f654623d538586866b037026449d2a921f3 100644 (file)
@@ -3974,6 +3974,9 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
                goto err;
        }
 
+       /* Configure the hash seed for hash based reo dest ring selection */
+       ath11k_wmi_pdev_lro_cfg(ar, ar->pdev->pdev_id);
+
        mutex_unlock(&ar->conf_mutex);
 
        rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx],
@@ -5791,6 +5794,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
                ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
                ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);
                ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU);
+               ieee80211_hw_set(ar->hw, USES_RSS);
        }
 
        ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
index 2e8ce886bfe46b486c40b30bac3aa0b85d2f3a28..e7ce36966d6a74ec0bd2646f84ea573344e5e4e0 100644 (file)
@@ -2995,6 +2995,41 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
        return ret;
 }
 
+int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar,
+                           int pdev_id)
+{
+       struct ath11k_wmi_pdev_lro_config_cmd *cmd;
+       struct sk_buff *skb;
+       int ret;
+
+       skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct ath11k_wmi_pdev_lro_config_cmd *)skb->data;
+       cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_LRO_INFO_CMD) |
+                         FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
+
+       get_random_bytes(cmd->th_4, sizeof(uint32_t) * ATH11K_IPV4_TH_SEED_SIZE);
+       get_random_bytes(cmd->th_6, sizeof(uint32_t) * ATH11K_IPV6_TH_SEED_SIZE);
+
+       cmd->pdev_id = pdev_id;
+
+       ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_LRO_CONFIG_CMDID);
+       if (ret) {
+               ath11k_warn(ar->ab,
+                           "failed to send lro cfg req wmi cmd\n");
+               goto err;
+       }
+
+       ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+                  "WMI lro cfg cmd pdev_id 0x%x\n", pdev_id);
+       return 0;
+err:
+       dev_kfree_skb(skb);
+       return ret;
+}
+
 int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab)
 {
        unsigned long time_left;
index 31e14ef0456e07f1484732cf79c5aaa3b9f78baa..510f9c6bc1d78a56140602c5f6f95d0036535793 100644 (file)
@@ -4645,6 +4645,18 @@ struct wmi_bss_color_change_enable_params_cmd {
        u32 enable;
 } __packed;
 
+#define ATH11K_IPV4_TH_SEED_SIZE 5
+#define ATH11K_IPV6_TH_SEED_SIZE 11
+
+struct ath11k_wmi_pdev_lro_config_cmd {
+       u32 tlv_header;
+       u32 lro_enable;
+       u32 res;
+       u32 th_4[ATH11K_IPV4_TH_SEED_SIZE];
+       u32 th_6[ATH11K_IPV6_TH_SEED_SIZE];
+       u32 pdev_id;
+} __packed;
+
 struct target_resource_config {
        u32 num_vdevs;
        u32 num_peers;
@@ -4844,5 +4856,5 @@ int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
                                                 bool enable);
 int ath11k_wmi_send_bss_color_change_enable_cmd(struct ath11k *ar, u32 vdev_id,
                                                bool enable);
-
+int ath11k_wmi_pdev_lro_cfg(struct ath11k *ar, int pdev_id);
 #endif