Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
authorKalle Valo <kvalo@kernel.org>
Tue, 30 Aug 2022 14:23:40 +0000 (17:23 +0300)
committerKalle Valo <kvalo@kernel.org>
Tue, 30 Aug 2022 14:23:40 +0000 (17:23 +0300)
ath.git patches for v6.1. Only fixes this time.

drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath9k/htc_hst.c

index 276954b70d6305e554699ebfa197e3c77c16c6d1..d1ac64026cb3102813389454395d7af18dc2a5e4 100644 (file)
@@ -98,6 +98,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = true,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA988X_HW_2_0_VERSION,
@@ -136,6 +137,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = true,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9887_HW_1_0_VERSION,
@@ -175,6 +177,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA6174_HW_3_2_VERSION,
@@ -209,6 +212,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .supports_peer_stats_info = true,
                .dynamic_sar_support = true,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA6174_HW_2_1_VERSION,
@@ -247,6 +251,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA6174_HW_2_1_VERSION,
@@ -285,6 +290,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA6174_HW_3_0_VERSION,
@@ -323,6 +329,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA6174_HW_3_2_VERSION,
@@ -365,6 +372,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .supports_peer_stats_info = true,
                .dynamic_sar_support = true,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -409,6 +417,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9984_HW_1_0_DEV_VERSION,
@@ -460,6 +469,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9888_HW_2_0_DEV_VERSION,
@@ -508,6 +518,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9377_HW_1_0_DEV_VERSION,
@@ -546,6 +557,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -586,6 +598,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -617,6 +630,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .credit_size_workaround = true,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = QCA4019_HW_1_0_DEV_VERSION,
@@ -662,6 +676,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = false,
                .hw_restart_disconnect = false,
+               .use_fw_tx_credits = true,
        },
        {
                .id = WCN3990_HW_1_0_DEV_VERSION,
@@ -693,6 +708,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
                .tx_stats_over_pktlog = false,
                .dynamic_sar_support = true,
                .hw_restart_disconnect = true,
+               .use_fw_tx_credits = false,
        },
 };
 
index fab398046a3f231c38b20e60d771f3548ddaba57..6d1784f74bea497e7ac1c34a70504e6d4b023960 100644 (file)
@@ -947,13 +947,18 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                return -ECOMM;
        }
 
-       htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
+       if (ar->hw_params.use_fw_tx_credits)
+               htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
+       else
+               htc->total_transmit_credits = 1;
+
        htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
 
        ath10k_dbg(ar, ATH10K_DBG_HTC,
-                  "Target ready! transmit resources: %d size:%d\n",
+                  "Target ready! transmit resources: %d size:%d actual credits:%d\n",
                   htc->total_transmit_credits,
-                  htc->target_credit_size);
+                  htc->target_credit_size,
+                  msg->ready.credit_count);
 
        if ((htc->total_transmit_credits == 0) ||
            (htc->target_credit_size == 0)) {
index 93acf0dd580a6f0f5e076fb6d6106887c39791ef..1b99f3a39a1134bcca75fe729c0fe5f1acdbf3ac 100644 (file)
@@ -635,6 +635,8 @@ struct ath10k_hw_params {
        bool dynamic_sar_support;
 
        bool hw_restart_disconnect;
+
+       bool use_fw_tx_credits;
 };
 
 struct htt_resp;
index 9dd3b8fba4b0e5d078d5b20637c0a3ce54451e93..23381a9db6aebba6fc50f4cd4a49c6515923853f 100644 (file)
@@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
        return 0;
 }
 
+static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer)
+{
+       int peer_id, i;
+
+       lockdep_assert_held(&ar->conf_mutex);
+
+       for_each_set_bit(peer_id, peer->peer_ids,
+                        ATH10K_MAX_NUM_PEER_IDS) {
+               ar->peer_map[peer_id] = NULL;
+       }
+
+       /* Double check that peer is properly un-referenced from
+        * the peer_map
+        */
+       for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
+               if (ar->peer_map[i] == peer) {
+                       ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
+                                   peer->addr, peer, i);
+                       ar->peer_map[i] = NULL;
+               }
+       }
+
+       list_del(&peer->list);
+       kfree(peer);
+       ar->num_peers--;
+}
+
 static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
 {
        struct ath10k_peer *peer, *tmp;
-       int peer_id;
-       int i;
 
        lockdep_assert_held(&ar->conf_mutex);
 
@@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
                ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
                            peer->addr, vdev_id);
 
-               for_each_set_bit(peer_id, peer->peer_ids,
-                                ATH10K_MAX_NUM_PEER_IDS) {
-                       ar->peer_map[peer_id] = NULL;
-               }
-
-               /* Double check that peer is properly un-referenced from
-                * the peer_map
-                */
-               for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
-                       if (ar->peer_map[i] == peer) {
-                               ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
-                                           peer->addr, peer, i);
-                               ar->peer_map[i] = NULL;
-                       }
-               }
-
-               list_del(&peer->list);
-               kfree(peer);
-               ar->num_peers--;
+               ath10k_peer_map_cleanup(ar, peer);
        }
        spin_unlock_bh(&ar->data_lock);
 }
@@ -7621,10 +7628,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                                /* Clean up the peer object as well since we
                                 * must have failed to do this above.
                                 */
-                               list_del(&peer->list);
-                               ar->peer_map[i] = NULL;
-                               kfree(peer);
-                               ar->num_peers--;
+                               ath10k_peer_map_cleanup(ar, peer);
                        }
                }
                spin_unlock_bh(&ar->data_lock);
index 994ec48b2f669588dbfe46c69611aad47aaebfbe..ca05b07a45e67c714e58ac5f9c708acfb1b8f1c8 100644 (file)
@@ -364,33 +364,27 @@ ret:
 }
 
 static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
-                                     struct sk_buff *skb)
+                                     struct sk_buff *skb, u32 len)
 {
        uint32_t *pattern = (uint32_t *)skb->data;
 
-       switch (*pattern) {
-       case 0x33221199:
-               {
+       if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) {
                struct htc_panic_bad_vaddr *htc_panic;
                htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
                dev_err(htc_handle->dev, "ath: firmware panic! "
                        "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
                        htc_panic->exccause, htc_panic->pc,
                        htc_panic->badvaddr);
-               break;
-               }
-       case 0x33221299:
-               {
+               return;
+       }
+       if (*pattern == 0x33221299) {
                struct htc_panic_bad_epid *htc_panic;
                htc_panic = (struct htc_panic_bad_epid *) skb->data;
                dev_err(htc_handle->dev, "ath: firmware panic! "
                        "bad epid: 0x%08x\n", htc_panic->epid);
-               break;
-               }
-       default:
-               dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
-               break;
+               return;
        }
+       dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
 }
 
 /*
@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
        if (!htc_handle || !skb)
                return;
 
+       /* A valid message requires len >= 8.
+        *
+        *   sizeof(struct htc_frame_hdr) == 8
+        *   sizeof(struct htc_ready_msg) == 8
+        *   sizeof(struct htc_panic_bad_vaddr) == 16
+        *   sizeof(struct htc_panic_bad_epid) == 8
+        */
+       if (unlikely(len < sizeof(struct htc_frame_hdr)))
+               goto invalid;
        htc_hdr = (struct htc_frame_hdr *) skb->data;
        epid = htc_hdr->endpoint_id;
 
        if (epid == 0x99) {
-               ath9k_htc_fw_panic_report(htc_handle, skb);
+               ath9k_htc_fw_panic_report(htc_handle, skb, len);
                kfree_skb(skb);
                return;
        }
 
        if (epid < 0 || epid >= ENDPOINT_MAX) {
+invalid:
                if (pipe_id != USB_REG_IN_PIPE)
                        dev_kfree_skb_any(skb);
                else
@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
 
                /* Handle trailer */
                if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
-                       if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
+                       if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) {
                                /* Move past the Watchdog pattern */
                                htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
+                               len -= 4;
+                       }
                }
 
                /* Get the message ID */
+               if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16)))
+                       goto invalid;
                msg_id = (__be16 *) ((void *) htc_hdr +
                                     sizeof(struct htc_frame_hdr));
 
                /* Now process HTC messages */
                switch (be16_to_cpu(*msg_id)) {
                case HTC_MSG_READY_ID:
+                       if (unlikely(len < sizeof(struct htc_ready_msg)))
+                               goto invalid;
                        htc_process_target_rdy(htc_handle, htc_hdr);
                        break;
                case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
+                       if (unlikely(len < sizeof(struct htc_frame_hdr) +
+                                    sizeof(struct htc_conn_svc_rspmsg)))
+                               goto invalid;
                        htc_process_conn_rsp(htc_handle, htc_hdr);
                        break;
                default: