]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
qtnfmac: handle MIC failure event from firmware
authorSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Wed, 13 Nov 2019 11:06:57 +0000 (11:06 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 14 Nov 2019 15:28:52 +0000 (17:28 +0200)
Report MIC failure from firmware to cfg80211 subsystem
using dedicated callback cfg80211_michael_mic_failure.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/quantenna/qtnfmac/event.c
drivers/net/wireless/quantenna/qtnfmac/qlink.h

index 7846383c88283fef3719dbda9200b4b635342740..51af93bdf06e88ee34c2364cbea886f159959036 100644 (file)
@@ -618,6 +618,42 @@ qtnf_event_handle_external_auth(struct qtnf_vif *vif,
        return ret;
 }
 
+static int
+qtnf_event_handle_mic_failure(struct qtnf_vif *vif,
+                             const struct qlink_event_mic_failure *mic_ev,
+                             u16 len)
+{
+       struct wiphy *wiphy = priv_to_wiphy(vif->mac);
+       u8 pairwise;
+
+       if (len < sizeof(*mic_ev)) {
+               pr_err("VIF%u.%u: payload is too short (%u < %zu)\n",
+                      vif->mac->macid, vif->vifid, len,
+                      sizeof(struct qlink_event_mic_failure));
+               return -EINVAL;
+       }
+
+       if (!wiphy->registered || !vif->netdev)
+               return 0;
+
+       if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
+               pr_err("VIF%u.%u: MIC_FAILURE event when not in STA mode\n",
+                      vif->mac->macid, vif->vifid);
+               return -EPROTO;
+       }
+
+       pairwise = mic_ev->pairwise ?
+               NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP;
+
+       pr_info("%s: MIC error: src=%pM key_index=%u pairwise=%u\n",
+               vif->netdev->name, mic_ev->src, mic_ev->key_index, pairwise);
+
+       cfg80211_michael_mic_failure(vif->netdev, mic_ev->src, pairwise,
+                                    mic_ev->key_index, NULL, GFP_KERNEL);
+
+       return 0;
+}
+
 static int qtnf_event_parse(struct qtnf_wmac *mac,
                            const struct sk_buff *event_skb)
 {
@@ -680,6 +716,10 @@ static int qtnf_event_parse(struct qtnf_wmac *mac,
                ret = qtnf_event_handle_external_auth(vif, (const void *)event,
                                                      event_len);
                break;
+       case QLINK_EVENT_MIC_FAILURE:
+               ret = qtnf_event_handle_mic_failure(vif, (const void *)event,
+                                                   event_len);
+               break;
        default:
                pr_warn("unknown event type: %x\n", event_id);
                break;
index 8a3c6344fa8ed5ab20124bb0d1667771e7457387..ac1ebe4bb5805adb847c20940947f6f226f5d7ac 100644 (file)
@@ -958,6 +958,7 @@ enum qlink_event_type {
        QLINK_EVENT_FREQ_CHANGE         = 0x0028,
        QLINK_EVENT_RADAR               = 0x0029,
        QLINK_EVENT_EXTERNAL_AUTH       = 0x0030,
+       QLINK_EVENT_MIC_FAILURE         = 0x0031,
 };
 
 /**
@@ -1151,6 +1152,20 @@ struct qlink_event_external_auth {
        u8 action;
 } __packed;
 
+/**
+ * struct qlink_event_mic_failure - data for QLINK_EVENT_MIC_FAILURE event
+ *
+ * @src: source MAC address of the frame
+ * @key_index: index of the key being reported
+ * @pairwise: whether the key is pairwise or group
+ */
+struct qlink_event_mic_failure {
+       struct qlink_event ehdr;
+       u8 src[ETH_ALEN];
+       u8 key_index;
+       u8 pairwise;
+} __packed;
+
 /* QLINK TLVs (Type-Length Values) definitions
  */