Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/9] set addr_assign_type when inheriting a dev_addr
From: Bjørn Mork @ 2013-08-30 16:08 UTC (permalink / raw)
  To: netdev
  Cc: Bjørn Mork, Patrick McHardy, Jiri Pirko, John W. Linville,
	linux-wireless, Jouni Malinen, libertas-dev, Greg Kroah-Hartman,
	devel, Forest Bond, Stephen Hemminger, Dan Carpenter

Copying the dev_addr from a parent device is an operation
common to a number of drivers. The addr_assign_type should
be updated accordingly, either by reusing the value from
the source device or explicitly indicating that the address
is stolen by setting addr_assign_type to NET_ADDR_STOLEN.

This patch set adds a helper copying both the dev_addr and
the addr_assign_type, and use this helper in drivers which
don't currently set the addr_assign_type. Using NET_ADDR_STOLEN
might be more appropriate in some of these cases.  Please
let me know, and I'll update the patch accordingly.

Changes in v2:
 - assuming addr_len == ETH_ALEN to allow optimized memcpy
 - dropped the vt6656 patch due to addr_len being unset in that driver


Bjørn Mork (9):
  net: etherdevice: add address inherit helper
  net: vlan: inherit addr_assign_type along with dev_addr
  net: dsa: inherit addr_assign_type along with dev_addr
  net: macvlan: inherit addr_assign_type along with dev_addr
  net: team: inherit addr_assign_type along with dev_addr
  net: airo: inherit addr_assign_type along with dev_addr
  net: hostap: inherit addr_assign_type along with dev_addr
  net: libertas: inherit addr_assign_type along with dev_addr
  staging: vt6655: inherit addr_assign_type along with dev_addr

 drivers/net/macvlan.c                     |    2 +-
 drivers/net/team/team.c                   |    2 +-
 drivers/net/wireless/airo.c               |    2 +-
 drivers/net/wireless/hostap/hostap_hw.c   |    2 +-
 drivers/net/wireless/hostap/hostap_main.c |    2 +-
 drivers/net/wireless/libertas/mesh.c      |    2 +-
 drivers/staging/vt6655/hostap.c           |    2 +-
 drivers/staging/vt6655/ioctl.c            |    2 +-
 drivers/staging/vt6655/wpactl.c           |    2 +-
 include/linux/etherdevice.h               |   15 +++++++++++++++
 net/8021q/vlan_dev.c                      |    2 +-
 net/dsa/slave.c                           |    2 +-
 12 files changed, 26 insertions(+), 11 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* [PATCH v2 net-next 1/9] net: etherdevice: add address inherit helper
From: Bjørn Mork @ 2013-08-30 16:08 UTC (permalink / raw)
  To: netdev
  Cc: Bjørn Mork, Stephen Hemminger, Patrick McHardy, Jiri Pirko,
	John W. Linville, linux-wireless, Jouni Malinen, libertas-dev,
	Greg Kroah-Hartman, devel, Forest Bond
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>

Some etherdevices inherit their address from a parent or
master device. The addr_assign_type should be updated along
with the address in these cases.  Adding a helper function
to simplify this.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 include/linux/etherdevice.h |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index c623861..d8b5124 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -199,6 +199,21 @@ static inline void eth_hw_addr_random(struct net_device *dev)
 }
 
 /**
+ * eth_hw_addr_inherit - Copy dev_addr from another net_device
+ * @dst: pointer to net_device to copy dev_addr to
+ * @src: pointer to net_device to copy dev_addr from
+ *
+ * Copy the Ethernet address from one net_device to another along with
+ * the address attributes (addr_assign_type).
+ */
+static inline void eth_hw_addr_inherit(struct net_device *dst,
+				       struct net_device *src)
+{
+	dst->addr_assign_type = src->addr_assign_type;
+	memcpy(dst->dev_addr, src->dev_addr, ETH_ALEN);
+}
+
+/**
  * compare_ether_addr - Compare two Ethernet addresses
  * @addr1: Pointer to a six-byte array containing the Ethernet address
  * @addr2: Pointer other six-byte array containing the Ethernet address
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v2 net-next 8/9] net: libertas: inherit addr_assign_type along with dev_addr
From: Bjørn Mork @ 2013-08-30 16:08 UTC (permalink / raw)
  To: netdev; +Cc: Bjørn Mork, libertas-dev, linux-wireless
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>

A device inheriting a random or set address should reflect this in
its addr_assign_type.

Acked-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/wireless/libertas/mesh.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index efae07e..6fef746 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1017,7 +1017,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
 
 	mesh_dev->netdev_ops = &mesh_netdev_ops;
 	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
-	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
+	eth_hw_addr_inherit(mesh_dev, priv->dev);
 
 	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v2 net-next 7/9] net: hostap: inherit addr_assign_type along with dev_addr
From: Bjørn Mork @ 2013-08-30 16:08 UTC (permalink / raw)
  To: netdev; +Cc: Bjørn Mork, John W. Linville, linux-wireless, Jouni Malinen
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>

A device inheriting a random or set address should reflect this in
its addr_assign_type.

Cc: Jouni Malinen <j@w1.fi>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/wireless/hostap/hostap_hw.c   |    2 +-
 drivers/net/wireless/hostap/hostap_main.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 6307a4e..c275dc1 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -1425,7 +1425,7 @@ static int prism2_hw_init2(struct net_device *dev, int initial)
 		}
 		list_for_each(ptr, &local->hostap_interfaces) {
 			iface = list_entry(ptr, struct hostap_interface, list);
-			memcpy(iface->dev->dev_addr, dev->dev_addr, ETH_ALEN);
+			eth_hw_addr_inherit(iface->dev, dev);
 		}
 	} else if (local->fw_ap)
 		prism2_check_sta_fw_version(local);
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index e4f56ad..a1257c9 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -66,7 +66,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
 	list_add(&iface->list, &local->hostap_interfaces);
 
 	mdev = local->dev;
-	memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN);
+	eth_hw_addr_inherit(dev, mdev);
 	dev->base_addr = mdev->base_addr;
 	dev->irq = mdev->irq;
 	dev->mem_start = mdev->mem_start;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v2 net-next 6/9] net: airo: inherit addr_assign_type along with dev_addr
From: Bjørn Mork @ 2013-08-30 16:08 UTC (permalink / raw)
  To: netdev; +Cc: Bjørn Mork, linux-wireless
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>

A device inheriting a random or set address should reflect this in
its addr_assign_type.

Acked-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
 drivers/net/wireless/airo.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index d0adbaf..7fe1964 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2693,7 +2693,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
 	dev->base_addr = ethdev->base_addr;
 	dev->wireless_data = ethdev->wireless_data;
 	SET_NETDEV_DEV(dev, ethdev->dev.parent);
-	memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
+	eth_hw_addr_inherit(dev, ethdev);
 	err = register_netdev(dev);
 	if (err<0) {
 		free_netdev(dev);
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCHv4 0/6] add IBSS channel switch announcement support
From: Johannes Berg @ 2013-08-30 14:21 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1377690093-27024-1-git-send-email-siwu@hrz.tu-chemnitz.de>

On Wed, 2013-08-28 at 13:41 +0200, Simon Wunderlich wrote:
> This is the third iteration of the channel switch support for IBSS mode patchset
> (thanks Johannes for comments). CSA for IBSS will be required for IBSS-DFS support
> later. The patchset builds on top of the previously submitted AP DFS patchset.

Applied.

johannes


^ permalink raw reply

* [PATCH 7/7] ath10k: simplify ath10k_ce_init() wake up handling
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

ath10k_ce_init() and the functions it calls wakeup
the chip multiple times. Simplify that to call
ath10k_pci_wake() only once. This also makes it
easier to add error handling when wakeup fails.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 0f6735a..96c62a2 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -946,7 +946,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	src_ring->nentries = nentries;
 	src_ring->nentries_mask = nentries - 1;
 
-	ath10k_pci_wake(ar);
 	src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
 	src_ring->sw_index &= src_ring->nentries_mask;
 	src_ring->hw_index = src_ring->sw_index;
@@ -954,7 +953,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	src_ring->write_index =
 		ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
 	src_ring->write_index &= src_ring->nentries_mask;
-	ath10k_pci_sleep(ar);
 
 	src_ring->per_transfer_context = (void **)ptr;
 
@@ -1004,7 +1002,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 			src_ring->shadow_base_unaligned,
 			CE_DESC_RING_ALIGN);
 
-	ath10k_pci_wake(ar);
 	ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
 					 src_ring->base_addr_ce_space);
 	ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
@@ -1012,7 +1009,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0);
 	ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
 	ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
-	ath10k_pci_sleep(ar);
 
 	return 0;
 }
@@ -1049,13 +1045,11 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
 	dest_ring->nentries = nentries;
 	dest_ring->nentries_mask = nentries - 1;
 
-	ath10k_pci_wake(ar);
 	dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
 	dest_ring->sw_index &= dest_ring->nentries_mask;
 	dest_ring->write_index =
 		ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
 	dest_ring->write_index &= dest_ring->nentries_mask;
-	ath10k_pci_sleep(ar);
 
 	dest_ring->per_transfer_context = (void **)ptr;
 
@@ -1090,14 +1084,12 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
 			dest_ring->base_addr_ce_space_unaligned,
 			CE_DESC_RING_ALIGN);
 
-	ath10k_pci_wake(ar);
 	ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
 					  dest_ring->base_addr_ce_space);
 	ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
 	ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
 	ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
 	ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
-	ath10k_pci_sleep(ar);
 
 	return 0;
 }
@@ -1138,6 +1130,10 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
 	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
 	int ret;
 
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return NULL;
+
 	ce_state = ath10k_ce_init_state(ar, ce_id, attr);
 	if (!ce_state) {
 		ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
@@ -1165,8 +1161,8 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
 	}
 
 	/* Enable CE error interrupts */
-	ath10k_pci_wake(ar);
 	ath10k_ce_error_intr_enable(ar, ctrl_addr);
+
 	ath10k_pci_sleep(ar);
 
 	return ce_state;


^ permalink raw reply related

* [PATCH 6/7] ath10k: convert ath10k_pci_wake() to return
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

We should not try to access hw if wakeup fails so add
proper error checking for that. Also add the timeout lenght
to the warning message.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c  |   43 ++++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath10k/pci.c |   11 +++++---
 drivers/net/wireless/ath/ath10k/pci.h |    8 ++++--
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 496baa2..0f6735a 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -277,7 +277,9 @@ static int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 		ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n",
 			    __func__, nbytes, ce_state->src_sz_max);
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return ret;
 
 	if (unlikely(CE_RING_DELTA(nentries_mask,
 				   write_index, sw_index - 1) <= 0)) {
@@ -419,7 +421,9 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
 	write_index = dest_ring->write_index;
 	sw_index = dest_ring->sw_index;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		goto out;
 
 	if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) {
 		struct ce_desc *base = dest_ring->base_addr_owner_space;
@@ -441,6 +445,8 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
 		ret = -EIO;
 	}
 	ath10k_pci_sleep(ar);
+
+out:
 	spin_unlock_bh(&ar_pci->ce_lock);
 
 	return ret;
@@ -596,6 +602,7 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 	unsigned int sw_index = src_ring->sw_index;
 	struct ce_desc *sdesc, *sbase;
 	unsigned int read_index;
+	int ret;
 
 	if (src_ring->hw_index == sw_index) {
 		/*
@@ -605,10 +612,15 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 		 * the SW has really caught up to the HW, or if the cached
 		 * value of the HW index has become stale.
 		 */
-		ath10k_pci_wake(ar);
+
+		ret = ath10k_pci_wake(ar);
+		if (ret)
+			return ret;
+
 		src_ring->hw_index =
 			ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
 		src_ring->hw_index &= nentries_mask;
+
 		ath10k_pci_sleep(ar);
 	}
 
@@ -735,8 +747,12 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 	unsigned int nbytes;
 	unsigned int id;
 	unsigned int flags;
+	int ret;
+
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
-	ath10k_pci_wake(ar);
 	spin_lock_bh(&ar_pci->ce_lock);
 
 	/* Clear the copy-complete interrupts that will be handled here. */
@@ -795,10 +811,13 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	int ce_id;
+	int ce_id, ret;
 	u32 intr_summary;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
+
 	intr_summary = CE_INTERRUPT_SUMMARY(ar);
 
 	for (ce_id = 0; intr_summary && (ce_id < ar_pci->ce_count); ce_id++) {
@@ -826,8 +845,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
 {
 	u32 ctrl_addr = ce_state->ctrl_addr;
 	struct ath10k *ar = ce_state->ar;
+	int ret;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
 	if ((!disable_copy_compl_intr) &&
 	    (ce_state->send_cb || ce_state->recv_cb))
@@ -843,9 +865,12 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
 void ath10k_ce_disable_interrupts(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	int ce_id;
+	int ce_id, ret;
+
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
-	ath10k_pci_wake(ar);
 	for (ce_id = 0; ce_id < ar_pci->ce_count; ce_id++) {
 		struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
 		u32 ctrl_addr = ce_state->ctrl_addr;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 61f4086..66ca652 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -537,7 +537,7 @@ static void ath10k_pci_wait(struct ath10k *ar)
 		ath10k_warn("Unable to wakeup target\n");
 }
 
-void ath10k_do_pci_wake(struct ath10k *ar)
+int ath10k_do_pci_wake(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 	void __iomem *pci_addr = ar_pci->mem;
@@ -553,18 +553,19 @@ void ath10k_do_pci_wake(struct ath10k *ar)
 	atomic_inc(&ar_pci->keep_awake_count);
 
 	if (ar_pci->verified_awake)
-		return;
+		return 0;
 
 	for (;;) {
 		if (ath10k_pci_target_is_awake(ar)) {
 			ar_pci->verified_awake = true;
-			break;
+			return 0;
 		}
 
 		if (tot_delay > PCIE_WAKE_TIMEOUT) {
-			ath10k_warn("target takes too long to wake up (awake count %d)\n",
+			ath10k_warn("target took longer %d us to wake up (awake count %d)\n",
+				    PCIE_WAKE_TIMEOUT,
 				    atomic_read(&ar_pci->keep_awake_count));
-			break;
+			return -ETIMEDOUT;
 		}
 
 		udelay(curr_delay);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 5c0f9aa..49aff20 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -325,15 +325,17 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
 	return ioread32(ar_pci->mem + offset);
 }
 
-void ath10k_do_pci_wake(struct ath10k *ar);
+int ath10k_do_pci_wake(struct ath10k *ar);
 void ath10k_do_pci_sleep(struct ath10k *ar);
 
-static inline void ath10k_pci_wake(struct ath10k *ar)
+static inline int ath10k_pci_wake(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 
 	if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
-		ath10k_do_pci_wake(ar);
+		return ath10k_do_pci_wake(ar);
+
+	return 0;
 }
 
 static inline void ath10k_pci_sleep(struct ath10k *ar)


^ permalink raw reply related

* [PATCH 5/7] ath10k: clean up ath10k_ce_completed_send_next_nolock()
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

The error handling was just weird, simplify it.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c |   41 +++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 16be8c2..496baa2 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -594,8 +594,8 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 	struct ath10k *ar = ce_state->ar;
 	unsigned int nentries_mask = src_ring->nentries_mask;
 	unsigned int sw_index = src_ring->sw_index;
+	struct ce_desc *sdesc, *sbase;
 	unsigned int read_index;
-	int ret = -EIO;
 
 	if (src_ring->hw_index == sw_index) {
 		/*
@@ -611,32 +611,33 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 		src_ring->hw_index &= nentries_mask;
 		ath10k_pci_sleep(ar);
 	}
+
 	read_index = src_ring->hw_index;
 
-	if ((read_index != sw_index) && (read_index != 0xffffffff)) {
-		struct ce_desc *sbase = src_ring->shadow_base;
-		struct ce_desc *sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
+	if ((read_index == sw_index) || (read_index == 0xffffffff))
+		return -EIO;
 
-		/* Return data from completed source descriptor */
-		*bufferp = __le32_to_cpu(sdesc->addr);
-		*nbytesp = __le16_to_cpu(sdesc->nbytes);
-		*transfer_idp = MS(__le16_to_cpu(sdesc->flags),
-						CE_DESC_FLAGS_META_DATA);
+	sbase = src_ring->shadow_base;
+	sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
 
-		if (per_transfer_contextp)
-			*per_transfer_contextp =
-				src_ring->per_transfer_context[sw_index];
+	/* Return data from completed source descriptor */
+	*bufferp = __le32_to_cpu(sdesc->addr);
+	*nbytesp = __le16_to_cpu(sdesc->nbytes);
+	*transfer_idp = MS(__le16_to_cpu(sdesc->flags),
+			   CE_DESC_FLAGS_META_DATA);
 
-		/* sanity */
-		src_ring->per_transfer_context[sw_index] = NULL;
+	if (per_transfer_contextp)
+		*per_transfer_contextp =
+			src_ring->per_transfer_context[sw_index];
 
-		/* Update sw_index */
-		sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
-		src_ring->sw_index = sw_index;
-		ret = 0;
-	}
+	/* sanity */
+	src_ring->per_transfer_context[sw_index] = NULL;
 
-	return ret;
+	/* Update sw_index */
+	sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+	src_ring->sw_index = sw_index;
+
+	return 0;
 }
 
 /* NB: Modeled after ath10k_ce_completed_send_next */


^ permalink raw reply related

* [PATCH 4/7] ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

This is consistent with all other functions.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   19 +++++++------------
 drivers/net/wireless/ath/ath10k/pci.h |   12 ++++++++----
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 76426bf..61f4086 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2321,18 +2321,13 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
 
 static void ath10k_pci_device_reset(struct ath10k *ar)
 {
-	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	void __iomem *mem = ar_pci->mem;
 	int i;
 	u32 val;
 
 	if (!SOC_GLOBAL_RESET_ADDRESS)
 		return;
 
-	if (!mem)
-		return;
-
-	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS,
+	ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS,
 			       PCIE_SOC_WAKE_V_MASK);
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
 		if (ath10k_pci_target_is_awake(ar))
@@ -2341,12 +2336,12 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
 	}
 
 	/* Put Target, including PCIe, into RESET. */
-	val = ath10k_pci_reg_read32(mem, SOC_GLOBAL_RESET_ADDRESS);
+	val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS);
 	val |= 1;
-	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-		if (ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+		if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
 					  RTC_STATE_COLD_RESET_MASK)
 			break;
 		msleep(1);
@@ -2354,16 +2349,16 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
 
 	/* Pull Target, including PCIe, out of RESET. */
 	val &= ~1;
-	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-		if (!(ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+		if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
 					    RTC_STATE_COLD_RESET_MASK))
 			break;
 		msleep(1);
 	}
 
-	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
+	ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
 }
 
 static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 2e1f422..5c0f9aa 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -244,14 +244,18 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
 	return ar->hif.priv;
 }
 
-static inline u32 ath10k_pci_reg_read32(void __iomem *mem, u32 addr)
+static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr)
 {
-	return ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr);
 }
 
-static inline void ath10k_pci_reg_write32(void __iomem *mem, u32 addr, u32 val)
+static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val)
 {
-	iowrite32(val, mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr);
 }
 
 #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */


^ permalink raw reply related

* [PATCH 3/7] ath10k: remove void pointer from struct ath10k_pci_compl
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

Void pointers are bad, mmkay.

No functional changes.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   12 ++++++------
 drivers/net/wireless/ath/ath10k/pci.h |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 304bd4f..76426bf 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -643,7 +643,7 @@ static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state,
 		compl->state = ATH10K_PCI_COMPL_SEND;
 		compl->ce_state = ce_state;
 		compl->pipe_info = pipe_info;
-		compl->transfer_context = transfer_context;
+		compl->skb = transfer_context;
 		compl->nbytes = nbytes;
 		compl->transfer_id = transfer_id;
 		compl->flags = 0;
@@ -693,7 +693,7 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state,
 		compl->state = ATH10K_PCI_COMPL_RECV;
 		compl->ce_state = ce_state;
 		compl->pipe_info = pipe_info;
-		compl->transfer_context = transfer_context;
+		compl->skb = transfer_context;
 		compl->nbytes = nbytes;
 		compl->transfer_id = transfer_id;
 		compl->flags = flags;
@@ -939,7 +939,7 @@ static void ath10k_pci_stop_ce(struct ath10k *ar)
 	 * their associated resources */
 	spin_lock_bh(&ar_pci->compl_lock);
 	list_for_each_entry(compl, &ar_pci->compl_process, list) {
-		skb = (struct sk_buff *)compl->transfer_context;
+		skb = compl->skb;
 		ATH10K_SKB_CB(skb)->is_aborted = true;
 	}
 	spin_unlock_bh(&ar_pci->compl_lock);
@@ -960,7 +960,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
 
 	list_for_each_entry_safe(compl, tmp, &ar_pci->compl_process, list) {
 		list_del(&compl->list);
-		netbuf = (struct sk_buff *)compl->transfer_context;
+		netbuf = compl->skb;
 		dev_kfree_skb_any(netbuf);
 		kfree(compl);
 	}
@@ -1014,7 +1014,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
 		switch (compl->state) {
 		case ATH10K_PCI_COMPL_SEND:
 			cb->tx_completion(ar,
-					  compl->transfer_context,
+					  compl->skb,
 					  compl->transfer_id);
 			send_done = 1;
 			break;
@@ -1026,7 +1026,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
 				break;
 			}
 
-			skb = (struct sk_buff *)compl->transfer_context;
+			skb = (struct sk_buff *)compl->skb;
 			nbytes = compl->nbytes;
 
 			ath10k_dbg(ATH10K_DBG_PCI,
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index c65fe1b..2e1f422 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -54,7 +54,7 @@ struct ath10k_pci_compl {
 	enum ath10k_pci_compl_state state;
 	struct ath10k_ce_pipe *ce_state;
 	struct ath10k_pci_pipe *pipe_info;
-	void *transfer_context;
+	struct sk_buff *skb;
 	unsigned int nbytes;
 	unsigned int transfer_id;
 	unsigned int flags;


^ permalink raw reply related

* [PATCH 2/7] ath10k: make target_ce_config_wlan more readable
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

It's easier to read t if the field names are visible.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   85 ++++++++++++++++++++++++++++-----
 1 file changed, 71 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index cf7a3e4..304bd4f 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -125,21 +125,78 @@ static const struct ce_attr host_ce_config_wlan[] = {
 
 /* Target firmware's Copy Engine configuration. */
 static const struct ce_pipe_config target_ce_config_wlan[] = {
-	/* host->target HTC control and raw streams */
-	{ /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0,},
-	/* target->host HTT + HTC control */
-	{ /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0,},
-	/* target->host WMI */
-	{ /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* host->target WMI */
-	{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* host->target HTT */
-	{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0,},
+	/* CE0: host->target HTC control and raw streams */
+	{
+		.pipenum = 0,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 256,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE1: target->host HTT + HTC control */
+	{
+		.pipenum = 1,
+		.pipedir = PIPEDIR_IN,
+		.nentries = 32,
+		.nbytes_max = 512,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE2: target->host WMI */
+	{
+		.pipenum = 2,
+		.pipedir = PIPEDIR_IN,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE3: host->target WMI */
+	{
+		.pipenum = 3,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE4: host->target HTT */
+	{
+		.pipenum = 4,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 256,
+		.nbytes_max = 256,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
 	/* NB: 50% of src nentries, since tx has 2 frags */
-	/* unused */
-	{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* Reserved for target autonomous hif_memcpy */
-	{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0,},
+
+	/* CE5: unused */
+	{
+		.pipenum = 5,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE6: Reserved for target autonomous hif_memcpy */
+	{
+		.pipenum = 6,
+		.pipedir = PIPEDIR_INOUT,
+		.nentries = 32,
+		.nbytes_max = 4096,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
 	/* CE7 used only by Host */
 };
 


^ permalink raw reply related

* [PATCH 1/7] ath10k: pci: make host_ce_config_wlan[] more readable
From: Kalle Valo @ 2013-08-30 12:30 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130830122905.31164.50662.stgit@localhost6.localdomain6>

It's much more readable if struct entries in host_ce_config_wlan
are explicitly set.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   81 ++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index e29213b..cf7a3e4 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -58,24 +58,69 @@ static int ath10k_pci_start_intr(struct ath10k *ar);
 static void ath10k_pci_stop_intr(struct ath10k *ar);
 
 static const struct ce_attr host_ce_config_wlan[] = {
-	/* host->target HTC control and raw streams */
-	{ /* CE0 */ CE_ATTR_FLAGS, 16, 256, 0 },
-	/* could be moved to share CE3 */
-	/* target->host HTT + HTC control */
-	{ /* CE1 */ CE_ATTR_FLAGS, 0, 512, 512 },
-	/* target->host WMI */
-	{ /* CE2 */ CE_ATTR_FLAGS, 0, 2048, 32 },
-	/* host->target WMI */
-	{ /* CE3 */ CE_ATTR_FLAGS, 32, 2048, 0 },
-	/* host->target HTT */
-	{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
-		    CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0 },
-	/* unused */
-	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0 },
-	/* Target autonomous hif_memcpy */
-	{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0 },
-	/* ce_diag, the Diagnostic Window */
-	{ /* CE7 */ CE_ATTR_FLAGS, 2, DIAG_TRANSFER_LIMIT, 2 },
+	/* CE0: host->target HTC control and raw streams */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 16,
+		.src_sz_max = 256,
+		.dest_nentries = 0,
+	},
+
+	/* CE1: target->host HTT + HTC control */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 512,
+		.dest_nentries = 512,
+	},
+
+	/* CE2: target->host WMI */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 2048,
+		.dest_nentries = 32,
+	},
+
+	/* CE3: host->target WMI */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 32,
+		.src_sz_max = 2048,
+		.dest_nentries = 0,
+	},
+
+	/* CE4: host->target HTT */
+	{
+		.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
+		.src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES,
+		.src_sz_max = 256,
+		.dest_nentries = 0,
+	},
+
+	/* CE5: unused */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 0,
+		.dest_nentries = 0,
+	},
+
+	/* CE6: target autonomous hif_memcpy */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 0,
+		.dest_nentries = 0,
+	},
+
+	/* CE7: ce_diag, the Diagnostic Window */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 2,
+		.src_sz_max = DIAG_TRANSFER_LIMIT,
+		.dest_nentries = 2,
+	},
 };
 
 /* Target firmware's Copy Engine configuration. */


^ permalink raw reply related

* [PATCH 0/7] ath10k: pci cleanup
From: Kalle Valo @ 2013-08-30 12:29 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

Small PCI related code cleanup. Depends on Michal's CE
clean patchset.

---

Kalle Valo (7):
      ath10k: pci: make host_ce_config_wlan[] more readable
      ath10k: make target_ce_config_wlan more readable
      ath10k: remove void pointer from struct ath10k_pci_compl
      ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
      ath10k: clean up ath10k_ce_completed_send_next_nolock()
      ath10k: convert ath10k_pci_wake() to return
      ath10k: simplify ath10k_ce_init() wake up handling


 drivers/net/wireless/ath/ath10k/ce.c  |   98 ++++++++++------
 drivers/net/wireless/ath/ath10k/pci.c |  208 ++++++++++++++++++++++++---------
 drivers/net/wireless/ath/ath10k/pci.h |   22 ++-
 3 files changed, 227 insertions(+), 101 deletions(-)


^ permalink raw reply

* Re: [PATCH] cfg80211: fix potential deadlock regression
From: Johannes Berg @ 2013-08-30 12:23 UTC (permalink / raw)
  To: mbizon; +Cc: linux-wireless
In-Reply-To: <1377719389.559.9.camel@sakura.staff.proxad.net>

On Wed, 2013-08-28 at 21:49 +0200, Maxime Bizon wrote:
> On Tue, 2013-06-04 at 22:22 +0200, Johannes Berg wrote:
>  
> > -	rtnl_lock();
> >  
> >  	res = device_add(&rdev->wiphy.dev);
> > +	if (res)
> > +		return res;
> 
> I just ran across a regression caused by this commit

Sorry, yeah ... this was the locking cleanups, we did get this right
before ...

> I'm again getting uevent notifications for wireless devices that are not
> yet properly registered (ENODEV on NL80211 when using sysfs phy id)
> 
> I originally  fixed the bug by taking the cfg80211 mutex across the
> whole registration:

[...]

Yeah, but then I got rid of the cfg80211_mutex :)

> It does not seem we can reverse the rfkill_register() and device_add()
> because wiphy dev is a parent of rfkill dev.
> 
> any idea to fix this ?

I think this should be OK:
http://p.sipsolutions.net/28cf9ed446845440.txt, can you try?

johannes


^ permalink raw reply

* Re: [PATCH v2 1/4] iw:  Print Interworking IE details in scan results.
From: Johannes Berg @ 2013-08-30 11:50 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless
In-Reply-To: <1377815027-3736-1-git-send-email-greearb@candelatech.com>

Applied all, thanks

(with some minor code-style improvements)

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: implement STA CSA for drivers using channel contexts
From: Johannes Berg @ 2013-08-30 11:38 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <CA+XVXfecHzDzWi1ayiigiQ-qMiun1DK7kYnbuizjiDEYakPM+w@mail.gmail.com>

On Sun, 2013-08-25 at 16:14 +0300, Arik Nemtsov wrote:

> >> The right thing for chan_switch drivers would be not to call hw_config()..
> >
> > chan_switch? or chanctx?
> 
> both. the hw_config(channel) is meaningless for chanctx drivers. The
> legacy code for op_chan_switch drivers didn't call hw_config() as
> well, assuming they'd already get notified internally by their op.

Right.

> >> The TI driver implements the chan_switch op and uses channel contexts.
> >
> > Huh, ok, that was a combination I didn't think was going to exist, since
> > the chanswitch API doesn't really tell you what channel context etc.
> > OTOH, it does give you the vif so you have the chanctx implicitly.
> 
> Yep, it's good enough. The driver gets the chandef from the vif.

Ok, fair enough.

> >> Note that with the above, the channel_contexts + software chan-switch
> >> drivers will still need the kind of code that I wrote. So it would
> >> just lead to replicated code. Or maybe you meant something else?
> >
> > We have too many possibilities I guess ... I think for MVM I want the
> > disconnect, not the channel context change in software. You're taking
> > that possibility away, hence my suggestion of a new hardware flag for it
> > or so.
> 
> I was thinking it's equivalent to to AP case - currently mac80211 is
> the dictator and simply changes the chandef once the lower drv
> completes the switch.

Yeah but the driver in this case has a choice to not supported it.

> Anyway IMHO the simplest approach to handle all the legacy stuff +
> chanctx it to keep the current patch as is, and add a mac80211 HW flag
> to support it, keeping the deauth option as default.
> That's what I think you're suggesting?

Yeah, that sounds about right.

> >> Also, where would you put csa_active = true (if at all) for a STA
> >> interface? Unlike AP, the trigger here is mac80211 code. So putting it
> >> there seemed appropriate.
> >
> > Yeah, I was really just trying to say that current chanctx drivers need
> > not really expect a chanctx to change channel unless they implement CSA,
> > but that currently means AP-CSA - basically what I just said above with
> > taking away the possibility of doing the deauth instead.
> 
> Let's keep the csa_active as I've used it, and just do a deauth when
> the csa-support HW flag is not given?

Works for me - I wasn't particularly worried about the csa_active
handling per se, but rather what it implied about the calls and driver
support etc.

johannes


^ permalink raw reply

* Re: [PATCH v14 2/2] cfg80211: P2P find phase offload
From: Johannes Berg @ 2013-08-30 11:36 UTC (permalink / raw)
  To: Vladimir Kondratiev
  Cc: linux-wireless, Luis R . Rodriguez, John W . Linville,
	Jouni Malinen
In-Reply-To: <5966990.L3xT1qRD5c@lx-vladimir>

On Mon, 2013-08-26 at 16:26 +0300, Vladimir Kondratiev wrote:
> On Friday, August 23, 2013 04:16:49 PM Johannes Berg wrote:
> > Ilan also pointed out to me that it might be necessary to document (and
> > enforce?) that scan/sched_scan can't be executed in parallel? Or can
> > they?
> 
> Indeed, one can't simultaneously scan and do p2p_find on the same hardware,
> because of contradictionary requirements. I documented it in start_p2p_find:
> > + *     P2P find can't run concurrently with ROC or scan,
> > + *     conflict with scan detected by cfg80211 and -EBUSY returned;
> > + *     and driver should check for ROC and return -EBUSY to indicate
> > conflict.
> 
> Shall I elaborate more, what is appropriate location for this explanation?

Ah, I missed that. I was thinking it should be in nl80211.h so that
users of the API would also be told about it.

In fact, it looks like you have no documentation in nl80211.h for the
new commands at all, you should change that anyway. I'm surprised we
never discussed that before, sorry.

> Regarding locking - I feel I need to do it similar to scan. There, we have
> locked inner function that is invoked from cfg80211_wq.

Yes, we put the 'done' completion on the workqueue. However, we don't
have an explicit stop operation for scan, so things are a bit simpler -
scan is triggered and eventually stops. There's no race.

If you do the same, there's a race:

  driver stops by itself
  driver calls stop
  stop queued to workqueue
                                 userspace calls stop
                                 driver stop invoked

This could lead to confusion I think.

> And, overall - maybe reuse scan pattern in other aspects -
> allocate cfg80211_p2p_find_params like it is done for cfg80211_scan_request
> (and rename struct to cfg80211_p2p_find_request).
> instead of wdev->p2p_find_active, have rdev->p2p_find_req - this will sort
> concurrent p2p_find for sibling wdevs
> 
> Also, same pattern will make p2p_find API more intuitive if it follows same
> conventions as scan 

I guess you can make that work, just due the race above it's a bit
trickier than scan.

johannes


^ permalink raw reply

* Re: [PATCH 0/2] mac80211: fix minstrel fixed_rate management
From: Johannes Berg @ 2013-08-30 11:29 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: Lorenzo Bianconi, linville, linux-wireless
In-Reply-To: <52207CC4.50702@openwrt.org>

On Fri, 2013-08-30 at 13:06 +0200, Felix Fietkau wrote:
> On 2013-08-27 4:59 PM, Lorenzo Bianconi wrote:
> > This couple of patches add/fix fixed_rate management of minstrel/minstrel_ht
> > rate controller. In particular:
> > *[PATCH 1/2]: add the capability to use a particular rate to minstrel rate
> >  controller
> > *[PATCH 2/2]: restore the mcs index configured according to fixed_rate value
> >  since it has been overridden in minstrel_ht_update_stats throughput computation
> > 
> > Regards,
> > Lorenzo
> > 
> > Lorenzo Bianconi (2):
> >   mac80211: add fixed_rate management to minstrel rc
> >   mac80211: do not override fixed_rate_idx in minstrel_ht_update_stats
> > 
> >  net/mac80211/rc80211_minstrel.c    | 14 ++++++++++++++
> >  net/mac80211/rc80211_minstrel_ht.c | 23 +++++++++++++----------
> >  2 files changed, 27 insertions(+), 10 deletions(-)
> Acked-by: Felix Fietkau <nbd@openwrt.org>

Applied.

johannes


^ permalink raw reply

* Re: [PATCH 0/2] mac80211: fix minstrel fixed_rate management
From: Felix Fietkau @ 2013-08-30 11:06 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linville, linux-wireless, johannes
In-Reply-To: <1377615587-6015-1-git-send-email-lorenzo.bianconi83@gmail.com>

On 2013-08-27 4:59 PM, Lorenzo Bianconi wrote:
> This couple of patches add/fix fixed_rate management of minstrel/minstrel_ht
> rate controller. In particular:
> *[PATCH 1/2]: add the capability to use a particular rate to minstrel rate
>  controller
> *[PATCH 2/2]: restore the mcs index configured according to fixed_rate value
>  since it has been overridden in minstrel_ht_update_stats throughput computation
> 
> Regards,
> Lorenzo
> 
> Lorenzo Bianconi (2):
>   mac80211: add fixed_rate management to minstrel rc
>   mac80211: do not override fixed_rate_idx in minstrel_ht_update_stats
> 
>  net/mac80211/rc80211_minstrel.c    | 14 ++++++++++++++
>  net/mac80211/rc80211_minstrel_ht.c | 23 +++++++++++++----------
>  2 files changed, 27 insertions(+), 10 deletions(-)
Acked-by: Felix Fietkau <nbd@openwrt.org>


^ permalink raw reply

* Re: [PATCH v2] mac80211: change beacon/connection polling
From: Johannes Berg @ 2013-08-30 10:04 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless
In-Reply-To: <20130827093635.GD5548@redhat.com>

On Tue, 2013-08-27 at 11:36 +0200, Stanislaw Gruszka wrote:
> Since when we detect baecon lost we do active AP probing (using nullfunc
> frame or probe request) there is no need to have beacon polling. Flags
> IEEE80211_STA_BEACON_POLL seems to be used just for historical reasons.
> 
> Change also make that after we start connection poll due to beacon loss,
> next received beacon will abort the poll.

Applied, thanks

johannes


^ permalink raw reply

* Re: [PATCH] cfg80211: use the correct macro to check for active monitor support
From: Johannes Berg @ 2013-08-30 10:03 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1377772017-24764-1-git-send-email-luciano.coelho@intel.com>

On Thu, 2013-08-29 at 13:26 +0300, Luciano Coelho wrote:
> Use MONITOR_FLAG_ACTIVE, which is a flag mask, instead of
> NL80211_MNTR_FLAG_ACTIVE, which is a flag index, when checking if the
> hardware supports active monitoring.

Applied, thanks.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: Remove superfluous is_multicast_ether_addr() call
From: Johannes Berg @ 2013-08-30 10:03 UTC (permalink / raw)
  To: Sergey Ryazanov; +Cc: linux-wireless
In-Reply-To: <1377812109-22889-1-git-send-email-ryazanov.s.a@gmail.com>

On Fri, 2013-08-30 at 01:35 +0400, Sergey Ryazanov wrote:
> Remove superfluous call and use locally stored previous result.

Applied, thanks.

johannes


^ permalink raw reply

* [PATCH 2/3] ieee80211: fix vht cap definitions
From: Johannes Berg @ 2013-08-30  8:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: Eliad Peller
In-Reply-To: <1377852561-16754-1-git-send-email-johannes@sipsolutions.net>

From: Eliad Peller <eliad@wizery.com>

VHT_CAP_BEAMFORMER_ANTENNAS cap is actually defined in the draft as
VHT_CAP_BEAMFORMEE_STS_MAX, and its size is 3 bits long.

VHT_CAP_SOUNDING_DIMENSIONS is also 3 bits long.

Fix the definitions and change the cap masking accordingly.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/linux/ieee80211.h | 4 ++--
 net/mac80211/vht.c        | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 23a8877..57b699e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1390,8 +1390,8 @@ struct ieee80211_vht_operation {
 #define IEEE80211_VHT_CAP_RXSTBC_MASK				0x00000700
 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE			0x00000800
 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE			0x00001000
-#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX		0x00006000
-#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX		0x00030000
+#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX			0x0000e000
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX		0x00070000
 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE			0x00080000
 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE			0x00100000
 #define IEEE80211_VHT_CAP_VHT_TXOP_PS				0x00200000
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 97c28941..de01127 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -185,13 +185,13 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
 	if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {
 		vht_cap->cap |= cap_info &
 				(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
-				 IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX |
 				 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX);
 	}
 
 	if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
 		vht_cap->cap |= cap_info &
-				IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+				(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+				 IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX);
 
 	if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
 		vht_cap->cap |= cap_info &
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 3/3] mac80211: allow configuring smps_mode_in_ps
From: Johannes Berg @ 2013-08-30  8:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: Eliad Peller
In-Reply-To: <1377852561-16754-1-git-send-email-johannes@sipsolutions.net>

From: Eliad Peller <eliad@wizery.com>

When in automatic smps mode (default for station mode),
mac80211 configures dynamic smps when the station enters
powersave.

However, drivers might prefer using different modes in this
case (e.g. due to major throughput degradation).

Add a new hw->smps_mode_in_ps field that can be configured
by the driver in order to override the default smps dynamic mode.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/mac80211.h        |  5 +++++
 net/mac80211/cfg.c            |  2 +-
 net/mac80211/debugfs_netdev.c | 11 +++++++----
 net/mac80211/main.c           |  1 +
 net/mac80211/mlme.c           |  7 ++++++-
 5 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3ecf635..637b797 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1615,6 +1615,10 @@ enum ieee80211_hw_flags {
  * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may
  *	deliver to a WMM STA during any Service Period triggered by the WMM STA.
  *	Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values.
+ *
+ * @smps_mode_in_ps: smps mode to use when automatic smps mode is configured.
+ *	The default is _DYNAMIC.
+ *	Use the %IEEE80211_SMPS_* values.
  */
 struct ieee80211_hw {
 	struct ieee80211_conf conf;
@@ -1642,6 +1646,7 @@ struct ieee80211_hw {
 	netdev_features_t netdev_features;
 	u8 uapsd_queues;
 	u8 uapsd_max_sp_len;
+	enum ieee80211_smps_mode smps_mode_in_ps;
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7aa38ce..1932126 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2364,7 +2364,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
 
 	if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
 		if (sdata->u.mgd.powersave)
-			smps_mode = IEEE80211_SMPS_DYNAMIC;
+			smps_mode = sdata->local->hw.smps_mode_in_ps;
 		else
 			smps_mode = IEEE80211_SMPS_OFF;
 	}
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index cafe614..66dff46 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -212,16 +212,19 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
 			      enum ieee80211_smps_mode smps_mode)
 {
 	struct ieee80211_local *local = sdata->local;
+	enum ieee80211_smps_mode target_mode = smps_mode;
 	int err;
 
+	/* in case of auto, hw.smps_mode_in_ps will be configured when in psm */
+	if (smps_mode == IEEE80211_SMPS_AUTOMATIC)
+		target_mode = local->hw.smps_mode_in_ps;
+
 	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) &&
-	    smps_mode == IEEE80211_SMPS_STATIC)
+	    target_mode == IEEE80211_SMPS_STATIC)
 		return -EINVAL;
 
-	/* auto should be dynamic if in PS mode */
 	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) &&
-	    (smps_mode == IEEE80211_SMPS_DYNAMIC ||
-	     smps_mode == IEEE80211_SMPS_AUTOMATIC))
+	    target_mode == IEEE80211_SMPS_DYNAMIC)
 		return -EINVAL;
 
 	/* supported only on managed interfaces for now */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 21d5d44..885c8e3 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -585,6 +585,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
 	local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
 	local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
+	local->hw.smps_mode_in_ps = IEEE80211_SMPS_DYNAMIC;
 	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 	wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
 	wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 45a87ee..007cc4d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3700,7 +3700,12 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 	ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
 	ifmgd->p2p_noa_index = -1;
 
-	if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
+	/* set automatic smps by default, if hw.smps_mode_in_ps is supported */
+	if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS &&
+	    sdata->local->hw.smps_mode_in_ps == IEEE80211_SMPS_DYNAMIC)
+		ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
+	else if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS &&
+		 sdata->local->hw.smps_mode_in_ps == IEEE80211_SMPS_STATIC)
 		ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
 	else
 		ifmgd->req_smps = IEEE80211_SMPS_OFF;
-- 
1.8.4.rc3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox