From patchwork Thu Aug 27 10:57:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Copeland X-Patchwork-Id: 7083131 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A40599F1C2 for ; Thu, 27 Aug 2015 10:57:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 89D3A20982 for ; Thu, 27 Aug 2015 10:57:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6A22C20981 for ; Thu, 27 Aug 2015 10:57:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753491AbbH0K5f (ORCPT ); Thu, 27 Aug 2015 06:57:35 -0400 Received: from mail-ig0-f173.google.com ([209.85.213.173]:34370 "EHLO mail-ig0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753459AbbH0K5c (ORCPT ); Thu, 27 Aug 2015 06:57:32 -0400 Received: by igui7 with SMTP id i7so58320633igu.1 for ; Thu, 27 Aug 2015 03:57:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dZiHZbZNlc53ms95iskNN3LHFQT7UzWqKpRxNGNFma0=; b=kMQHt1CvZSF8gLek9jNsrt+W+pV5MZAkV5EghOajePVeVBaBbhRxDR3wtbunNGI2xJ 9rHJ5WTfjrESt4KeuCuukF+YimlAxdArMxDeepYvwtcwfSaHy1s8RPRZrK6DCgjIU/bb Isfi3MX7NRGpNiBmcfncuX0ao3G3WZwSlnsmNuLjdu/Iraj9VAuxdWGBEhVUOMCd4Mbh BDIvVN82gnCWdju0YFcBAdKQsqSvnpBdhsuYMEgTnWQWA3zqQjKOb8Fyj99MeKIWCzbu oHvrEASTGjDMO4wn5bf9Qy34x3oXKtU655i+DRGAOa8uiXn7DnxfkMaDFH+64x48FaAd wQJw== X-Gm-Message-State: ALoCoQlfCgvV2NoI61ZmD3QUSqucyndfynMKpkPS56jhBcV3vJ+VsL0gapMOj8185/xmbTCmaHVc X-Received: by 10.50.93.99 with SMTP id ct3mr16472006igb.83.1440673051511; Thu, 27 Aug 2015 03:57:31 -0700 (PDT) Received: from hash ([2001:470:1d:6db:230:48ff:fe9d:9c89]) by smtp.gmail.com with ESMTPSA id 93sm1453589iog.4.2015.08.27.03.57.30 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Aug 2015 03:57:30 -0700 (PDT) Received: from bob by hash with local (Exim 4.84) (envelope-from ) id 1ZUurn-0003Zt-Ec; Thu, 27 Aug 2015 06:57:11 -0400 From: Bob Copeland To: linux-wireless@vger.kernel.org Cc: ath10k@lists.infradead.org, Bob Copeland Subject: [PATCH 3/3] ath10k: implement mesh support Date: Thu, 27 Aug 2015 06:57:04 -0400 Message-Id: <1440673024-13696-4-git-send-email-me@bobcopeland.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1440673024-13696-1-git-send-email-me@bobcopeland.com> References: <1440673024-13696-1-git-send-email-me@bobcopeland.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for mesh to ath10k. We simply use an AP virtual interface in the firmware in order to enable beaconing without TSF adoption, and use the raw (802.11) transmit mode. Due to firmware limitations, the firmware must operate in raw (non-native 802.11) mode. As this is configured at firmware init time, a new "rawmode" modparam is added, and mesh interfaces are available only if rawmode=true. The firmware must advertise support for rawmode (tested successfully with firmware 10.2.4.70-2). When loaded with rawmode=1, ath10k can operate an open mesh STA via something like the following: ip link set wlan0 down iw dev wlan0 set type mp ip link set wlan0 up iw dev wlan0 set freq 5745 80 5775 iw dev wlan0 mesh join mesh-vht Signed-off-by: Bob Copeland --- Since ath10k ml posting: * added raw mode feature flag check * usage and firmware notes in commit log drivers/net/wireless/ath/ath10k/core.c | 12 ++++++++++++ drivers/net/wireless/ath/ath10k/mac.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b87b986..9dafe25 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -34,16 +34,19 @@ unsigned int ath10k_debug_mask; static unsigned int ath10k_cryptmode_param; static bool uart_print; static bool skip_otp; +static bool rawmode; module_param_named(debug_mask, ath10k_debug_mask, uint, 0644); module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644); module_param(uart_print, bool, 0644); module_param(skip_otp, bool, 0644); +module_param(rawmode, bool, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); MODULE_PARM_DESC(uart_print, "Uart target debugging"); MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); +MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); static const struct ath10k_hw_params ath10k_hw_params_list[] = { { @@ -1117,6 +1120,15 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT; ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT; + if (rawmode) { + if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT, + ar->fw_features)) { + ath10k_err(ar, "rawmode = 1 requires support from firmware"); + return -EINVAL; + } + set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags); + } + if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 7dfe37f..b0f1594 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4176,6 +4176,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_ADHOC: arvif->vdev_type = WMI_VDEV_TYPE_IBSS; break; + case NL80211_IFTYPE_MESH_POINT: + if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { + ret = -EINVAL; + ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n"); + goto err; + } + arvif->vdev_type = WMI_VDEV_TYPE_AP; + break; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -4216,6 +4224,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap. */ if (vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_AP) { arvif->beacon_buf = dma_zalloc_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, @@ -4555,6 +4564,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, if (ret) ath10k_warn(ar, "failed to update beacon template: %d\n", ret); + + if (ieee80211_vif_is_mesh(vif)) { + /* mesh doesn't use SSID but firmware needs it */ + strncpy(arvif->u.ap.ssid, "mesh", + sizeof(arvif->u.ap.ssid)); + arvif->u.ap.ssid_len = 4; + } } if (changed & BSS_CHANGED_AP_PROBE_RESP) { @@ -5294,6 +5310,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, } else if (old_state == IEEE80211_STA_AUTH && new_state == IEEE80211_STA_ASSOC && (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_ADHOC)) { /* * New association. @@ -5329,6 +5346,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH && (vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_ADHOC)) { /* * Disassociation. @@ -6642,14 +6660,16 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = { }, { .max = 7, - .types = BIT(NL80211_IFTYPE_AP) + .types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_MESH_POINT) }, }; static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = { { .max = 8, - .types = BIT(NL80211_IFTYPE_AP) + .types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_MESH_POINT) }, }; @@ -6688,7 +6708,8 @@ static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO), + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_MESH_POINT) }, { .max = 1, @@ -6708,7 +6729,8 @@ static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = { { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO), + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_MESH_POINT), }, { .max = 1, @@ -6998,7 +7020,8 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP); + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_MESH_POINT); ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;