From patchwork Thu Sep 19 10:52:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= X-Patchwork-Id: 1164531 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=silabs.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=silabs.onmicrosoft.com header.i=@silabs.onmicrosoft.com header.b="WUYtIv79"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46Ytxl3dT5z9sPT for ; Thu, 19 Sep 2019 20:53:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389684AbfISKxj (ORCPT ); Thu, 19 Sep 2019 06:53:39 -0400 Received: from mail-eopbgr730082.outbound.protection.outlook.com ([40.107.73.82]:1632 "EHLO NAM05-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2389579AbfISKxE (ORCPT ); Thu, 19 Sep 2019 06:53:04 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=j16J/LUz2Ak4GKAtYvSjza4S/8DPCen8+As2uH0YnqR2GQE6C2FBwK70Hv/fVSAFWZol3MiQIiEqcwxmrOPo5cd//qqG+6ObJHZcFdRu9AIheCdq19fXftrKDJh2R61NmqpBW3tRjMYiX9FTyROx7A/Jtvt73ytP2Mj3zYGXu0qi/wVzdKepjeyiKrY9eN3A3WcgN0r/FnSnqZw8wxQ0HmtY+k0Jx2DFpOf98mIyBDSypoRnhmXCi7C9VvmMTaHomCGmbzwBLvvRjf+9FNiJMqJAb3630s68IxdxpD6ds6aerbapLN+fqiMbqXMDWG2FSW8K7B/q4cds1nNq1HSSwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Iq0bAM9TxdbYc7Ea6czWlaAO/RkEBr8XvTZ9NGU1O+k=; b=AcU2uaK5ELhFvhpRsu8WSLd2wRSTaabQ2LfQtAQxKyv6k3FqLtTpwGMKrl43rYYh1vT4gy9ko9hvGQ4p39/nzjjnmJYZzFztMEohysBmk51oJ/Heawb+s+LYJRh+Bbyu7GLu6XYmw7H5EsAVTDN/CYUAWGWG9KNpi4csJjS/LIcrtIFsNvccy6PBsvKVY9Crk/ixIJ85GvL9q4+AJxTr/v/a1IfEoWSjAri71gIGS2r1y2U8a9A4UF/7NZt8ImGDiC8Y3sPJ0m2aQxv2YSF05Vk1CSAbEIUsCnFDqvUbWWVen+lgJSQafRzIP+qdlxB1CtUp/yuwGyRwHsAYIerQCQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=silabs.com; dmarc=pass action=none header.from=silabs.com; dkim=pass header.d=silabs.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=silabs.onmicrosoft.com; s=selector2-silabs-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Iq0bAM9TxdbYc7Ea6czWlaAO/RkEBr8XvTZ9NGU1O+k=; b=WUYtIv79teZ8ZpVXJl6SHckA83esLWOApbqyJGohplFyRP1G+C4Fup1qdPsSPsjr2ltebQWSLMunnJylm7v2zkDrDufrW4WGg8ZXYsbCLsNxvol8UTXdAJjbfI6erTTe4SiHIwwzcNc+8/hD3QSsirkCihqNbO3Fvi48uxBOdiY= Received: from MN2PR11MB4063.namprd11.prod.outlook.com (20.179.149.217) by MN2PR11MB4415.namprd11.prod.outlook.com (52.135.39.95) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2263.17; Thu, 19 Sep 2019 10:52:45 +0000 Received: from MN2PR11MB4063.namprd11.prod.outlook.com ([fe80::45dc:e073:4446:4bf8]) by MN2PR11MB4063.namprd11.prod.outlook.com ([fe80::45dc:e073:4446:4bf8%3]) with mapi id 15.20.2263.023; Thu, 19 Sep 2019 10:52:45 +0000 From: Jerome Pouiller To: "devel@driverdev.osuosl.org" , "linux-wireless@vger.kernel.org" CC: "netdev@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Greg Kroah-Hartman , Kalle Valo , "David S . Miller" , David Le Goff , Jerome Pouiller Subject: [PATCH 19/20] staging: wfx: implement 802.11 key handling Thread-Topic: [PATCH 19/20] staging: wfx: implement 802.11 key handling Thread-Index: AQHVbthdFRXeeKeLB0ms1h9a98U3aA== Date: Thu, 19 Sep 2019 10:52:44 +0000 Message-ID: <20190919105153.15285-20-Jerome.Pouiller@silabs.com> References: <20190919105153.15285-1-Jerome.Pouiller@silabs.com> In-Reply-To: <20190919105153.15285-1-Jerome.Pouiller@silabs.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Jerome.Pouiller@silabs.com; x-originating-ip: [37.71.187.125] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2d77b910-b970-4e35-89c3-08d73cef8122 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600167)(711020)(4605104)(1401327)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:MN2PR11MB4415; x-ms-traffictypediagnostic: MN2PR11MB4415: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2657; x-forefront-prvs: 016572D96D x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(396003)(366004)(39850400004)(376002)(136003)(189003)(199004)(14454004)(71190400001)(2906002)(81156014)(81166006)(478600001)(316002)(2501003)(64756008)(76176011)(66476007)(256004)(86362001)(66446008)(99286004)(25786009)(8676002)(66556008)(66946007)(11346002)(6512007)(110136005)(66574012)(5660300002)(54906003)(30864003)(6436002)(71200400001)(14444005)(76116006)(3846002)(6506007)(91956017)(1076003)(6116002)(486006)(305945005)(36756003)(2616005)(446003)(4326008)(7736002)(8936002)(66066001)(186003)(107886003)(26005)(476003)(6486002)(102836004); DIR:OUT; SFP:1101; SCL:1; SRVR:MN2PR11MB4415; H:MN2PR11MB4063.namprd11.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: silabs.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: qUBmXdBD+e3jZITWRN3c20/2M1VLzj6kQ1Nq/dh3Jg9jjd4Q8iITOOAuShMQbWtXhj82/oi+IPi74c4rP7ZhObDUv/dQVMYFsbLzc9xx8O/JzbrO+PXN2COPq4uG7bXW9D3F62ULpdE35AZiVwqiUSAVrr9hBLFdoM+liiKPf5/MW6+wFLkIOjf0Bf3O0Dlf0qt3EJ/DbNt+XdRhXRZXb0Li+3Sn93G8g/ARkrmAqtfn6Qxax8BmmPjwP4DK/KEobb8J7QCek9FJGluyJ7WSrSAFE7hGi+L3F6gJsdAc/CSIetExX8OpI21AYmR2fb9Q7y8aBHZ/lU5eqkVlzC+zuNe8krlA4SN2OAvyGDEXe4KLazGizqXYDS8mC8Vbe2ozuEEJVo9hIAKGayQ9mhOfW600TUzf3+I3emonJ7GE7hg= Content-ID: <5AFB49AAC013034F95A827B3770F279D@namprd11.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2d77b910-b970-4e35-89c3-08d73cef8122 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Sep 2019 10:52:44.2587 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 54dbd822-5231-4b20-944d-6f4abcd541fb X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: W4x7DNqNZ55CaQFAAUrCCrfC6EemKvtdB2nkWCGWd4Nnwyx+TrFzsAHt+Sa+HTkpEy+m6K+9asvddAuLF/+VEg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR11MB4415 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/staging/wfx/Makefile | 1 + drivers/staging/wfx/key.c | 272 +++++++++++++++++++++++++++++++++++ drivers/staging/wfx/key.h | 22 +++ drivers/staging/wfx/main.c | 2 + drivers/staging/wfx/sta.c | 4 + drivers/staging/wfx/wfx.h | 19 +++ 6 files changed, 320 insertions(+) create mode 100644 drivers/staging/wfx/key.c create mode 100644 drivers/staging/wfx/key.h diff --git a/drivers/staging/wfx/Makefile b/drivers/staging/wfx/Makefile index 2b8a5fa86fac..0d9c1ed092f6 100644 --- a/drivers/staging/wfx/Makefile +++ b/drivers/staging/wfx/Makefile @@ -14,6 +14,7 @@ wfx-y := \ data_rx.o \ scan.o \ sta.o \ + key.o \ main.o \ sta.o \ debug.o diff --git a/drivers/staging/wfx/key.c b/drivers/staging/wfx/key.c new file mode 100644 index 000000000000..696424f244cb --- /dev/null +++ b/drivers/staging/wfx/key.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Key management related functions. + * + * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include + +#include "key.h" +#include "wfx.h" +#include "hif_tx_mib.h" + +static int wfx_alloc_key(struct wfx_dev *wdev) +{ + int idx; + + idx = ffs(~wdev->key_map) - 1; + if (idx < 0 || idx >= MAX_KEY_ENTRIES) + return -1; + + wdev->key_map |= BIT(idx); + wdev->keys[idx].entry_index = idx; + return idx; +} + +static void wfx_free_key(struct wfx_dev *wdev, int idx) +{ + BUG_ON(!(wdev->key_map & BIT(idx))); + memset(&wdev->keys[idx], 0, sizeof(wdev->keys[idx])); + wdev->key_map &= ~BIT(idx); +} + +static uint8_t fill_wep_pair(struct hif_wep_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + WARN_ON(key->keylen > sizeof(msg->key_data)); + msg->key_length = key->keylen; + memcpy(msg->key_data, key->key, key->keylen); + ether_addr_copy(msg->peer_address, peer_addr); + return HIF_KEY_TYPE_WEP_PAIRWISE; +} + +static uint8_t fill_wep_group(struct hif_wep_group_key *msg, + struct ieee80211_key_conf *key) +{ + WARN_ON(key->keylen > sizeof(msg->key_data)); + msg->key_id = key->keyidx; + msg->key_length = key->keylen; + memcpy(msg->key_data, key->key, key->keylen); + return HIF_KEY_TYPE_WEP_DEFAULT; +} + +static uint8_t fill_tkip_pair(struct hif_tkip_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + uint8_t *keybuf = key->key; + + WARN_ON(key->keylen != sizeof(msg->tkip_key_data) + + sizeof(msg->tx_mic_key) + + sizeof(msg->rx_mic_key)); + memcpy(msg->tkip_key_data, keybuf, sizeof(msg->tkip_key_data)); + keybuf += sizeof(msg->tkip_key_data); + memcpy(msg->tx_mic_key, keybuf, sizeof(msg->tx_mic_key)); + keybuf += sizeof(msg->tx_mic_key); + memcpy(msg->rx_mic_key, keybuf, sizeof(msg->rx_mic_key)); + ether_addr_copy(msg->peer_address, peer_addr); + return HIF_KEY_TYPE_TKIP_PAIRWISE; +} + +static uint8_t fill_tkip_group(struct hif_tkip_group_key *msg, + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq, + enum nl80211_iftype iftype) +{ + uint8_t *keybuf = key->key; + + WARN_ON(key->keylen != sizeof(msg->tkip_key_data) + + 2 * sizeof(msg->rx_mic_key)); + msg->key_id = key->keyidx; + memcpy(msg->rx_sequence_counter, &seq->tkip.iv16, sizeof(seq->tkip.iv16)); + memcpy(msg->rx_sequence_counter + sizeof(uint16_t), &seq->tkip.iv32, sizeof(seq->tkip.iv32)); + memcpy(msg->tkip_key_data, keybuf, sizeof(msg->tkip_key_data)); + keybuf += sizeof(msg->tkip_key_data); + if (iftype == NL80211_IFTYPE_AP) + // Use Tx MIC Key + memcpy(msg->rx_mic_key, keybuf + 0, sizeof(msg->rx_mic_key)); + else + // Use Rx MIC Key + memcpy(msg->rx_mic_key, keybuf + 8, sizeof(msg->rx_mic_key)); + return HIF_KEY_TYPE_TKIP_GROUP; +} + +static uint8_t fill_ccmp_pair(struct hif_aes_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + WARN_ON(key->keylen != sizeof(msg->aes_key_data)); + ether_addr_copy(msg->peer_address, peer_addr); + memcpy(msg->aes_key_data, key->key, key->keylen); + return HIF_KEY_TYPE_AES_PAIRWISE; +} + +static uint8_t fill_ccmp_group(struct hif_aes_group_key *msg, + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) +{ + WARN_ON(key->keylen != sizeof(msg->aes_key_data)); + memcpy(msg->aes_key_data, key->key, key->keylen); + memcpy(msg->rx_sequence_counter, seq->ccmp.pn, sizeof(seq->ccmp.pn)); + memreverse(msg->rx_sequence_counter, sizeof(seq->ccmp.pn)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_AES_GROUP; +} + +static uint8_t fill_sms4_pair(struct hif_wapi_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + uint8_t *keybuf = key->key; + + WARN_ON(key->keylen != sizeof(msg->wapi_key_data) + + sizeof(msg->mic_key_data)); + ether_addr_copy(msg->peer_address, peer_addr); + memcpy(msg->wapi_key_data, keybuf, sizeof(msg->wapi_key_data)); + keybuf += sizeof(msg->wapi_key_data); + memcpy(msg->mic_key_data, keybuf, sizeof(msg->mic_key_data)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_WAPI_PAIRWISE; +} + +static uint8_t fill_sms4_group(struct hif_wapi_group_key *msg, + struct ieee80211_key_conf *key) +{ + uint8_t *keybuf = key->key; + + WARN_ON(key->keylen != sizeof(msg->wapi_key_data) + + sizeof(msg->mic_key_data)); + memcpy(msg->wapi_key_data, keybuf, sizeof(msg->wapi_key_data)); + keybuf += sizeof(msg->wapi_key_data); + memcpy(msg->mic_key_data, keybuf, sizeof(msg->mic_key_data)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_WAPI_GROUP; +} + +static uint8_t fill_aes_cmac_group(struct hif_igtk_group_key *msg, + struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) +{ + WARN_ON(key->keylen != sizeof(msg->igtk_key_data)); + memcpy(msg->igtk_key_data, key->key, key->keylen); + memcpy(msg->ipn, seq->aes_cmac.pn, sizeof(seq->aes_cmac.pn)); + memreverse(msg->ipn, sizeof(seq->aes_cmac.pn)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_IGTK_GROUP; +} + +static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int ret; + struct hif_req_add_key *k; + struct ieee80211_key_seq seq; + struct wfx_dev *wdev = wvif->wdev; + int idx = wfx_alloc_key(wvif->wdev); + bool pairwise = key->flags & IEEE80211_KEY_FLAG_PAIRWISE; + + WARN_ON(key->flags & IEEE80211_KEY_FLAG_PAIRWISE && !sta); + ieee80211_get_key_rx_seq(key, 0, &seq); + if (idx < 0) + return -EINVAL; + k = &wdev->keys[idx]; + k->int_id = wvif->id; + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) { + if (pairwise) + k->type = fill_wep_pair(&k->key.wep_pairwise_key, key, sta->addr); + else + k->type = fill_wep_group(&k->key.wep_group_key, key); + } else if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + if (pairwise) + k->type = fill_tkip_pair(&k->key.tkip_pairwise_key, key, sta->addr); + else + k->type = fill_tkip_group(&k->key.tkip_group_key, key, &seq, wvif->vif->type); + } else if (key->cipher == WLAN_CIPHER_SUITE_CCMP) { + if (pairwise) + k->type = fill_ccmp_pair(&k->key.aes_pairwise_key, key, sta->addr); + else + k->type = fill_ccmp_group(&k->key.aes_group_key, key, &seq); + } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { + if (pairwise) + k->type = fill_sms4_pair(&k->key.wapi_pairwise_key, key, sta->addr); + else + k->type = fill_sms4_group(&k->key.wapi_group_key, key); + } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + k->type = fill_aes_cmac_group(&k->key.igtk_group_key, key, &seq); + } else { + dev_warn(wdev->dev, "unsupported key type %d\n", key->cipher); + wfx_free_key(wdev, idx); + return -EOPNOTSUPP; + } + ret = hif_add_key(wdev, k); + if (ret) { +#if KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE && \ + KERNEL_VERSION(4, 9, 63) > LINUX_VERSION_CODE && \ + KERNEL_VERSION(4, 4, 99) > LINUX_VERSION_CODE + if (ret == HIF_INVALID_PARAMETER) { + // Use a patched kernel in order to solve this error + dev_warn(wdev->dev, "chip prevents re-installation of same key\n"); + dev_warn(wdev->dev, "your kernel is not patched to protect against KRACK attack\n"); + } +#endif + wfx_free_key(wdev, idx); + return -EOPNOTSUPP; + } +#if (KERNEL_VERSION(3, 19, 0) > LINUX_VERSION_CODE) + key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; +#else + key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE | + IEEE80211_KEY_FLAG_RESERVE_TAILROOM; +#endif + key->hw_key_idx = idx; + return 0; +} + +static int wfx_remove_key(struct wfx_vif *wvif, struct ieee80211_key_conf *key) +{ + WARN(key->hw_key_idx >= MAX_KEY_ENTRIES, "corrupted hw_key_idx"); + wfx_free_key(wvif->wdev, key->hw_key_idx); + return hif_remove_key(wvif->wdev, key->hw_key_idx); +} + +int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int ret = -EOPNOTSUPP; + struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv; + + mutex_lock(&wvif->wdev->conf_mutex); + if (cmd == SET_KEY) + ret = wfx_add_key(wvif, sta, key); + if (cmd == DISABLE_KEY) + ret = wfx_remove_key(wvif, key); + mutex_unlock(&wvif->wdev->conf_mutex); + return ret; +} + +int wfx_upload_keys(struct wfx_vif *wvif) +{ + int i; + struct hif_req_add_key *key; + struct wfx_dev *wdev = wvif->wdev; + + for (i = 0; i < ARRAY_SIZE(wdev->keys); i++) { + if (wdev->key_map & BIT(i)) { + key = &wdev->keys[i]; + if (key->int_id == wvif->id) + hif_add_key(wdev, key); + } + } + return 0; +} + +void wfx_wep_key_work(struct work_struct *work) +{ + struct wfx_vif *wvif = container_of(work, struct wfx_vif, wep_key_work); + + wfx_tx_flush(wvif->wdev); + hif_wep_default_key_id(wvif, wvif->wep_default_key_id); + wfx_pending_requeue(wvif->wdev, wvif->wep_pending_skb); + wvif->wep_pending_skb = NULL; + wfx_tx_unlock(wvif->wdev); +} diff --git a/drivers/staging/wfx/key.h b/drivers/staging/wfx/key.h new file mode 100644 index 000000000000..9436ccdf4d3b --- /dev/null +++ b/drivers/staging/wfx/key.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Implementation of mac80211 API. + * + * Copyright (c) 2017-2019, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_KEY_H +#define WFX_KEY_H + +#include + +struct wfx_dev; +struct wfx_vif; + +int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +int wfx_upload_keys(struct wfx_vif *wvif); +void wfx_wep_key_work(struct work_struct *work); + +#endif /* WFX_STA_H */ diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index 06220bac5b75..e7bba24aae0b 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -27,6 +27,7 @@ #include "bus.h" #include "bh.h" #include "sta.h" +#include "key.h" #include "debug.h" #include "data_tx.h" #include "secure_link.h" @@ -56,6 +57,7 @@ static const struct ieee80211_ops wfx_ops = { .remove_interface = wfx_remove_interface, .tx = wfx_tx, .hw_scan = wfx_hw_scan, + .set_key = wfx_set_key, }; bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor) diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index c9a35a5307dd..ccf45bdb7e42 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -10,6 +10,7 @@ #include "sta.h" #include "wfx.h" +#include "key.h" #include "scan.h" #include "hif_tx_mib.h" @@ -172,6 +173,9 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0); #endif + wvif->wep_default_key_id = -1; + INIT_WORK(&wvif->wep_key_work, wfx_wep_key_work); + sema_init(&wvif->scan.lock, 1); INIT_WORK(&wvif->scan.work, wfx_scan_work); INIT_DELAYED_WORK(&wvif->scan.timeout, wfx_scan_timeout); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index a6b430ee7cdf..ba5e1a32d869 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -69,6 +69,9 @@ struct wfx_dev { int tx_burst_idx; atomic_t tx_lock; + u32 key_map; + struct hif_req_add_key keys[MAX_KEY_ENTRIES]; + struct hif_rx_stats rx_stats; struct mutex rx_stats_lock; @@ -94,6 +97,9 @@ struct wfx_vif { struct work_struct mcast_start_work; struct work_struct mcast_stop_work; + s8 wep_default_key_id; + struct sk_buff *wep_pending_skb; + struct work_struct wep_key_work; struct tx_policy_cache tx_policy_cache; struct work_struct tx_policy_upload_work; @@ -141,6 +147,19 @@ static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev, struct wfx_vif return NULL; } +static inline void memreverse(uint8_t *src, uint8_t length) +{ + uint8_t *lo = src; + uint8_t *hi = src + length - 1; + uint8_t swap; + + while (lo < hi) { + swap = *lo; + *lo++ = *hi; + *hi-- = swap; + } +} + static inline int memzcmp(void *src, unsigned int size) { uint8_t *buf = src;