From patchwork Sun Dec 16 00:41:37 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Lamparter X-Patchwork-Id: 1905761 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 790773FCA5 for ; Sat, 22 Dec 2012 14:46:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751238Ab2LVOqL (ORCPT ); Sat, 22 Dec 2012 09:46:11 -0500 Received: from mail-wi0-f172.google.com ([209.85.212.172]:62571 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751144Ab2LVOqJ (ORCPT ); Sat, 22 Dec 2012 09:46:09 -0500 Received: by mail-wi0-f172.google.com with SMTP id o1so5699747wic.11 for ; Sat, 22 Dec 2012 06:46:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:in-reply-to:references:from:date:subject:to :cc; bh=T6lsMeA9vuccOKXoM0Hl1dn9WrZa6VHyhDDnHW5F7lM=; b=08qPR9PhLsY6Su6cI1HF1vYUM8Ri04R5GEZcSZRQFyD4ek+b/OIif8wn3Xrj4QGfpW r4uA484WQkR/On2lueqv3t2qVE8f/5wTiRm9vMQIWaLGkmHQc8vjKmJ6P13O8mD09Lpu p8ukI0HZWsxN0jszjI3Dwd7wCsjZRmisiizFrYpb/nytSrMmd+lTkPbIXUKJoG3ZjVOf nChIPb8Mcyd7qn9n76Y5IWO0EfUXn69D2LbxEKq3cja4Yf6EIzEL28blWWYxbEFtrH9x liHMx41Xbi8RuycAQxtjH11115xopkb6Mc0pKZ8LHkfD74Sy5StgCH1p2PaAvLuakAm7 YOsg== X-Received: by 10.180.107.130 with SMTP id hc2mr28006182wib.12.1356187568521; Sat, 22 Dec 2012 06:46:08 -0800 (PST) Received: from debian64.localnet (pD9F88B3A.dip.t-dialin.net. [217.248.139.58]) by mx.google.com with ESMTPS id p2sm23574791wic.7.2012.12.22.06.46.07 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 22 Dec 2012 06:46:07 -0800 (PST) Received: from localhost ([127.0.0.1] helo=debian64.localnet ident=chuck) by debian64.localnet with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1TmQKy-0004Aa-6x; Sat, 22 Dec 2012 15:46:05 +0100 Message-Id: In-Reply-To: <8f92b38a456c1dd901ce2022fcb66609a5b8ac4b.1356186145.git.chunkeey@googlemail.com> References: <8f92b38a456c1dd901ce2022fcb66609a5b8ac4b.1356186145.git.chunkeey@googlemail.com> From: Christian Lamparter Date: Sun, 16 Dec 2012 01:41:37 +0100 Subject: [PATCH 4/8] carl9170: allow P2P_GO interface creation after P2P_CLIENT To: linux-wireless@vger.kernel.org Cc: linville@tuxdriver.com Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Janusz Dziedzic reported that after a change in wpa_supplicant ["nl80211: Automatically use concurrent P2P if possible"], carl9170 was no longer able to host a P2P network. This patch tackles the problem by allowing GO interfaces to be registered, long after the P2P_CLIENT interface is brought up. Reported-by: Janusz Dziedzic Signed-off-by: Christian Lamparter --- drivers/net/wireless/ath/carl9170/main.c | 54 ++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 9dce200..5d3cb88 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -580,7 +580,7 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; - struct ieee80211_vif *main_vif; + struct ieee80211_vif *main_vif, *old_main = NULL; struct ar9170 *ar = hw->priv; int vif_id = -1, err = 0; @@ -602,6 +602,15 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, goto init; } + /* Because the AR9170 HW's MAC doesn't provide full support for + * multiple, independent interfaces [of different operation modes]. + * We have to select ONE main interface [main mode of HW], but we + * can have multiple slaves [AKA: entry in the ACK-table]. + * + * The first (from HEAD/TOP) interface in the ar->vif_list is + * always the main intf. All following intfs in this list + * are considered to be slave intfs. + */ main_vif = carl9170_get_main_vif(ar); if (main_vif) { @@ -610,6 +619,18 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_STATION) break; + /* P2P GO [master] use-case + * Because the P2P GO station is selected dynamically + * by all participating peers of a WIFI Direct network, + * the driver has be able to change the main interface + * operating mode on the fly. + */ + if (main_vif->p2p && vif->p2p && + vif->type == NL80211_IFTYPE_AP) { + old_main = main_vif; + break; + } + err = -EBUSY; rcu_read_unlock(); @@ -648,14 +669,41 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, vif_priv->id = vif_id; vif_priv->enable_beacon = false; ar->vifs++; - list_add_tail_rcu(&vif_priv->list, &ar->vif_list); + if (old_main) { + /* We end up in here, if the main interface is being replaced. + * Put the new main interface at the HEAD of the list and the + * previous inteface will automatically become second in line. + */ + list_add_rcu(&vif_priv->list, &ar->vif_list); + } else { + /* Add new inteface. If the list is empty, it will become the + * main inteface, otherwise it will be slave. + */ + list_add_tail_rcu(&vif_priv->list, &ar->vif_list); + } rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); init: - if (carl9170_get_main_vif(ar) == vif) { + main_vif = carl9170_get_main_vif(ar); + + if (main_vif == vif) { rcu_assign_pointer(ar->beacon_iter, vif_priv); rcu_read_unlock(); + if (old_main) { + struct carl9170_vif_info *old_main_priv = + (void *) old_main->drv_priv; + /* downgrade old main intf to slave intf. + * NOTE: We are no longer under rcu_read_lock. + * But we are still holding ar->mutex, so the + * vif data [id, addr] is safe. + */ + err = carl9170_mod_virtual_mac(ar, old_main_priv->id, + old_main->addr); + if (err) + goto unlock; + } + err = carl9170_init_interface(ar, vif); if (err) goto unlock;