From patchwork Wed Oct 24 19:59:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Cardona X-Patchwork-Id: 1640361 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 517513FCF7 for ; Wed, 24 Oct 2012 19:59:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757585Ab2JXT7x (ORCPT ); Wed, 24 Oct 2012 15:59:53 -0400 Received: from mail-da0-f46.google.com ([209.85.210.46]:38503 "EHLO mail-da0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756093Ab2JXT7w (ORCPT ); Wed, 24 Oct 2012 15:59:52 -0400 Received: by mail-da0-f46.google.com with SMTP id n41so403982dak.19 for ; Wed, 24 Oct 2012 12:59:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=PwObum89XUdYbNfs6u+U0OY12K4j3ud3F1vePcc7lO4=; b=mi8adXHfZN6OCMbp9R2jd2Qc2cV5Je4WyjxXblcq4d/ZdYM4lCyvhCCP9lNzjvZjc2 8W3Gsj8TarnGOMrNx2GKrycqdQXOvQehMUBeibxot7pkWlzNASl2RnrLa2JkFeA2z00l Ko0GpQ3IBq4ZE89unB++fYxvKSWGxT6jCK1WwdToP3aZGXxve1SDHAlPxg1+Q3PJ0Cw0 S0Td/sIPOqosznHHXbrZLu+/gt8Hyw5BB/l5OtK9UiquJaXo61hY/xiTr9wcJzE0stus ASQgdwTHSrMWbp3SIcR1XHecg4nYAIfJZFUWzVE+CYi8TdwUwKvoyXszSP8hFvV++xLy hjQA== Received: by 10.69.1.37 with SMTP id bd5mr53027201pbd.77.1351108792089; Wed, 24 Oct 2012 12:59:52 -0700 (PDT) Received: from localhost.localdomain (70-35-43-50.static.wiline.com. [70.35.43.50]) by mx.google.com with ESMTPS id ru4sm9907108pbc.25.2012.10.24.12.59.50 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 24 Oct 2012 12:59:51 -0700 (PDT) From: Javier Cardona To: linville@tuxdriver.com Cc: Javier Cardona , linux-wireless@vger.kernel.org, devel@lists.open80211s.org, johannes@sipsolutions.net Subject: [PATCH 1/2] ath9k_htc: Add support for NL80211_IFTYPE_MESH_POINT interfaces Date: Wed, 24 Oct 2012 12:59:33 -0700 Message-Id: <1351108774-7450-2-git-send-email-javier@cozybit.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1351108774-7450-1-git-send-email-javier@cozybit.com> References: <1351108774-7450-1-git-send-email-javier@cozybit.com> X-Gm-Message-State: ALoCoQmJ09w61yFOMWggnNLA2Um7JQgAfkN757xHIJQev02RtiK1t1e8Tsp6kHcLqsj6aRsGBb8J Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org More specifically, enable AP-style beaconing on mesh ifaces, honor FIF_OTHER_BSS filter and change the hw capabilities to reflect mesh support. Also enable IEEE80211_HW_SUPPORTS_PER_STA_GTK, IEEE80211_HW_MFP_CAPABLE and WIPHY_FLAG_IBSS_RSN. Probably these should depend on the capabilities of the hardware but I don't know which hardware supports what. But these are required for secured mesh and work fine on our TL-WN821N Signed-off-by: Javier Cardona --- drivers/net/wireless/ath/ath9k/htc.h | 7 +++++++ drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 17 ++++++++++++++++- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 +++++- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b30596f..c64dd0f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -207,6 +207,9 @@ struct ath9k_htc_target_rx_stats { case NL80211_IFTYPE_AP: \ _priv->num_ap_vif++; \ break; \ + case NL80211_IFTYPE_MESH_POINT: \ + _priv->num_mbss_vif++; \ + break; \ default: \ break; \ } \ @@ -223,6 +226,9 @@ struct ath9k_htc_target_rx_stats { case NL80211_IFTYPE_AP: \ _priv->num_ap_vif--; \ break; \ + case NL80211_IFTYPE_MESH_POINT: \ + _priv->num_mbss_vif--; \ + break; \ default: \ break; \ } \ @@ -449,6 +455,7 @@ struct ath9k_htc_priv { u8 sta_slot; u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; u8 num_ibss_vif; + u8 num_mbss_vif; u8 num_sta_vif; u8 num_sta_assoc_vif; u8 num_ap_vif; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index f42d2eb..263f9b7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -28,7 +28,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); - if (priv->ah->opmode == NL80211_IFTYPE_AP) { + if (priv->ah->opmode == NL80211_IFTYPE_AP || + priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) { qi.tqi_aifs = 1; qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; @@ -628,6 +629,13 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, case NL80211_IFTYPE_ADHOC: ath9k_htc_beacon_config_adhoc(priv, cur_conf); break; + case NL80211_IFTYPE_MESH_POINT: + /* 802.11s defines a different beaconing method for + * mesh points that closely resembles AP-style + * beaconing. Until that is implemented, just use + * AP-style beaconing for mesh points. + */ + /* Fall through */ case NL80211_IFTYPE_AP: ath9k_htc_beacon_config_ap(priv, cur_conf); break; @@ -649,6 +657,13 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) case NL80211_IFTYPE_ADHOC: ath9k_htc_beacon_config_adhoc(priv, cur_conf); break; + case NL80211_IFTYPE_MESH_POINT: + /* 802.11s defines a different beaconing method for + * mesh points that closely resembles AP-style + * beaconing. Until that is implemented, just use + * AP-style beaconing for mesh points. + */ + /* Fall through */ case NL80211_IFTYPE_AP: ath9k_htc_beacon_config_ap(priv, cur_conf); break; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index d98255e..9c5c63c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -707,6 +707,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SUPPORTS_PER_STA_GTK | + IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; hw->wiphy->interface_modes = @@ -714,9 +716,11 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT); + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_MESH_POINT); hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ca78e33..d763423 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -178,6 +178,8 @@ static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv) priv->ah->opmode = NL80211_IFTYPE_ADHOC; else if (priv->num_ap_vif) priv->ah->opmode = NL80211_IFTYPE_AP; + else if (priv->num_mbss_vif) + priv->ah->opmode = NL80211_IFTYPE_MESH_POINT; else priv->ah->opmode = NL80211_IFTYPE_STATION; @@ -1048,6 +1050,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, return -ENOBUFS; } + if (priv->num_mbss_vif || + (priv->nvifs && vif->type == NL80211_IFTYPE_MESH_POINT)) { + ath_err(common, "Mesh BSS coexistence with other modes is not allowed\n"); + mutex_unlock(&priv->mutex); + return -ENOBUFS; + } + if (((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_ADHOC)) && ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) { @@ -1070,6 +1079,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_AP: hvif.opmode = HTC_M_HOSTAP; break; + case NL80211_IFTYPE_MESH_POINT: + /* close enough */ + hvif.opmode = HTC_M_WDS; + break; default: ath_err(common, "Interface type %d not yet supported\n", vif->type); @@ -1102,6 +1115,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, INC_VIF(priv, vif->type); if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_MESH_POINT) || (vif->type == NL80211_IFTYPE_ADHOC)) ath9k_htc_assign_bslot(priv, vif);