From 239ce8a79778b62eb50a2084ac43cb0b410ee15b Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Wed, 13 Nov 2019 11:06:57 +0000 Subject: qtnfmac: handle MIC failure event from firmware Report MIC failure from firmware to cfg80211 subsystem using dedicated callback cfg80211_michael_mic_failure. Signed-off-by: Sergey Matyukevich Signed-off-by: Kalle Valo --- drivers/net/wireless/quantenna/qtnfmac/event.c | 40 ++++++++++++++++++++++++++ drivers/net/wireless/quantenna/qtnfmac/qlink.h | 15 ++++++++++ 2 files changed, 55 insertions(+) (limited to 'drivers/net/wireless/quantenna') diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 7846383c8828..51af93bdf06e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -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; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index 8a3c6344fa8e..ac1ebe4bb580 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -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 */ -- cgit v1.2.3