ath10k: add handler for HTT_T2H_MSG_TYPE_SEC_IND event
authorWen Gong <wgong@codeaurora.org>
Fri, 26 Apr 2019 06:41:08 +0000 (09:41 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 29 Apr 2019 14:37:23 +0000 (17:37 +0300)
Add the handler for HTT_T2H_MSG_TYPE_SEC_IND event from firmware, which stores
PN for replay check implemented in the following patch.

Tested on QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00007-QCARMSWP-1.

Signed-off-by: Wen Gong <wgong@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath10k/htt_rx.c

index f22840bbc389603f626a525933f1e287254a13f4..cc2875d73bf0d641f3b44504987e2f3171f7889f 100644 (file)
@@ -3267,6 +3267,51 @@ out:
        rcu_read_unlock();
 }
 
+static int ath10k_htt_rx_pn_len(enum htt_security_types sec_type)
+{
+       switch (sec_type) {
+       case HTT_SECURITY_TKIP:
+       case HTT_SECURITY_TKIP_NOMIC:
+       case HTT_SECURITY_AES_CCMP:
+               return 48;
+       default:
+               return 0;
+       }
+}
+
+static void ath10k_htt_rx_sec_ind_handler(struct ath10k *ar,
+                                         struct htt_security_indication *ev)
+{
+       enum htt_txrx_sec_cast_type sec_index;
+       enum htt_security_types sec_type;
+       struct ath10k_peer *peer;
+
+       spin_lock_bh(&ar->data_lock);
+
+       peer = ath10k_peer_find_by_id(ar, __le16_to_cpu(ev->peer_id));
+       if (!peer) {
+               ath10k_warn(ar, "failed to find peer id %d for security indication",
+                           __le16_to_cpu(ev->peer_id));
+               goto out;
+       }
+
+       sec_type = MS(ev->flags, HTT_SECURITY_TYPE);
+
+       if (ev->flags & HTT_SECURITY_IS_UNICAST)
+               sec_index = HTT_TXRX_SEC_UCAST;
+       else
+               sec_index = HTT_TXRX_SEC_MCAST;
+
+       peer->rx_pn[sec_index].sec_type = sec_type;
+       peer->rx_pn[sec_index].pn_len = ath10k_htt_rx_pn_len(sec_type);
+
+       memset(peer->tids_last_pn_valid, 0, sizeof(peer->tids_last_pn_valid));
+       memset(peer->tids_last_pn, 0, sizeof(peer->tids_last_pn));
+
+out:
+       spin_unlock_bh(&ar->data_lock);
+}
+
 bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 {
        struct ath10k_htt *htt = &ar->htt;
@@ -3360,6 +3405,7 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
                struct ath10k *ar = htt->ar;
                struct htt_security_indication *ev = &resp->security_indication;
 
+               ath10k_htt_rx_sec_ind_handler(ar, ev);
                ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "sec ind peer_id %d unicast %d type %d\n",
                          __le16_to_cpu(ev->peer_id),