All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/6] ath10k: add basic tdls support
@ 2015-03-20 11:02 ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

This patchset introduces tdls funtionality without tdls peer uapsd
and tdls channel switching. Tdls is supported by qca6174 hardware 
what is indicated by firmware through supported services.
Tdls station when authorized requires some parameters that are filled in 
by rate control initialization. Rate control for tdls is initialized
at proper time in mac80211 patch:
mac80211: initialize rate control earlier for tdls station

So tdls funtionality implemented by this patchset depends on 
mac80211: initialize rate control earlier for tdls station

v2:
-introduce tdls peer counter
-minor changes after review

v3:
-more minor changes after review
-replace tdls peer counter variable by iterate station function

v4:
-provide functions for counting tdls station per vif and tdls vifs
-handle maximum number of tdls vifs
-split code into more patches

Marek Puzyniak (5):
  ath10k: make peer type configurable
  ath10k: store max tdls vdevs that fw can handle
  ath10k: update station counting
  ath10k: add wmi support for tdls
  ath10k: introduce basic tdls functionality

Michal Kazior (1):
  ath10k: unify tx mode and dispatch

 drivers/net/wireless/ath/ath10k/core.c    |   1 +
 drivers/net/wireless/ath/ath10k/core.h    |   3 +
 drivers/net/wireless/ath/ath10k/htt_rx.c  |   8 -
 drivers/net/wireless/ath/ath10k/htt_tx.c  |  30 ++-
 drivers/net/wireless/ath/ath10k/hw.h      |   1 +
 drivers/net/wireless/ath/ath10k/mac.c     | 391 +++++++++++++++++++++++++-----
 drivers/net/wireless/ath/ath10k/mac.h     |   8 +
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  50 +++-
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 160 +++++++++++-
 drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 ++++
 drivers/net/wireless/ath/ath10k/wmi.c     |   3 +-
 drivers/net/wireless/ath/ath10k/wmi.h     |  43 ++++
 12 files changed, 664 insertions(+), 87 deletions(-)

-- 
2.1.4


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v4 0/6] ath10k: add basic tdls support
@ 2015-03-20 11:02 ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

This patchset introduces tdls funtionality without tdls peer uapsd
and tdls channel switching. Tdls is supported by qca6174 hardware 
what is indicated by firmware through supported services.
Tdls station when authorized requires some parameters that are filled in 
by rate control initialization. Rate control for tdls is initialized
at proper time in mac80211 patch:
mac80211: initialize rate control earlier for tdls station

So tdls funtionality implemented by this patchset depends on 
mac80211: initialize rate control earlier for tdls station

v2:
-introduce tdls peer counter
-minor changes after review

v3:
-more minor changes after review
-replace tdls peer counter variable by iterate station function

v4:
-provide functions for counting tdls station per vif and tdls vifs
-handle maximum number of tdls vifs
-split code into more patches

Marek Puzyniak (5):
  ath10k: make peer type configurable
  ath10k: store max tdls vdevs that fw can handle
  ath10k: update station counting
  ath10k: add wmi support for tdls
  ath10k: introduce basic tdls functionality

Michal Kazior (1):
  ath10k: unify tx mode and dispatch

 drivers/net/wireless/ath/ath10k/core.c    |   1 +
 drivers/net/wireless/ath/ath10k/core.h    |   3 +
 drivers/net/wireless/ath/ath10k/htt_rx.c  |   8 -
 drivers/net/wireless/ath/ath10k/htt_tx.c  |  30 ++-
 drivers/net/wireless/ath/ath10k/hw.h      |   1 +
 drivers/net/wireless/ath/ath10k/mac.c     | 391 +++++++++++++++++++++++++-----
 drivers/net/wireless/ath/ath10k/mac.h     |   8 +
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  50 +++-
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 160 +++++++++++-
 drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 ++++
 drivers/net/wireless/ath/ath10k/wmi.c     |   3 +-
 drivers/net/wireless/ath/ath10k/wmi.h     |  43 ++++
 12 files changed, 664 insertions(+), 87 deletions(-)

-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v4 1/6] ath10k: unify tx mode and dispatch
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Michal Kazior, Marek Puzyniak

From: Michal Kazior <michal.kazior@tieto.com>

There are a few different tx paths depending on
firmware and frame itself.

Creating a uniform decision will make it possible
to switch between different txmode easier, both
for testing and for future features as well.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.h   |   2 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   8 --
 drivers/net/wireless/ath/ath10k/htt_tx.c |  30 +++---
 drivers/net/wireless/ath/ath10k/mac.c    | 155 ++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath10k/mac.h    |   8 ++
 5 files changed, 144 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index c1f43b0..b07d883 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -83,6 +83,8 @@ struct ath10k_skb_cb {
 	dma_addr_t paddr;
 	u8 eid;
 	u8 vdev_id;
+	enum ath10k_hw_txrx_mode txmode;
+	bool is_protected;
 
 	struct {
 		u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 01a2b38..756fc19 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -637,14 +637,6 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
 	return 0;
 }
 
-struct rfc1042_hdr {
-	u8 llc_dsap;
-	u8 llc_ssap;
-	u8 llc_ctrl;
-	u8 snap_oui[3];
-	__be16 snap_type;
-} __packed;
-
 struct amsdu_subframe_hdr {
 	u8 dst[ETH_ALEN];
 	u8 src[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index cbd2bc9..5b2c61b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -420,9 +420,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	int res;
 	u8 flags0 = 0;
 	u16 msdu_id, flags1 = 0;
-	dma_addr_t paddr;
-	u32 frags_paddr;
-	bool use_frags;
+	dma_addr_t paddr = 0;
+	u32 frags_paddr = 0;
 
 	res = ath10k_htt_tx_inc_pending(htt);
 	if (res)
@@ -440,12 +439,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	prefetch_len = min(htt->prefetch_len, msdu->len);
 	prefetch_len = roundup(prefetch_len, 4);
 
-	/* Since HTT 3.0 there is no separate mgmt tx command. However in case
-	 * of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
-	 * fragment list host driver specifies directly frame pointer. */
-	use_frags = htt->target_version_major < 3 ||
-		    !ieee80211_is_mgmt(hdr->frame_control);
-
 	skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC,
 					   &paddr);
 	if (!skb_cb->htt.txbuf) {
@@ -466,7 +459,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	if (res)
 		goto err_free_txbuf;
 
-	if (likely(use_frags)) {
+	switch (skb_cb->txmode) {
+	case ATH10K_HW_TXRX_RAW:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
+		flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+		/* pass through */
+	case ATH10K_HW_TXRX_ETHERNET:
 		frags = skb_cb->htt.txbuf->frags;
 
 		frags[0].paddr = __cpu_to_le32(skb_cb->paddr);
@@ -474,15 +472,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 		frags[1].paddr = 0;
 		frags[1].len = 0;
 
-		flags0 |= SM(ATH10K_HW_TXRX_NATIVE_WIFI,
-			     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+		flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
 
 		frags_paddr = skb_cb->htt.txbuf_paddr;
-	} else {
+		break;
+	case ATH10K_HW_TXRX_MGMT:
 		flags0 |= SM(ATH10K_HW_TXRX_MGMT,
 			     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+		flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
 
 		frags_paddr = skb_cb->paddr;
+		break;
 	}
 
 	/* Normally all commands go through HTC which manages tx credits for
@@ -508,11 +508,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 			prefetch_len);
 	skb_cb->htt.txbuf->htc_hdr.flags = 0;
 
-	if (!ieee80211_has_protected(hdr->frame_control))
+	if (!skb_cb->is_protected)
 		flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
 
-	flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
-
 	flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
 	flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
 	if (msdu->ip_summed == CHECKSUM_PARTIAL) {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 506e886..6b07ef6 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2519,6 +2519,43 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
 	return 0;
 }
 
+static enum ath10k_hw_txrx_mode
+ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
+		       struct sk_buff *skb)
+{
+	const struct ieee80211_hdr *hdr = (void *)skb->data;
+	__le16 fc = hdr->frame_control;
+
+	if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
+		return ATH10K_HW_TXRX_RAW;
+
+	if (ieee80211_is_mgmt(fc))
+		return ATH10K_HW_TXRX_MGMT;
+
+	/* Workaround:
+	 *
+	 * NullFunc frames are mostly used to ping if a client or AP are still
+	 * reachable and responsive. This implies tx status reports must be
+	 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
+	 * come to a conclusion that the other end disappeared and tear down
+	 * BSS connection or it can never disconnect from BSS/client (which is
+	 * the case).
+	 *
+	 * Firmware with HTT older than 3.0 delivers incorrect tx status for
+	 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
+	 * which seems to deliver correct tx reports for NullFunc frames. The
+	 * downside of using it is it ignores client powersave state so it can
+	 * end up disconnecting sleeping clients in AP mode. It should fix STA
+	 * mode though because AP don't sleep.
+	 */
+	if (ar->htt.target_version_major < 3 &&
+	    (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
+	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
+		return ATH10K_HW_TXRX_MGMT;
+
+	return ATH10K_HW_TXRX_NATIVE_WIFI;
+}
+
 /* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
  * Control in the header.
  */
@@ -2547,6 +2584,33 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
 	hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
 }
 
+static void ath10k_tx_h_8023(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+	struct rfc1042_hdr *rfc1042;
+	struct ethhdr *eth;
+	size_t hdrlen;
+	u8 da[ETH_ALEN];
+	u8 sa[ETH_ALEN];
+	__be16 type;
+
+	hdr = (void *)skb->data;
+	hdrlen = ieee80211_hdrlen(hdr->frame_control);
+	rfc1042 = (void *)skb->data + hdrlen;
+
+	ether_addr_copy(da, ieee80211_get_DA(hdr));
+	ether_addr_copy(sa, ieee80211_get_SA(hdr));
+	type = rfc1042->snap_type;
+
+	skb_pull(skb, hdrlen + sizeof(*rfc1042));
+	skb_push(skb, sizeof(*eth));
+
+	eth = (void *)skb->data;
+	ether_addr_copy(eth->h_dest, da);
+	ether_addr_copy(eth->h_source, sa);
+	eth->h_proto = type;
+}
+
 static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
 				       struct ieee80211_vif *vif,
 				       struct sk_buff *skb)
@@ -2583,45 +2647,51 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
 		 ar->htt.target_version_minor >= 4);
 }
 
-static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
+static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
 	int ret = 0;
 
-	if (ar->htt.target_version_major >= 3) {
-		/* Since HTT 3.0 there is no separate mgmt tx command */
-		ret = ath10k_htt_tx(&ar->htt, skb);
-		goto exit;
+	spin_lock_bh(&ar->data_lock);
+
+	if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
+		ath10k_warn(ar, "wmi mgmt tx queue is full\n");
+		ret = -ENOSPC;
+		goto unlock;
 	}
 
-	if (ieee80211_is_mgmt(hdr->frame_control)) {
-		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
-			     ar->fw_features)) {
-			if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >=
-			    ATH10K_MAX_NUM_MGMT_PENDING) {
-				ath10k_warn(ar, "reached WMI management transmit queue limit\n");
-				ret = -EBUSY;
-				goto exit;
-			}
+	__skb_queue_tail(q, skb);
+	ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
 
-			skb_queue_tail(&ar->wmi_mgmt_tx_queue, skb);
-			ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
-		} else {
-			ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-		}
-	} else if (!test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
-			     ar->fw_features) &&
-		   ieee80211_is_nullfunc(hdr->frame_control)) {
-		/* FW does not report tx status properly for NullFunc frames
-		 * unless they are sent through mgmt tx path. mac80211 sends
-		 * those frames when it detects link/beacon loss and depends
-		 * on the tx status to be correct. */
-		ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-	} else {
-		ret = ath10k_htt_tx(&ar->htt, skb);
+unlock:
+	spin_unlock_bh(&ar->data_lock);
+
+	return ret;
+}
+
+static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+	struct ath10k_htt *htt = &ar->htt;
+	int ret = 0;
+
+	switch (cb->txmode) {
+	case ATH10K_HW_TXRX_RAW:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
+	case ATH10K_HW_TXRX_ETHERNET:
+		ret = ath10k_htt_tx(htt, skb);
+		break;
+	case ATH10K_HW_TXRX_MGMT:
+		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
+			     ar->fw_features))
+			ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
+		else if (ar->htt.target_version_major >= 3)
+			ret = ath10k_htt_tx(htt, skb);
+		else
+			ret = ath10k_htt_mgmt_tx(htt, skb);
+		break;
 	}
 
-exit:
 	if (ret) {
 		ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
 			    ret);
@@ -2694,7 +2764,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 		ar->offchan_tx_skb = skb;
 		spin_unlock_bh(&ar->data_lock);
 
-		ath10k_tx_htt(ar, skb);
+		ath10k_mac_tx(ar, skb);
 
 		ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
 						  3 * HZ);
@@ -2919,6 +2989,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_vif *vif = info->control.vif;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	__le16 fc = hdr->frame_control;
 
 	/* We should disable CCK RATE due to P2P */
 	if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -2927,12 +2998,26 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	ATH10K_SKB_CB(skb)->htt.is_offchan = false;
 	ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
 	ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, skb);
+	ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
 
-	/* it makes no sense to process injected frames like that */
-	if (vif && vif->type != NL80211_IFTYPE_MONITOR) {
+	switch (ATH10K_SKB_CB(skb)->txmode) {
+	case ATH10K_HW_TXRX_MGMT:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
 		ath10k_tx_h_nwifi(hw, skb);
 		ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
 		ath10k_tx_h_seq_no(vif, skb);
+		break;
+	case ATH10K_HW_TXRX_ETHERNET:
+		ath10k_tx_h_8023(skb);
+		break;
+	case ATH10K_HW_TXRX_RAW:
+		/* FIXME: Packet injection isn't implemented. It should be
+		 * doable with firmware 10.2 on qca988x.
+		 */
+		WARN_ON_ONCE(1);
+		ieee80211_free_txskb(hw, skb);
+		return;
 	}
 
 	if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
@@ -2954,7 +3039,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 		}
 	}
 
-	ath10k_tx_htt(ar, skb);
+	ath10k_mac_tx(ar, skb);
 }
 
 /* Must not be called with conf_mutex held as workers can use that also. */
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index 3b64d99..2cdf68d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -28,6 +28,14 @@ struct ath10k_generic_iter {
 	int ret;
 };
 
+struct rfc1042_hdr {
+	u8 llc_dsap;
+	u8 llc_ssap;
+	u8 llc_ctrl;
+	u8 snap_oui[3];
+	__be16 snap_type;
+} __packed;
+
 struct ath10k *ath10k_mac_create(size_t priv_size);
 void ath10k_mac_destroy(struct ath10k *ar);
 int ath10k_mac_register(struct ath10k *ar);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 1/6] ath10k: unify tx mode and dispatch
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak, Michal Kazior

From: Michal Kazior <michal.kazior@tieto.com>

There are a few different tx paths depending on
firmware and frame itself.

Creating a uniform decision will make it possible
to switch between different txmode easier, both
for testing and for future features as well.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.h   |   2 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   8 --
 drivers/net/wireless/ath/ath10k/htt_tx.c |  30 +++---
 drivers/net/wireless/ath/ath10k/mac.c    | 155 ++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath10k/mac.h    |   8 ++
 5 files changed, 144 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index c1f43b0..b07d883 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -83,6 +83,8 @@ struct ath10k_skb_cb {
 	dma_addr_t paddr;
 	u8 eid;
 	u8 vdev_id;
+	enum ath10k_hw_txrx_mode txmode;
+	bool is_protected;
 
 	struct {
 		u8 tid;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 01a2b38..756fc19 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -637,14 +637,6 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
 	return 0;
 }
 
-struct rfc1042_hdr {
-	u8 llc_dsap;
-	u8 llc_ssap;
-	u8 llc_ctrl;
-	u8 snap_oui[3];
-	__be16 snap_type;
-} __packed;
-
 struct amsdu_subframe_hdr {
 	u8 dst[ETH_ALEN];
 	u8 src[ETH_ALEN];
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index cbd2bc9..5b2c61b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -420,9 +420,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	int res;
 	u8 flags0 = 0;
 	u16 msdu_id, flags1 = 0;
-	dma_addr_t paddr;
-	u32 frags_paddr;
-	bool use_frags;
+	dma_addr_t paddr = 0;
+	u32 frags_paddr = 0;
 
 	res = ath10k_htt_tx_inc_pending(htt);
 	if (res)
@@ -440,12 +439,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	prefetch_len = min(htt->prefetch_len, msdu->len);
 	prefetch_len = roundup(prefetch_len, 4);
 
-	/* Since HTT 3.0 there is no separate mgmt tx command. However in case
-	 * of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
-	 * fragment list host driver specifies directly frame pointer. */
-	use_frags = htt->target_version_major < 3 ||
-		    !ieee80211_is_mgmt(hdr->frame_control);
-
 	skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC,
 					   &paddr);
 	if (!skb_cb->htt.txbuf) {
@@ -466,7 +459,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 	if (res)
 		goto err_free_txbuf;
 
-	if (likely(use_frags)) {
+	switch (skb_cb->txmode) {
+	case ATH10K_HW_TXRX_RAW:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
+		flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+		/* pass through */
+	case ATH10K_HW_TXRX_ETHERNET:
 		frags = skb_cb->htt.txbuf->frags;
 
 		frags[0].paddr = __cpu_to_le32(skb_cb->paddr);
@@ -474,15 +472,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 		frags[1].paddr = 0;
 		frags[1].len = 0;
 
-		flags0 |= SM(ATH10K_HW_TXRX_NATIVE_WIFI,
-			     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+		flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
 
 		frags_paddr = skb_cb->htt.txbuf_paddr;
-	} else {
+		break;
+	case ATH10K_HW_TXRX_MGMT:
 		flags0 |= SM(ATH10K_HW_TXRX_MGMT,
 			     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+		flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
 
 		frags_paddr = skb_cb->paddr;
+		break;
 	}
 
 	/* Normally all commands go through HTC which manages tx credits for
@@ -508,11 +508,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 			prefetch_len);
 	skb_cb->htt.txbuf->htc_hdr.flags = 0;
 
-	if (!ieee80211_has_protected(hdr->frame_control))
+	if (!skb_cb->is_protected)
 		flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
 
-	flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
-
 	flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
 	flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
 	if (msdu->ip_summed == CHECKSUM_PARTIAL) {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 506e886..6b07ef6 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2519,6 +2519,43 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
 	return 0;
 }
 
+static enum ath10k_hw_txrx_mode
+ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
+		       struct sk_buff *skb)
+{
+	const struct ieee80211_hdr *hdr = (void *)skb->data;
+	__le16 fc = hdr->frame_control;
+
+	if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
+		return ATH10K_HW_TXRX_RAW;
+
+	if (ieee80211_is_mgmt(fc))
+		return ATH10K_HW_TXRX_MGMT;
+
+	/* Workaround:
+	 *
+	 * NullFunc frames are mostly used to ping if a client or AP are still
+	 * reachable and responsive. This implies tx status reports must be
+	 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
+	 * come to a conclusion that the other end disappeared and tear down
+	 * BSS connection or it can never disconnect from BSS/client (which is
+	 * the case).
+	 *
+	 * Firmware with HTT older than 3.0 delivers incorrect tx status for
+	 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
+	 * which seems to deliver correct tx reports for NullFunc frames. The
+	 * downside of using it is it ignores client powersave state so it can
+	 * end up disconnecting sleeping clients in AP mode. It should fix STA
+	 * mode though because AP don't sleep.
+	 */
+	if (ar->htt.target_version_major < 3 &&
+	    (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
+	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
+		return ATH10K_HW_TXRX_MGMT;
+
+	return ATH10K_HW_TXRX_NATIVE_WIFI;
+}
+
 /* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
  * Control in the header.
  */
@@ -2547,6 +2584,33 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
 	hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
 }
 
+static void ath10k_tx_h_8023(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+	struct rfc1042_hdr *rfc1042;
+	struct ethhdr *eth;
+	size_t hdrlen;
+	u8 da[ETH_ALEN];
+	u8 sa[ETH_ALEN];
+	__be16 type;
+
+	hdr = (void *)skb->data;
+	hdrlen = ieee80211_hdrlen(hdr->frame_control);
+	rfc1042 = (void *)skb->data + hdrlen;
+
+	ether_addr_copy(da, ieee80211_get_DA(hdr));
+	ether_addr_copy(sa, ieee80211_get_SA(hdr));
+	type = rfc1042->snap_type;
+
+	skb_pull(skb, hdrlen + sizeof(*rfc1042));
+	skb_push(skb, sizeof(*eth));
+
+	eth = (void *)skb->data;
+	ether_addr_copy(eth->h_dest, da);
+	ether_addr_copy(eth->h_source, sa);
+	eth->h_proto = type;
+}
+
 static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
 				       struct ieee80211_vif *vif,
 				       struct sk_buff *skb)
@@ -2583,45 +2647,51 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
 		 ar->htt.target_version_minor >= 4);
 }
 
-static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
+static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
 	int ret = 0;
 
-	if (ar->htt.target_version_major >= 3) {
-		/* Since HTT 3.0 there is no separate mgmt tx command */
-		ret = ath10k_htt_tx(&ar->htt, skb);
-		goto exit;
+	spin_lock_bh(&ar->data_lock);
+
+	if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
+		ath10k_warn(ar, "wmi mgmt tx queue is full\n");
+		ret = -ENOSPC;
+		goto unlock;
 	}
 
-	if (ieee80211_is_mgmt(hdr->frame_control)) {
-		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
-			     ar->fw_features)) {
-			if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >=
-			    ATH10K_MAX_NUM_MGMT_PENDING) {
-				ath10k_warn(ar, "reached WMI management transmit queue limit\n");
-				ret = -EBUSY;
-				goto exit;
-			}
+	__skb_queue_tail(q, skb);
+	ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
 
-			skb_queue_tail(&ar->wmi_mgmt_tx_queue, skb);
-			ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
-		} else {
-			ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-		}
-	} else if (!test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
-			     ar->fw_features) &&
-		   ieee80211_is_nullfunc(hdr->frame_control)) {
-		/* FW does not report tx status properly for NullFunc frames
-		 * unless they are sent through mgmt tx path. mac80211 sends
-		 * those frames when it detects link/beacon loss and depends
-		 * on the tx status to be correct. */
-		ret = ath10k_htt_mgmt_tx(&ar->htt, skb);
-	} else {
-		ret = ath10k_htt_tx(&ar->htt, skb);
+unlock:
+	spin_unlock_bh(&ar->data_lock);
+
+	return ret;
+}
+
+static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+	struct ath10k_htt *htt = &ar->htt;
+	int ret = 0;
+
+	switch (cb->txmode) {
+	case ATH10K_HW_TXRX_RAW:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
+	case ATH10K_HW_TXRX_ETHERNET:
+		ret = ath10k_htt_tx(htt, skb);
+		break;
+	case ATH10K_HW_TXRX_MGMT:
+		if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
+			     ar->fw_features))
+			ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
+		else if (ar->htt.target_version_major >= 3)
+			ret = ath10k_htt_tx(htt, skb);
+		else
+			ret = ath10k_htt_mgmt_tx(htt, skb);
+		break;
 	}
 
-exit:
 	if (ret) {
 		ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
 			    ret);
@@ -2694,7 +2764,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 		ar->offchan_tx_skb = skb;
 		spin_unlock_bh(&ar->data_lock);
 
-		ath10k_tx_htt(ar, skb);
+		ath10k_mac_tx(ar, skb);
 
 		ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
 						  3 * HZ);
@@ -2919,6 +2989,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_vif *vif = info->control.vif;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	__le16 fc = hdr->frame_control;
 
 	/* We should disable CCK RATE due to P2P */
 	if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
@@ -2927,12 +2998,26 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	ATH10K_SKB_CB(skb)->htt.is_offchan = false;
 	ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
 	ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
+	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, skb);
+	ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
 
-	/* it makes no sense to process injected frames like that */
-	if (vif && vif->type != NL80211_IFTYPE_MONITOR) {
+	switch (ATH10K_SKB_CB(skb)->txmode) {
+	case ATH10K_HW_TXRX_MGMT:
+	case ATH10K_HW_TXRX_NATIVE_WIFI:
 		ath10k_tx_h_nwifi(hw, skb);
 		ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
 		ath10k_tx_h_seq_no(vif, skb);
+		break;
+	case ATH10K_HW_TXRX_ETHERNET:
+		ath10k_tx_h_8023(skb);
+		break;
+	case ATH10K_HW_TXRX_RAW:
+		/* FIXME: Packet injection isn't implemented. It should be
+		 * doable with firmware 10.2 on qca988x.
+		 */
+		WARN_ON_ONCE(1);
+		ieee80211_free_txskb(hw, skb);
+		return;
 	}
 
 	if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
@@ -2954,7 +3039,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 		}
 	}
 
-	ath10k_tx_htt(ar, skb);
+	ath10k_mac_tx(ar, skb);
 }
 
 /* Must not be called with conf_mutex held as workers can use that also. */
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index 3b64d99..2cdf68d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -28,6 +28,14 @@ struct ath10k_generic_iter {
 	int ret;
 };
 
+struct rfc1042_hdr {
+	u8 llc_dsap;
+	u8 llc_ssap;
+	u8 llc_ctrl;
+	u8 snap_oui[3];
+	__be16 snap_type;
+} __packed;
+
 struct ath10k *ath10k_mac_create(size_t priv_size);
 void ath10k_mac_destroy(struct ath10k *ar);
 int ath10k_mac_register(struct ath10k *ar);
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 2/6] ath10k: make peer type configurable
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak, Marek Kwaczynski

Peer type was hardcoded to default value.
For future implementation it is required
to make is configurable.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c     | 17 +++++++++++------
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  8 +++++---
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |  5 +++--
 drivers/net/wireless/ath/ath10k/wmi.c     |  3 ++-
 drivers/net/wireless/ath/ath10k/wmi.h     |  6 ++++++
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 6b07ef6..866c948 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -428,7 +428,8 @@ static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
 	}
 }
 
-static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
+			      enum wmi_peer_type peer_type)
 {
 	int ret;
 
@@ -437,7 +438,7 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
 	if (ar->num_peers >= ar->max_num_peers)
 		return -ENOBUFS;
 
-	ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
+	ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
 	if (ret) {
 		ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
 			    addr, vdev_id, ret);
@@ -1288,7 +1289,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
 		return;
 	}
 
-	ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer);
+	ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer,
+				 WMI_PEER_TYPE_DEFAULT);
 	if (ret) {
 		ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
 			    self_peer, arvif->vdev_id, ret);
@@ -2753,7 +2755,8 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 				   peer_addr, vdev_id);
 
 		if (!peer) {
-			ret = ath10k_peer_create(ar, vdev_id, peer_addr);
+			ret = ath10k_peer_create(ar, vdev_id, peer_addr,
+						 WMI_PEER_TYPE_DEFAULT);
 			if (ret)
 				ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
 					    peer_addr, vdev_id, ret);
@@ -3660,7 +3663,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
 	}
 
 	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
-		ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
+		ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
+					 WMI_PEER_TYPE_DEFAULT);
 		if (ret) {
 			ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
 				    arvif->vdev_id, ret);
@@ -4456,7 +4460,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
-		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
+		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
+					 WMI_PEER_TYPE_DEFAULT);
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index f0a8b8d..28d042c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -83,7 +83,8 @@ struct wmi_ops {
 	struct sk_buff *(*gen_vdev_wmm_conf)(struct ath10k *ar, u32 vdev_id,
 					     const struct wmi_wmm_params_all_arg *arg);
 	struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id,
-					   const u8 peer_addr[ETH_ALEN]);
+					   const u8 peer_addr[ETH_ALEN],
+					   enum wmi_peer_type peer_type);
 	struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id,
 					   const u8 peer_addr[ETH_ALEN]);
 	struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id,
@@ -636,14 +637,15 @@ ath10k_wmi_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
 
 static inline int
 ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
-		       const u8 peer_addr[ETH_ALEN])
+		       const u8 peer_addr[ETH_ALEN],
+		       enum wmi_peer_type peer_type)
 {
 	struct sk_buff *skb;
 
 	if (!ar->wmi.ops->gen_peer_create)
 		return -EOPNOTSUPP;
 
-	skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr);
+	skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr, peer_type);
 	if (IS_ERR(skb))
 		return PTR_ERR(skb);
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 3eec042..a65e11b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1860,7 +1860,8 @@ ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
 
 static struct sk_buff *
 ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
-				  const u8 peer_addr[ETH_ALEN])
+				  const u8 peer_addr[ETH_ALEN],
+				  enum wmi_peer_type peer_type)
 {
 	struct wmi_tlv_peer_create_cmd *cmd;
 	struct wmi_tlv *tlv;
@@ -1875,7 +1876,7 @@ ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
 	tlv->len = __cpu_to_le16(sizeof(*cmd));
 	cmd = (void *)tlv->value;
 	cmd->vdev_id = __cpu_to_le32(vdev_id);
-	cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */
+	cmd->peer_type = __cpu_to_le32(peer_type);
 	ether_addr_copy(cmd->peer_addr.addr, peer_addr);
 
 	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 54430a1..e78dd2b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4510,7 +4510,8 @@ ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
 
 static struct sk_buff *
 ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
-			      const u8 peer_addr[ETH_ALEN])
+			      const u8 peer_addr[ETH_ALEN],
+			      enum wmi_peer_type peer_type)
 {
 	struct wmi_peer_create_cmd *cmd;
 	struct sk_buff *skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 938e652..3dddd47 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4333,6 +4333,12 @@ struct wmi_peer_create_cmd {
 	struct wmi_mac_addr peer_macaddr;
 } __packed;
 
+enum wmi_peer_type {
+	WMI_PEER_TYPE_DEFAULT = 0,
+	WMI_PEER_TYPE_BSS = 1,
+	WMI_PEER_TYPE_TDLS = 2,
+};
+
 struct wmi_peer_delete_cmd {
 	__le32 vdev_id;
 	struct wmi_mac_addr peer_macaddr;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 2/6] ath10k: make peer type configurable
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Kwaczynski, Marek Puzyniak

Peer type was hardcoded to default value.
For future implementation it is required
to make is configurable.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c     | 17 +++++++++++------
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  8 +++++---
 drivers/net/wireless/ath/ath10k/wmi-tlv.c |  5 +++--
 drivers/net/wireless/ath/ath10k/wmi.c     |  3 ++-
 drivers/net/wireless/ath/ath10k/wmi.h     |  6 ++++++
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 6b07ef6..866c948 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -428,7 +428,8 @@ static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
 	}
 }
 
-static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr,
+			      enum wmi_peer_type peer_type)
 {
 	int ret;
 
@@ -437,7 +438,7 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
 	if (ar->num_peers >= ar->max_num_peers)
 		return -ENOBUFS;
 
-	ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
+	ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
 	if (ret) {
 		ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
 			    addr, vdev_id, ret);
@@ -1288,7 +1289,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
 		return;
 	}
 
-	ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer);
+	ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer,
+				 WMI_PEER_TYPE_DEFAULT);
 	if (ret) {
 		ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
 			    self_peer, arvif->vdev_id, ret);
@@ -2753,7 +2755,8 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 				   peer_addr, vdev_id);
 
 		if (!peer) {
-			ret = ath10k_peer_create(ar, vdev_id, peer_addr);
+			ret = ath10k_peer_create(ar, vdev_id, peer_addr,
+						 WMI_PEER_TYPE_DEFAULT);
 			if (ret)
 				ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
 					    peer_addr, vdev_id, ret);
@@ -3660,7 +3663,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
 	}
 
 	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
-		ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
+		ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr,
+					 WMI_PEER_TYPE_DEFAULT);
 		if (ret) {
 			ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
 				    arvif->vdev_id, ret);
@@ -4456,7 +4460,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
-		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
+		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
+					 WMI_PEER_TYPE_DEFAULT);
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index f0a8b8d..28d042c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -83,7 +83,8 @@ struct wmi_ops {
 	struct sk_buff *(*gen_vdev_wmm_conf)(struct ath10k *ar, u32 vdev_id,
 					     const struct wmi_wmm_params_all_arg *arg);
 	struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id,
-					   const u8 peer_addr[ETH_ALEN]);
+					   const u8 peer_addr[ETH_ALEN],
+					   enum wmi_peer_type peer_type);
 	struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id,
 					   const u8 peer_addr[ETH_ALEN]);
 	struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id,
@@ -636,14 +637,15 @@ ath10k_wmi_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
 
 static inline int
 ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
-		       const u8 peer_addr[ETH_ALEN])
+		       const u8 peer_addr[ETH_ALEN],
+		       enum wmi_peer_type peer_type)
 {
 	struct sk_buff *skb;
 
 	if (!ar->wmi.ops->gen_peer_create)
 		return -EOPNOTSUPP;
 
-	skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr);
+	skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr, peer_type);
 	if (IS_ERR(skb))
 		return PTR_ERR(skb);
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 3eec042..a65e11b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1860,7 +1860,8 @@ ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
 
 static struct sk_buff *
 ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
-				  const u8 peer_addr[ETH_ALEN])
+				  const u8 peer_addr[ETH_ALEN],
+				  enum wmi_peer_type peer_type)
 {
 	struct wmi_tlv_peer_create_cmd *cmd;
 	struct wmi_tlv *tlv;
@@ -1875,7 +1876,7 @@ ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
 	tlv->len = __cpu_to_le16(sizeof(*cmd));
 	cmd = (void *)tlv->value;
 	cmd->vdev_id = __cpu_to_le32(vdev_id);
-	cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */
+	cmd->peer_type = __cpu_to_le32(peer_type);
 	ether_addr_copy(cmd->peer_addr.addr, peer_addr);
 
 	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 54430a1..e78dd2b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4510,7 +4510,8 @@ ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
 
 static struct sk_buff *
 ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
-			      const u8 peer_addr[ETH_ALEN])
+			      const u8 peer_addr[ETH_ALEN],
+			      enum wmi_peer_type peer_type)
 {
 	struct wmi_peer_create_cmd *cmd;
 	struct sk_buff *skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 938e652..3dddd47 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4333,6 +4333,12 @@ struct wmi_peer_create_cmd {
 	struct wmi_mac_addr peer_macaddr;
 } __packed;
 
+enum wmi_peer_type {
+	WMI_PEER_TYPE_DEFAULT = 0,
+	WMI_PEER_TYPE_BSS = 1,
+	WMI_PEER_TYPE_TDLS = 2,
+};
+
 struct wmi_peer_delete_cmd {
 	__le32 vdev_id;
 	struct wmi_mac_addr peer_macaddr;
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 3/6] ath10k: store max tdls vdevs that fw can handle
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

Currently number of tdls vdevs supported by firmware
is hardcoded. For future usage it is stored in ath10k
structure based on defined value.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.c    | 1 +
 drivers/net/wireless/ath/ath10k/core.h    | 1 +
 drivers/net/wireless/ath/ath10k/hw.h      | 1 +
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +-
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index c0e454b..47a3c55 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -971,6 +971,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
 		ar->max_num_peers = TARGET_TLV_NUM_PEERS;
 		ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
 		ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
+		ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
 		ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
 		break;
 	case ATH10K_FW_WMI_OP_VERSION_UNSET:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index b07d883..7d4f9c9 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -638,6 +638,7 @@ struct ath10k {
 	int max_num_peers;
 	int max_num_stations;
 	int max_num_vdevs;
+	int max_num_tdls_vdevs;
 
 	struct work_struct offchan_tx_work;
 	struct sk_buff_head offchan_tx_queue;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 7f04645..3ae2dbf 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -261,6 +261,7 @@ struct ath10k_pktlog_hdr {
 #define TARGET_TLV_NUM_PEERS			((TARGET_TLV_NUM_STATIONS) + \
 						 (TARGET_TLV_NUM_VDEVS) + \
 						 2)
+#define TARGET_TLV_NUM_TDLS_VDEVS		1
 #define TARGET_TLV_NUM_TIDS			((TARGET_TLV_NUM_PEERS) * 2)
 #define TARGET_TLV_NUM_MSDU_DESC		(1024 + 32)
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index a65e11b..80e882b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1271,7 +1271,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
 	cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
 	cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
 	cfg->max_frag_entries = __cpu_to_le32(2);
-	cfg->num_tdls_vdevs = __cpu_to_le32(1);
+	cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
 	cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
 	cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
 	cfg->num_multicast_filter_entries = __cpu_to_le32(5);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 3/6] ath10k: store max tdls vdevs that fw can handle
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

Currently number of tdls vdevs supported by firmware
is hardcoded. For future usage it is stored in ath10k
structure based on defined value.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.c    | 1 +
 drivers/net/wireless/ath/ath10k/core.h    | 1 +
 drivers/net/wireless/ath/ath10k/hw.h      | 1 +
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +-
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index c0e454b..47a3c55 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -971,6 +971,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
 		ar->max_num_peers = TARGET_TLV_NUM_PEERS;
 		ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
 		ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
+		ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
 		ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
 		break;
 	case ATH10K_FW_WMI_OP_VERSION_UNSET:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index b07d883..7d4f9c9 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -638,6 +638,7 @@ struct ath10k {
 	int max_num_peers;
 	int max_num_stations;
 	int max_num_vdevs;
+	int max_num_tdls_vdevs;
 
 	struct work_struct offchan_tx_work;
 	struct sk_buff_head offchan_tx_queue;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 7f04645..3ae2dbf 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -261,6 +261,7 @@ struct ath10k_pktlog_hdr {
 #define TARGET_TLV_NUM_PEERS			((TARGET_TLV_NUM_STATIONS) + \
 						 (TARGET_TLV_NUM_VDEVS) + \
 						 2)
+#define TARGET_TLV_NUM_TDLS_VDEVS		1
 #define TARGET_TLV_NUM_TIDS			((TARGET_TLV_NUM_PEERS) * 2)
 #define TARGET_TLV_NUM_MSDU_DESC		(1024 + 32)
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index a65e11b..80e882b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1271,7 +1271,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
 	cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
 	cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
 	cfg->max_frag_entries = __cpu_to_le32(2);
-	cfg->num_tdls_vdevs = __cpu_to_le32(1);
+	cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
 	cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
 	cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
 	cfg->num_multicast_filter_entries = __cpu_to_le32(5);
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 4/6] ath10k: update station counting
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

Currently station counting functions
(inc_num_stations/dec_num_stations) does not handle
tdls type of stations. Tdls station should be counted
because it consumes peer in firmware. Only not tdls
stations are excluded from this counting.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 866c948..3c25507 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4386,14 +4386,14 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
 	mutex_unlock(&ar->conf_mutex);
 }
 
-static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif)
+static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
+				       struct ieee80211_sta *sta)
 {
 	struct ath10k *ar = arvif->ar;
 
 	lockdep_assert_held(&ar->conf_mutex);
 
-	if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
 		return 0;
 
 	if (ar->num_stations >= ar->max_num_stations)
@@ -4404,14 +4404,14 @@ static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif)
 	return 0;
 }
 
-static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif)
+static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
+					struct ieee80211_sta *sta)
 {
 	struct ath10k *ar = arvif->ar;
 
 	lockdep_assert_held(&ar->conf_mutex);
 
-	if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
 		return;
 
 	ar->num_stations--;
@@ -4453,7 +4453,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			   ar->num_stations + 1, ar->max_num_stations,
 			   ar->num_peers + 1, ar->max_num_peers);
 
-		ret = ath10k_mac_inc_num_stations(arvif);
+		ret = ath10k_mac_inc_num_stations(arvif, sta);
 		if (ret) {
 			ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
 				    ar->max_num_stations);
@@ -4465,7 +4465,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
-			ath10k_mac_dec_num_stations(arvif);
+			ath10k_mac_dec_num_stations(arvif, sta);
 			goto exit;
 		}
 
@@ -4478,7 +4478,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 					    arvif->vdev_id, ret);
 				WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id,
 							   sta->addr));
-				ath10k_mac_dec_num_stations(arvif);
+				ath10k_mac_dec_num_stations(arvif, sta);
 				goto exit;
 			}
 
@@ -4509,7 +4509,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
 
-		ath10k_mac_dec_num_stations(arvif);
+		ath10k_mac_dec_num_stations(arvif, sta);
 	} else if (old_state == IEEE80211_STA_AUTH &&
 		   new_state == IEEE80211_STA_ASSOC &&
 		   (vif->type == NL80211_IFTYPE_AP ||
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 4/6] ath10k: update station counting
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

Currently station counting functions
(inc_num_stations/dec_num_stations) does not handle
tdls type of stations. Tdls station should be counted
because it consumes peer in firmware. Only not tdls
stations are excluded from this counting.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 866c948..3c25507 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4386,14 +4386,14 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
 	mutex_unlock(&ar->conf_mutex);
 }
 
-static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif)
+static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
+				       struct ieee80211_sta *sta)
 {
 	struct ath10k *ar = arvif->ar;
 
 	lockdep_assert_held(&ar->conf_mutex);
 
-	if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
 		return 0;
 
 	if (ar->num_stations >= ar->max_num_stations)
@@ -4404,14 +4404,14 @@ static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif)
 	return 0;
 }
 
-static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif)
+static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
+					struct ieee80211_sta *sta)
 {
 	struct ath10k *ar = arvif->ar;
 
 	lockdep_assert_held(&ar->conf_mutex);
 
-	if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
 		return;
 
 	ar->num_stations--;
@@ -4453,7 +4453,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			   ar->num_stations + 1, ar->max_num_stations,
 			   ar->num_peers + 1, ar->max_num_peers);
 
-		ret = ath10k_mac_inc_num_stations(arvif);
+		ret = ath10k_mac_inc_num_stations(arvif, sta);
 		if (ret) {
 			ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
 				    ar->max_num_stations);
@@ -4465,7 +4465,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
-			ath10k_mac_dec_num_stations(arvif);
+			ath10k_mac_dec_num_stations(arvif, sta);
 			goto exit;
 		}
 
@@ -4478,7 +4478,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 					    arvif->vdev_id, ret);
 				WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id,
 							   sta->addr));
-				ath10k_mac_dec_num_stations(arvif);
+				ath10k_mac_dec_num_stations(arvif, sta);
 				goto exit;
 			}
 
@@ -4509,7 +4509,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
 
-		ath10k_mac_dec_num_stations(arvif);
+		ath10k_mac_dec_num_stations(arvif, sta);
 	} else if (old_state == IEEE80211_STA_AUTH &&
 		   new_state == IEEE80211_STA_ASSOC &&
 		   (vif->type == NL80211_IFTYPE_AP ||
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

As a part of tdls implementation introduce
tdls related wmi data structures, constant
values and functions.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
 4 files changed, 285 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 28d042c..1e444a0 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -151,6 +151,13 @@ struct wmi_ops {
 					      u32 num_ac);
 	struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar,
 					     const struct wmi_sta_keepalive_arg *arg);
+	struct sk_buff *(*gen_update_fw_tdls_state)(struct ath10k *ar,
+						    u32 vdev_id,
+						    enum wmi_tdls_state state);
+	struct sk_buff *(*gen_tdls_peer_update)(struct ath10k *ar,
+						const struct wmi_tdls_peer_update_cmd_arg *arg,
+						const struct wmi_tdls_peer_capab_arg *cap,
+						const struct wmi_channel_arg *chan);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1074,4 +1081,39 @@ ath10k_wmi_sta_keepalive(struct ath10k *ar,
 	return ath10k_wmi_cmd_send(ar, skb, cmd_id);
 }
 
+static inline int
+ath10k_wmi_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
+				enum wmi_tdls_state state)
+{
+	struct sk_buff *skb;
+
+	if (!ar->wmi.ops->gen_update_fw_tdls_state)
+		return -EOPNOTSUPP;
+
+	skb = ar->wmi.ops->gen_update_fw_tdls_state(ar, vdev_id, state);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->tdls_set_state_cmdid);
+}
+
+static inline int
+ath10k_wmi_tdls_peer_update(struct ath10k *ar,
+			    const struct wmi_tdls_peer_update_cmd_arg *arg,
+			    const struct wmi_tdls_peer_capab_arg *cap,
+			    const struct wmi_channel_arg *chan)
+{
+	struct sk_buff *skb;
+
+	if (!ar->wmi.ops->gen_tdls_peer_update)
+		return -EOPNOTSUPP;
+
+	skb = ar->wmi.ops->gen_tdls_peer_update(ar, arg, cap, chan);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	return ath10k_wmi_cmd_send(ar, skb,
+				   ar->wmi.cmd->tdls_peer_update_cmdid);
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 80e882b..7b62f0d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2564,6 +2564,155 @@ ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
 	return skb;
 }
 
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
+					   enum wmi_tdls_state state)
+{
+	struct wmi_tdls_set_state_cmd *cmd;
+	struct wmi_tlv *tlv;
+	struct sk_buff *skb;
+	void *ptr;
+	size_t len;
+	/* Set to options from wmi_tlv_tdls_options,
+	 * for now none of them are enabled.
+	 */
+	u32 options = 0;
+
+	len = sizeof(*tlv) + sizeof(*cmd);
+	skb = ath10k_wmi_alloc_skb(ar, len);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	ptr = (void *)skb->data;
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
+	tlv->len = __cpu_to_le16(sizeof(*cmd));
+
+	cmd = (void *)tlv->value;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+	cmd->state = __cpu_to_le32(state);
+	cmd->notification_interval_ms = __cpu_to_le32(5000);
+	cmd->tx_discovery_threshold = __cpu_to_le32(100);
+	cmd->tx_teardown_threshold = __cpu_to_le32(5);
+	cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
+	cmd->rssi_delta = __cpu_to_le32(-20);
+	cmd->tdls_options = __cpu_to_le32(options);
+	cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
+	cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
+	cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
+	cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
+	cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*cmd);
+
+	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
+		   state, vdev_id);
+	return skb;
+}
+
+static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
+{
+	u32 peer_qos = 0;
+
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
+
+	peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
+
+	return peer_qos;
+}
+
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
+				       const struct wmi_tdls_peer_update_cmd_arg *arg,
+				       const struct wmi_tdls_peer_capab_arg *cap,
+				       const struct wmi_channel_arg *chan_arg)
+{
+	struct wmi_tdls_peer_update_cmd *cmd;
+	struct wmi_tdls_peer_capab *peer_cap;
+	struct wmi_channel *chan;
+	struct wmi_tlv *tlv;
+	struct sk_buff *skb;
+	u32 peer_qos;
+	void *ptr;
+	int len;
+	int i;
+
+	len = sizeof(*tlv) + sizeof(*cmd) +
+	      sizeof(*tlv) + sizeof(*peer_cap) +
+	      sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
+
+	skb = ath10k_wmi_alloc_skb(ar, len);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	ptr = (void *)skb->data;
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
+	tlv->len = __cpu_to_le16(sizeof(*cmd));
+
+	cmd = (void *)tlv->value;
+	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
+	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
+	cmd->peer_state = __cpu_to_le32(arg->peer_state);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*cmd);
+
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
+	tlv->len = __cpu_to_le16(sizeof(*peer_cap));
+	peer_cap = (void *)tlv->value;
+	peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
+						   cap->peer_max_sp);
+	peer_cap->peer_qos = __cpu_to_le32(peer_qos);
+	peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
+	peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
+	peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
+	peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
+	peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
+	peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
+
+	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
+		peer_cap->peer_operclass[i] = cap->peer_operclass[i];
+
+	peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
+	peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
+	peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*peer_cap);
+
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
+	tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
+
+	ptr += sizeof(*tlv);
+
+	for (i = 0; i < cap->peer_chan_len; i++) {
+		tlv = ptr;
+		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
+		tlv->len = __cpu_to_le16(sizeof(*chan));
+		chan = (void *)tlv->value;
+		ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
+
+		ptr += sizeof(*tlv);
+		ptr += sizeof(*chan);
+	}
+
+	ath10k_dbg(ar, ATH10K_DBG_WMI,
+		   "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
+		   arg->vdev_id, arg->peer_state, cap->peer_chan_len);
+	return skb;
+}
+
 /****************/
 /* TLV mappings */
 /****************/
@@ -2688,6 +2837,8 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = {
 	.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
 	.pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
 	.vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
+	.tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
+	.tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
 };
 
 static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
@@ -2861,6 +3012,8 @@ static const struct wmi_ops wmi_tlv_ops = {
 	.gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
 	.gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
 	.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
+	.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
+	.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
 };
 
 /************/
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 06b37b2..03e2584 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1464,6 +1464,59 @@ struct wmi_tlv_roam_ev {
 	__le32 rssi;
 } __packed;
 
+/* TDLS Options */
+enum wmi_tlv_tdls_options {
+	WMI_TLV_TDLS_OFFCHAN_EN = BIT(0),
+	WMI_TLV_TDLS_BUFFER_STA_EN = BIT(1),
+	WMI_TLV_TDLS_SLEEP_STA_EN = BIT(2),
+};
+
+struct wmi_tdls_set_state_cmd {
+	__le32 vdev_id;
+	__le32 state;
+	__le32 notification_interval_ms;
+	__le32 tx_discovery_threshold;
+	__le32 tx_teardown_threshold;
+	__le32 rssi_teardown_threshold;
+	__le32 rssi_delta;
+	__le32 tdls_options;
+	__le32 tdls_peer_traffic_ind_window;
+	__le32 tdls_peer_traffic_response_timeout_ms;
+	__le32 tdls_puapsd_mask;
+	__le32 tdls_puapsd_inactivity_time_ms;
+	__le32 tdls_puapsd_rx_frame_threshold;
+} __packed;
+
+struct wmi_tdls_peer_update_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 peer_state;
+} __packed;
+
+enum {
+	WMI_TLV_TDLS_PEER_QOS_AC_VO = BIT(0),
+	WMI_TLV_TDLS_PEER_QOS_AC_VI = BIT(1),
+	WMI_TLV_TDLS_PEER_QOS_AC_BK = BIT(2),
+	WMI_TLV_TDLS_PEER_QOS_AC_BE = BIT(3),
+};
+
+#define WMI_TLV_TDLS_PEER_SP_MASK	0x60
+#define WMI_TLV_TDLS_PEER_SP_LSB	5
+
+struct wmi_tdls_peer_capab {
+	__le32 peer_qos;
+	__le32 buff_sta_support;
+	__le32 off_chan_support;
+	__le32 peer_curr_operclass;
+	__le32 self_curr_operclass;
+	__le32 peer_chan_len;
+	__le32 peer_operclass_len;
+	u8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES];
+	__le32 is_peer_responder;
+	__le32 pref_offchan_num;
+	__le32 pref_offchan_bw;
+} __packed;
+
 void ath10k_wmi_tlv_attach(struct ath10k *ar);
 
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3dddd47..f25ce03 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -552,6 +552,8 @@ struct wmi_cmd_map {
 	u32 gpio_output_cmdid;
 	u32 pdev_get_temperature_cmdid;
 	u32 vdev_set_wmm_params_cmdid;
+	u32 tdls_set_state_cmdid;
+	u32 tdls_peer_update_cmdid;
 };
 
 /*
@@ -4890,6 +4892,41 @@ struct wmi_pdev_temperature_event {
 	__le32 temperature;
 } __packed;
 
+enum wmi_tdls_state {
+	WMI_TDLS_DISABLE,
+	WMI_TDLS_ENABLE_PASSIVE,
+	WMI_TDLS_ENABLE_ACTIVE,
+};
+
+enum wmi_tdls_peer_state {
+	WMI_TDLS_PEER_STATE_PEERING,
+	WMI_TDLS_PEER_STATE_CONNECTED,
+	WMI_TDLS_PEER_STATE_TEARDOWN,
+};
+
+struct wmi_tdls_peer_update_cmd_arg {
+	u32 vdev_id;
+	enum wmi_tdls_peer_state peer_state;
+	u8 addr[ETH_ALEN];
+};
+
+#define WMI_TDLS_MAX_SUPP_OPER_CLASSES 32
+
+struct wmi_tdls_peer_capab_arg {
+	u8 peer_uapsd_queues;
+	u8 peer_max_sp;
+	u32 buff_sta_support;
+	u32 off_chan_support;
+	u32 peer_curr_operclass;
+	u32 self_curr_operclass;
+	u32 peer_chan_len;
+	u32 peer_operclass_len;
+	u8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES];
+	u32 is_peer_responder;
+	u32 pref_offchan_num;
+	u32 pref_offchan_bw;
+};
+
 struct ath10k;
 struct ath10k_vif;
 struct ath10k_fw_stats_pdev;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak

As a part of tdls implementation introduce
tdls related wmi data structures, constant
values and functions.

Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
 drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
 4 files changed, 285 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 28d042c..1e444a0 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -151,6 +151,13 @@ struct wmi_ops {
 					      u32 num_ac);
 	struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar,
 					     const struct wmi_sta_keepalive_arg *arg);
+	struct sk_buff *(*gen_update_fw_tdls_state)(struct ath10k *ar,
+						    u32 vdev_id,
+						    enum wmi_tdls_state state);
+	struct sk_buff *(*gen_tdls_peer_update)(struct ath10k *ar,
+						const struct wmi_tdls_peer_update_cmd_arg *arg,
+						const struct wmi_tdls_peer_capab_arg *cap,
+						const struct wmi_channel_arg *chan);
 };
 
 int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1074,4 +1081,39 @@ ath10k_wmi_sta_keepalive(struct ath10k *ar,
 	return ath10k_wmi_cmd_send(ar, skb, cmd_id);
 }
 
+static inline int
+ath10k_wmi_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
+				enum wmi_tdls_state state)
+{
+	struct sk_buff *skb;
+
+	if (!ar->wmi.ops->gen_update_fw_tdls_state)
+		return -EOPNOTSUPP;
+
+	skb = ar->wmi.ops->gen_update_fw_tdls_state(ar, vdev_id, state);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->tdls_set_state_cmdid);
+}
+
+static inline int
+ath10k_wmi_tdls_peer_update(struct ath10k *ar,
+			    const struct wmi_tdls_peer_update_cmd_arg *arg,
+			    const struct wmi_tdls_peer_capab_arg *cap,
+			    const struct wmi_channel_arg *chan)
+{
+	struct sk_buff *skb;
+
+	if (!ar->wmi.ops->gen_tdls_peer_update)
+		return -EOPNOTSUPP;
+
+	skb = ar->wmi.ops->gen_tdls_peer_update(ar, arg, cap, chan);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	return ath10k_wmi_cmd_send(ar, skb,
+				   ar->wmi.cmd->tdls_peer_update_cmdid);
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 80e882b..7b62f0d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2564,6 +2564,155 @@ ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
 	return skb;
 }
 
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_update_fw_tdls_state(struct ath10k *ar, u32 vdev_id,
+					   enum wmi_tdls_state state)
+{
+	struct wmi_tdls_set_state_cmd *cmd;
+	struct wmi_tlv *tlv;
+	struct sk_buff *skb;
+	void *ptr;
+	size_t len;
+	/* Set to options from wmi_tlv_tdls_options,
+	 * for now none of them are enabled.
+	 */
+	u32 options = 0;
+
+	len = sizeof(*tlv) + sizeof(*cmd);
+	skb = ath10k_wmi_alloc_skb(ar, len);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	ptr = (void *)skb->data;
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD);
+	tlv->len = __cpu_to_le16(sizeof(*cmd));
+
+	cmd = (void *)tlv->value;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+	cmd->state = __cpu_to_le32(state);
+	cmd->notification_interval_ms = __cpu_to_le32(5000);
+	cmd->tx_discovery_threshold = __cpu_to_le32(100);
+	cmd->tx_teardown_threshold = __cpu_to_le32(5);
+	cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
+	cmd->rssi_delta = __cpu_to_le32(-20);
+	cmd->tdls_options = __cpu_to_le32(options);
+	cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
+	cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
+	cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
+	cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
+	cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*cmd);
+
+	ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv update fw tdls state %d for vdev %i\n",
+		   state, vdev_id);
+	return skb;
+}
+
+static u32 ath10k_wmi_tlv_prepare_peer_qos(u8 uapsd_queues, u8 sp)
+{
+	u32 peer_qos = 0;
+
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VO;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_VI;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BK;
+	if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
+		peer_qos |= WMI_TLV_TDLS_PEER_QOS_AC_BE;
+
+	peer_qos |= SM(sp, WMI_TLV_TDLS_PEER_SP);
+
+	return peer_qos;
+}
+
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
+				       const struct wmi_tdls_peer_update_cmd_arg *arg,
+				       const struct wmi_tdls_peer_capab_arg *cap,
+				       const struct wmi_channel_arg *chan_arg)
+{
+	struct wmi_tdls_peer_update_cmd *cmd;
+	struct wmi_tdls_peer_capab *peer_cap;
+	struct wmi_channel *chan;
+	struct wmi_tlv *tlv;
+	struct sk_buff *skb;
+	u32 peer_qos;
+	void *ptr;
+	int len;
+	int i;
+
+	len = sizeof(*tlv) + sizeof(*cmd) +
+	      sizeof(*tlv) + sizeof(*peer_cap) +
+	      sizeof(*tlv) + cap->peer_chan_len * sizeof(*chan);
+
+	skb = ath10k_wmi_alloc_skb(ar, len);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	ptr = (void *)skb->data;
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD);
+	tlv->len = __cpu_to_le16(sizeof(*cmd));
+
+	cmd = (void *)tlv->value;
+	cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
+	ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
+	cmd->peer_state = __cpu_to_le32(arg->peer_state);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*cmd);
+
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES);
+	tlv->len = __cpu_to_le16(sizeof(*peer_cap));
+	peer_cap = (void *)tlv->value;
+	peer_qos = ath10k_wmi_tlv_prepare_peer_qos(cap->peer_uapsd_queues,
+						   cap->peer_max_sp);
+	peer_cap->peer_qos = __cpu_to_le32(peer_qos);
+	peer_cap->buff_sta_support = __cpu_to_le32(cap->buff_sta_support);
+	peer_cap->off_chan_support = __cpu_to_le32(cap->off_chan_support);
+	peer_cap->peer_curr_operclass = __cpu_to_le32(cap->peer_curr_operclass);
+	peer_cap->self_curr_operclass = __cpu_to_le32(cap->self_curr_operclass);
+	peer_cap->peer_chan_len = __cpu_to_le32(cap->peer_chan_len);
+	peer_cap->peer_operclass_len = __cpu_to_le32(cap->peer_operclass_len);
+
+	for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++)
+		peer_cap->peer_operclass[i] = cap->peer_operclass[i];
+
+	peer_cap->is_peer_responder = __cpu_to_le32(cap->is_peer_responder);
+	peer_cap->pref_offchan_num = __cpu_to_le32(cap->pref_offchan_num);
+	peer_cap->pref_offchan_bw = __cpu_to_le32(cap->pref_offchan_bw);
+
+	ptr += sizeof(*tlv);
+	ptr += sizeof(*peer_cap);
+
+	tlv = ptr;
+	tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
+	tlv->len = __cpu_to_le16(cap->peer_chan_len * sizeof(*chan));
+
+	ptr += sizeof(*tlv);
+
+	for (i = 0; i < cap->peer_chan_len; i++) {
+		tlv = ptr;
+		tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
+		tlv->len = __cpu_to_le16(sizeof(*chan));
+		chan = (void *)tlv->value;
+		ath10k_wmi_put_wmi_channel(chan, &chan_arg[i]);
+
+		ptr += sizeof(*tlv);
+		ptr += sizeof(*chan);
+	}
+
+	ath10k_dbg(ar, ATH10K_DBG_WMI,
+		   "wmi tlv tdls peer update vdev %i state %d n_chans %u\n",
+		   arg->vdev_id, arg->peer_state, cap->peer_chan_len);
+	return skb;
+}
+
 /****************/
 /* TLV mappings */
 /****************/
@@ -2688,6 +2837,8 @@ static struct wmi_cmd_map wmi_tlv_cmd_map = {
 	.gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
 	.pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
 	.vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
+	.tdls_set_state_cmdid = WMI_TLV_TDLS_SET_STATE_CMDID,
+	.tdls_peer_update_cmdid = WMI_TLV_TDLS_PEER_UPDATE_CMDID,
 };
 
 static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
@@ -2861,6 +3012,8 @@ static const struct wmi_ops wmi_tlv_ops = {
 	.gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
 	.gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
 	.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
+	.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
+	.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
 };
 
 /************/
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 06b37b2..03e2584 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1464,6 +1464,59 @@ struct wmi_tlv_roam_ev {
 	__le32 rssi;
 } __packed;
 
+/* TDLS Options */
+enum wmi_tlv_tdls_options {
+	WMI_TLV_TDLS_OFFCHAN_EN = BIT(0),
+	WMI_TLV_TDLS_BUFFER_STA_EN = BIT(1),
+	WMI_TLV_TDLS_SLEEP_STA_EN = BIT(2),
+};
+
+struct wmi_tdls_set_state_cmd {
+	__le32 vdev_id;
+	__le32 state;
+	__le32 notification_interval_ms;
+	__le32 tx_discovery_threshold;
+	__le32 tx_teardown_threshold;
+	__le32 rssi_teardown_threshold;
+	__le32 rssi_delta;
+	__le32 tdls_options;
+	__le32 tdls_peer_traffic_ind_window;
+	__le32 tdls_peer_traffic_response_timeout_ms;
+	__le32 tdls_puapsd_mask;
+	__le32 tdls_puapsd_inactivity_time_ms;
+	__le32 tdls_puapsd_rx_frame_threshold;
+} __packed;
+
+struct wmi_tdls_peer_update_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 peer_state;
+} __packed;
+
+enum {
+	WMI_TLV_TDLS_PEER_QOS_AC_VO = BIT(0),
+	WMI_TLV_TDLS_PEER_QOS_AC_VI = BIT(1),
+	WMI_TLV_TDLS_PEER_QOS_AC_BK = BIT(2),
+	WMI_TLV_TDLS_PEER_QOS_AC_BE = BIT(3),
+};
+
+#define WMI_TLV_TDLS_PEER_SP_MASK	0x60
+#define WMI_TLV_TDLS_PEER_SP_LSB	5
+
+struct wmi_tdls_peer_capab {
+	__le32 peer_qos;
+	__le32 buff_sta_support;
+	__le32 off_chan_support;
+	__le32 peer_curr_operclass;
+	__le32 self_curr_operclass;
+	__le32 peer_chan_len;
+	__le32 peer_operclass_len;
+	u8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES];
+	__le32 is_peer_responder;
+	__le32 pref_offchan_num;
+	__le32 pref_offchan_bw;
+} __packed;
+
 void ath10k_wmi_tlv_attach(struct ath10k *ar);
 
 #endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3dddd47..f25ce03 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -552,6 +552,8 @@ struct wmi_cmd_map {
 	u32 gpio_output_cmdid;
 	u32 pdev_get_temperature_cmdid;
 	u32 vdev_set_wmm_params_cmdid;
+	u32 tdls_set_state_cmdid;
+	u32 tdls_peer_update_cmdid;
 };
 
 /*
@@ -4890,6 +4892,41 @@ struct wmi_pdev_temperature_event {
 	__le32 temperature;
 } __packed;
 
+enum wmi_tdls_state {
+	WMI_TDLS_DISABLE,
+	WMI_TDLS_ENABLE_PASSIVE,
+	WMI_TDLS_ENABLE_ACTIVE,
+};
+
+enum wmi_tdls_peer_state {
+	WMI_TDLS_PEER_STATE_PEERING,
+	WMI_TDLS_PEER_STATE_CONNECTED,
+	WMI_TDLS_PEER_STATE_TEARDOWN,
+};
+
+struct wmi_tdls_peer_update_cmd_arg {
+	u32 vdev_id;
+	enum wmi_tdls_peer_state peer_state;
+	u8 addr[ETH_ALEN];
+};
+
+#define WMI_TDLS_MAX_SUPP_OPER_CLASSES 32
+
+struct wmi_tdls_peer_capab_arg {
+	u8 peer_uapsd_queues;
+	u8 peer_max_sp;
+	u32 buff_sta_support;
+	u32 off_chan_support;
+	u32 peer_curr_operclass;
+	u32 self_curr_operclass;
+	u32 peer_chan_len;
+	u32 peer_operclass_len;
+	u8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES];
+	u32 is_peer_responder;
+	u32 pref_offchan_num;
+	u32 pref_offchan_bw;
+};
+
 struct ath10k;
 struct ath10k_vif;
 struct ath10k_fw_stats_pdev;
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 6/6] ath10k: introduce basic tdls functionality
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-20 11:02   ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak, Michal Kazior, Marek Kwaczynski

This patch introduces tdls without tdls peer uapsd
and tdls channel switching.
Transmitting tdls data frames works only for ethernet
type frames, that's why data addressed to tdls sta
is in ethernet format.

This patch depends on:
mac80211: initialize rate control earlier for tdls station

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 205 ++++++++++++++++++++++++++++++++--
 1 file changed, 197 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3c25507..7368a04 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -582,6 +582,38 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
 	ar->num_stations = 0;
 }
 
+static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
+				       struct ieee80211_sta *sta,
+				       enum wmi_tdls_peer_state state)
+{
+	int ret;
+	struct wmi_tdls_peer_update_cmd_arg arg = {};
+	struct wmi_tdls_peer_capab_arg cap = {};
+	struct wmi_channel_arg chan_arg = {};
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	arg.vdev_id = vdev_id;
+	arg.peer_state = state;
+	ether_addr_copy(arg.addr, sta->addr);
+
+	cap.peer_max_sp = sta->max_sp;
+	cap.peer_uapsd_queues = sta->uapsd_queues;
+
+	if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
+	    !sta->tdls_initiator)
+		cap.is_peer_responder = 1;
+
+	ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
+	if (ret) {
+		ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
+			    arg.addr, vdev_id, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /************************/
 /* Interface management */
 /************************/
@@ -2523,7 +2555,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
 
 static enum ath10k_hw_txrx_mode
 ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
-		       struct sk_buff *skb)
+		       struct ieee80211_sta *sta, struct sk_buff *skb)
 {
 	const struct ieee80211_hdr *hdr = (void *)skb->data;
 	__le16 fc = hdr->frame_control;
@@ -2555,6 +2587,15 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
 	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
 		return ATH10K_HW_TXRX_MGMT;
 
+	/* Workaround:
+	 *
+	 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
+	 * NativeWifi txmode - it selects AP key instead of peer key. It seems
+	 * to work with Ethernet txmode so use it.
+	 */
+	if (ieee80211_is_data_present(fc) && sta && sta->tdls)
+		return ATH10K_HW_TXRX_ETHERNET;
+
 	return ATH10K_HW_TXRX_NATIVE_WIFI;
 }
 
@@ -2991,6 +3032,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	struct ath10k *ar = hw->priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_vif *vif = info->control.vif;
+	struct ieee80211_sta *sta = control->sta;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	__le16 fc = hdr->frame_control;
 
@@ -3001,7 +3043,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	ATH10K_SKB_CB(skb)->htt.is_offchan = false;
 	ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
 	ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
-	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, skb);
+	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
 	ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
 
 	switch (ATH10K_SKB_CB(skb)->txmode) {
@@ -4417,6 +4459,59 @@ static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
 	ar->num_stations--;
 }
 
+struct ath10k_mac_tdls_iter_data {
+	u32 num_tdls_stations;
+	struct ieee80211_vif *curr_vif;
+};
+
+static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
+						    struct ieee80211_sta *sta)
+{
+	struct ath10k_mac_tdls_iter_data *iter_data = data;
+	struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
+	struct ieee80211_vif *sta_vif = arsta->arvif->vif;
+
+	if (sta->tdls && sta_vif == iter_data->curr_vif)
+		iter_data->num_tdls_stations++;
+}
+
+static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
+					      struct ieee80211_vif *vif)
+{
+	struct ath10k_mac_tdls_iter_data data = {};
+
+	data.curr_vif = vif;
+
+	ieee80211_iterate_stations_atomic(hw,
+					  ath10k_mac_tdls_vif_stations_count_iter,
+					  &data);
+	return data.num_tdls_stations;
+}
+
+static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
+					    struct ieee80211_vif *vif)
+{
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int *num_tdls_vifs = data;
+
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
+		(*num_tdls_vifs)++;
+}
+
+static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
+{
+	int num_tdls_vifs = 0;
+
+	ieee80211_iterate_active_interfaces_atomic(hw,
+						   IEEE80211_IFACE_ITER_NORMAL,
+						   ath10k_mac_tdls_vifs_count_iter,
+						   &num_tdls_vifs);
+	return num_tdls_vifs;
+}
+
 static int ath10k_sta_state(struct ieee80211_hw *hw,
 			    struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta,
@@ -4447,6 +4542,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 		/*
 		 * New station addition.
 		 */
+		enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
+		u32 num_tdls_stations;
+		u32 num_tdls_vifs;
+
 		ath10k_dbg(ar, ATH10K_DBG_MAC,
 			   "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
 			   arvif->vdev_id, sta->addr,
@@ -4460,8 +4559,11 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
+		if (sta->tdls)
+			peer_type = WMI_PEER_TYPE_TDLS;
+
 		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
-					 WMI_PEER_TYPE_DEFAULT);
+					 peer_type);
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
@@ -4469,7 +4571,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
-		if (vif->type == NL80211_IFTYPE_STATION) {
+		if (vif->type == NL80211_IFTYPE_STATION &&
+		    !sta->tdls) {
 			WARN_ON(arvif->is_started);
 
 			ret = ath10k_vdev_start(arvif);
@@ -4484,6 +4587,53 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 
 			arvif->is_started = true;
 		}
+
+		if (!sta->tdls)
+			goto exit;
+
+		num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
+		num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
+
+		if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
+		    num_tdls_stations == 0) {
+			ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
+				    arvif->vdev_id, ar->max_num_tdls_vdevs);
+			ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
+			ath10k_mac_dec_num_stations(arvif, sta);
+			ret = -ENOBUFS;
+			goto exit;
+		}
+
+		if (num_tdls_stations == 0) {
+			/* This is the first tdls peer in current vif */
+			enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
+
+			ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+							      state);
+			if (ret) {
+				ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
+					    arvif->vdev_id, ret);
+				ath10k_peer_delete(ar, arvif->vdev_id,
+						   sta->addr);
+				ath10k_mac_dec_num_stations(arvif, sta);
+				goto exit;
+			}
+		}
+
+		ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
+						  WMI_TDLS_PEER_STATE_PEERING);
+		if (ret) {
+			ath10k_warn(ar,
+				    "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+			ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
+			ath10k_mac_dec_num_stations(arvif, sta);
+
+			if (num_tdls_stations != 0)
+				goto exit;
+			ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+							WMI_TDLS_DISABLE);
+		}
 	} else if ((old_state == IEEE80211_STA_NONE &&
 		    new_state == IEEE80211_STA_NOTEXIST)) {
 		/*
@@ -4493,7 +4643,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			   "mac vdev %d peer delete %pM (sta gone)\n",
 			   arvif->vdev_id, sta->addr);
 
-		if (vif->type == NL80211_IFTYPE_STATION) {
+		if (vif->type == NL80211_IFTYPE_STATION &&
+		    !sta->tdls) {
 			WARN_ON(!arvif->is_started);
 
 			ret = ath10k_vdev_stop(arvif);
@@ -4510,6 +4661,20 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 				    sta->addr, arvif->vdev_id, ret);
 
 		ath10k_mac_dec_num_stations(arvif, sta);
+
+		if (!sta->tdls)
+			goto exit;
+
+		if (ath10k_mac_tdls_vif_stations_count(hw, vif))
+			goto exit;
+
+		/* This was the last tdls peer in current vif */
+		ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+						      WMI_TDLS_DISABLE);
+		if (ret) {
+			ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
+				    arvif->vdev_id, ret);
+		}
 	} else if (old_state == IEEE80211_STA_AUTH &&
 		   new_state == IEEE80211_STA_ASSOC &&
 		   (vif->type == NL80211_IFTYPE_AP ||
@@ -4525,9 +4690,30 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
 	} else if (old_state == IEEE80211_STA_ASSOC &&
-		   new_state == IEEE80211_STA_AUTH &&
-		   (vif->type == NL80211_IFTYPE_AP ||
-		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		   new_state == IEEE80211_STA_AUTHORIZED &&
+		   sta->tdls) {
+		/*
+		 * Tdls station authorized.
+		 */
+		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
+			   sta->addr);
+
+		ret = ath10k_station_assoc(ar, vif, sta, false);
+		if (ret) {
+			ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+			goto exit;
+		}
+
+		ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
+						  WMI_TDLS_PEER_STATE_CONNECTED);
+		if (ret)
+			ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		    new_state == IEEE80211_STA_AUTH &&
+		    (vif->type == NL80211_IFTYPE_AP ||
+		     vif->type == NL80211_IFTYPE_ADHOC)) {
 		/*
 		 * Disassociation.
 		 */
@@ -5929,6 +6115,9 @@ int ath10k_mac_register(struct ath10k *ar)
 			NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
 	}
 
+	if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
+		ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+
 	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 	ar->hw->wiphy->max_remain_on_channel_duration = 5000;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v4 6/6] ath10k: introduce basic tdls functionality
@ 2015-03-20 11:02   ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-20 11:02 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Kwaczynski, Marek Puzyniak, Michal Kazior

This patch introduces tdls without tdls peer uapsd
and tdls channel switching.
Transmitting tdls data frames works only for ethernet
type frames, that's why data addressed to tdls sta
is in ethernet format.

This patch depends on:
mac80211: initialize rate control earlier for tdls station

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 205 ++++++++++++++++++++++++++++++++--
 1 file changed, 197 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3c25507..7368a04 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -582,6 +582,38 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
 	ar->num_stations = 0;
 }
 
+static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
+				       struct ieee80211_sta *sta,
+				       enum wmi_tdls_peer_state state)
+{
+	int ret;
+	struct wmi_tdls_peer_update_cmd_arg arg = {};
+	struct wmi_tdls_peer_capab_arg cap = {};
+	struct wmi_channel_arg chan_arg = {};
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	arg.vdev_id = vdev_id;
+	arg.peer_state = state;
+	ether_addr_copy(arg.addr, sta->addr);
+
+	cap.peer_max_sp = sta->max_sp;
+	cap.peer_uapsd_queues = sta->uapsd_queues;
+
+	if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
+	    !sta->tdls_initiator)
+		cap.is_peer_responder = 1;
+
+	ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
+	if (ret) {
+		ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
+			    arg.addr, vdev_id, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 /************************/
 /* Interface management */
 /************************/
@@ -2523,7 +2555,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
 
 static enum ath10k_hw_txrx_mode
 ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
-		       struct sk_buff *skb)
+		       struct ieee80211_sta *sta, struct sk_buff *skb)
 {
 	const struct ieee80211_hdr *hdr = (void *)skb->data;
 	__le16 fc = hdr->frame_control;
@@ -2555,6 +2587,15 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
 	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, ar->fw_features))
 		return ATH10K_HW_TXRX_MGMT;
 
+	/* Workaround:
+	 *
+	 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
+	 * NativeWifi txmode - it selects AP key instead of peer key. It seems
+	 * to work with Ethernet txmode so use it.
+	 */
+	if (ieee80211_is_data_present(fc) && sta && sta->tdls)
+		return ATH10K_HW_TXRX_ETHERNET;
+
 	return ATH10K_HW_TXRX_NATIVE_WIFI;
 }
 
@@ -2991,6 +3032,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	struct ath10k *ar = hw->priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_vif *vif = info->control.vif;
+	struct ieee80211_sta *sta = control->sta;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	__le16 fc = hdr->frame_control;
 
@@ -3001,7 +3043,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 	ATH10K_SKB_CB(skb)->htt.is_offchan = false;
 	ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
 	ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
-	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, skb);
+	ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
 	ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
 
 	switch (ATH10K_SKB_CB(skb)->txmode) {
@@ -4417,6 +4459,59 @@ static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
 	ar->num_stations--;
 }
 
+struct ath10k_mac_tdls_iter_data {
+	u32 num_tdls_stations;
+	struct ieee80211_vif *curr_vif;
+};
+
+static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
+						    struct ieee80211_sta *sta)
+{
+	struct ath10k_mac_tdls_iter_data *iter_data = data;
+	struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
+	struct ieee80211_vif *sta_vif = arsta->arvif->vif;
+
+	if (sta->tdls && sta_vif == iter_data->curr_vif)
+		iter_data->num_tdls_stations++;
+}
+
+static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
+					      struct ieee80211_vif *vif)
+{
+	struct ath10k_mac_tdls_iter_data data = {};
+
+	data.curr_vif = vif;
+
+	ieee80211_iterate_stations_atomic(hw,
+					  ath10k_mac_tdls_vif_stations_count_iter,
+					  &data);
+	return data.num_tdls_stations;
+}
+
+static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
+					    struct ieee80211_vif *vif)
+{
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int *num_tdls_vifs = data;
+
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
+		(*num_tdls_vifs)++;
+}
+
+static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
+{
+	int num_tdls_vifs = 0;
+
+	ieee80211_iterate_active_interfaces_atomic(hw,
+						   IEEE80211_IFACE_ITER_NORMAL,
+						   ath10k_mac_tdls_vifs_count_iter,
+						   &num_tdls_vifs);
+	return num_tdls_vifs;
+}
+
 static int ath10k_sta_state(struct ieee80211_hw *hw,
 			    struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta,
@@ -4447,6 +4542,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 		/*
 		 * New station addition.
 		 */
+		enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
+		u32 num_tdls_stations;
+		u32 num_tdls_vifs;
+
 		ath10k_dbg(ar, ATH10K_DBG_MAC,
 			   "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
 			   arvif->vdev_id, sta->addr,
@@ -4460,8 +4559,11 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
+		if (sta->tdls)
+			peer_type = WMI_PEER_TYPE_TDLS;
+
 		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr,
-					 WMI_PEER_TYPE_DEFAULT);
+					 peer_type);
 		if (ret) {
 			ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
@@ -4469,7 +4571,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			goto exit;
 		}
 
-		if (vif->type == NL80211_IFTYPE_STATION) {
+		if (vif->type == NL80211_IFTYPE_STATION &&
+		    !sta->tdls) {
 			WARN_ON(arvif->is_started);
 
 			ret = ath10k_vdev_start(arvif);
@@ -4484,6 +4587,53 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 
 			arvif->is_started = true;
 		}
+
+		if (!sta->tdls)
+			goto exit;
+
+		num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
+		num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
+
+		if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
+		    num_tdls_stations == 0) {
+			ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
+				    arvif->vdev_id, ar->max_num_tdls_vdevs);
+			ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
+			ath10k_mac_dec_num_stations(arvif, sta);
+			ret = -ENOBUFS;
+			goto exit;
+		}
+
+		if (num_tdls_stations == 0) {
+			/* This is the first tdls peer in current vif */
+			enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
+
+			ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+							      state);
+			if (ret) {
+				ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
+					    arvif->vdev_id, ret);
+				ath10k_peer_delete(ar, arvif->vdev_id,
+						   sta->addr);
+				ath10k_mac_dec_num_stations(arvif, sta);
+				goto exit;
+			}
+		}
+
+		ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
+						  WMI_TDLS_PEER_STATE_PEERING);
+		if (ret) {
+			ath10k_warn(ar,
+				    "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+			ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
+			ath10k_mac_dec_num_stations(arvif, sta);
+
+			if (num_tdls_stations != 0)
+				goto exit;
+			ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+							WMI_TDLS_DISABLE);
+		}
 	} else if ((old_state == IEEE80211_STA_NONE &&
 		    new_state == IEEE80211_STA_NOTEXIST)) {
 		/*
@@ -4493,7 +4643,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			   "mac vdev %d peer delete %pM (sta gone)\n",
 			   arvif->vdev_id, sta->addr);
 
-		if (vif->type == NL80211_IFTYPE_STATION) {
+		if (vif->type == NL80211_IFTYPE_STATION &&
+		    !sta->tdls) {
 			WARN_ON(!arvif->is_started);
 
 			ret = ath10k_vdev_stop(arvif);
@@ -4510,6 +4661,20 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 				    sta->addr, arvif->vdev_id, ret);
 
 		ath10k_mac_dec_num_stations(arvif, sta);
+
+		if (!sta->tdls)
+			goto exit;
+
+		if (ath10k_mac_tdls_vif_stations_count(hw, vif))
+			goto exit;
+
+		/* This was the last tdls peer in current vif */
+		ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
+						      WMI_TDLS_DISABLE);
+		if (ret) {
+			ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
+				    arvif->vdev_id, ret);
+		}
 	} else if (old_state == IEEE80211_STA_AUTH &&
 		   new_state == IEEE80211_STA_ASSOC &&
 		   (vif->type == NL80211_IFTYPE_AP ||
@@ -4525,9 +4690,30 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
 			ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
 				    sta->addr, arvif->vdev_id, ret);
 	} else if (old_state == IEEE80211_STA_ASSOC &&
-		   new_state == IEEE80211_STA_AUTH &&
-		   (vif->type == NL80211_IFTYPE_AP ||
-		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		   new_state == IEEE80211_STA_AUTHORIZED &&
+		   sta->tdls) {
+		/*
+		 * Tdls station authorized.
+		 */
+		ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
+			   sta->addr);
+
+		ret = ath10k_station_assoc(ar, vif, sta, false);
+		if (ret) {
+			ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+			goto exit;
+		}
+
+		ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
+						  WMI_TDLS_PEER_STATE_CONNECTED);
+		if (ret)
+			ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
+				    sta->addr, arvif->vdev_id, ret);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		    new_state == IEEE80211_STA_AUTH &&
+		    (vif->type == NL80211_IFTYPE_AP ||
+		     vif->type == NL80211_IFTYPE_ADHOC)) {
 		/*
 		 * Disassociation.
 		 */
@@ -5929,6 +6115,9 @@ int ath10k_mac_register(struct ath10k *ar)
 			NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
 	}
 
+	if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
+		ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+
 	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 	ar->hw->wiphy->max_remain_on_channel_duration = 5000;
-- 
2.1.4


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-20 11:02   ` Marek Puzyniak
@ 2015-03-22  7:49     ` Arik Nemtsov
  -1 siblings, 0 replies; 40+ messages in thread
From: Arik Nemtsov @ 2015-03-22  7:49 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
<marek.puzyniak@tieto.com> wrote:
> As a part of tdls implementation introduce
> tdls related wmi data structures, constant
> values and functions.
>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> ---
>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>  4 files changed, 285 insertions(+)
[...]
> +
> +       cmd = (void *)tlv->value;
> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
> +       cmd->state = __cpu_to_le32(state);
> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
> +       cmd->rssi_delta = __cpu_to_le32(-20);
> +       cmd->tdls_options = __cpu_to_le32(options);
> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);

Do the above lines assume all TDLS peers support TDLS buffer-sta
(which is required for peer UAPSD)? Especially the value of
tdls_puapsd_mask.
I can assure you not all peers support this :) For instance iwlwifi
does not (for now).

But I might be misinterpreting this - perhaps there some other code in
the driver/FW that checks the peer's extended-capabilities IE for
buffer-sta support (bit 28)?
That would be the best option.

Arik

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-22  7:49     ` Arik Nemtsov
  0 siblings, 0 replies; 40+ messages in thread
From: Arik Nemtsov @ 2015-03-22  7:49 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
<marek.puzyniak@tieto.com> wrote:
> As a part of tdls implementation introduce
> tdls related wmi data structures, constant
> values and functions.
>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> ---
>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>  4 files changed, 285 insertions(+)
[...]
> +
> +       cmd = (void *)tlv->value;
> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
> +       cmd->state = __cpu_to_le32(state);
> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
> +       cmd->rssi_delta = __cpu_to_le32(-20);
> +       cmd->tdls_options = __cpu_to_le32(options);
> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);

Do the above lines assume all TDLS peers support TDLS buffer-sta
(which is required for peer UAPSD)? Especially the value of
tdls_puapsd_mask.
I can assure you not all peers support this :) For instance iwlwifi
does not (for now).

But I might be misinterpreting this - perhaps there some other code in
the driver/FW that checks the peer's extended-capabilities IE for
buffer-sta support (bit 28)?
That would be the best option.

Arik

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-22  7:49     ` Arik Nemtsov
@ 2015-03-23  8:09       ` Michal Kazior
  -1 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-23  8:09 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: Marek Puzyniak, linux-wireless, ath10k

On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
> <marek.puzyniak@tieto.com> wrote:
>> As a part of tdls implementation introduce
>> tdls related wmi data structures, constant
>> values and functions.
>>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> ---
>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>  4 files changed, 285 insertions(+)
> [...]
>> +
>> +       cmd = (void *)tlv->value;
>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>> +       cmd->state = __cpu_to_le32(state);
>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>> +       cmd->tdls_options = __cpu_to_le32(options);
>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>
> Do the above lines assume all TDLS peers support TDLS buffer-sta
> (which is required for peer UAPSD)? Especially the value of
> tdls_puapsd_mask.
> I can assure you not all peers support this :) For instance iwlwifi
> does not (for now).
>
> But I might be misinterpreting this - perhaps there some other code in
> the driver/FW that checks the peer's extended-capabilities IE for
> buffer-sta support (bit 28)?
> That would be the best option.

ath10k doesn't support buffer-sta as well. Firmware requires
additional tdls_options flags (WMI_TLV_TDLS_BUFFER_STA_EN and
WMI_TLV_TDLS_SLEEP_STA_EN) to be set before it considers these values.


Michał

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-23  8:09       ` Michal Kazior
  0 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-23  8:09 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: Marek Puzyniak, linux-wireless, ath10k

On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
> <marek.puzyniak@tieto.com> wrote:
>> As a part of tdls implementation introduce
>> tdls related wmi data structures, constant
>> values and functions.
>>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> ---
>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>  4 files changed, 285 insertions(+)
> [...]
>> +
>> +       cmd = (void *)tlv->value;
>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>> +       cmd->state = __cpu_to_le32(state);
>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>> +       cmd->tdls_options = __cpu_to_le32(options);
>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>
> Do the above lines assume all TDLS peers support TDLS buffer-sta
> (which is required for peer UAPSD)? Especially the value of
> tdls_puapsd_mask.
> I can assure you not all peers support this :) For instance iwlwifi
> does not (for now).
>
> But I might be misinterpreting this - perhaps there some other code in
> the driver/FW that checks the peer's extended-capabilities IE for
> buffer-sta support (bit 28)?
> That would be the best option.

ath10k doesn't support buffer-sta as well. Firmware requires
additional tdls_options flags (WMI_TLV_TDLS_BUFFER_STA_EN and
WMI_TLV_TDLS_SLEEP_STA_EN) to be set before it considers these values.


Michał

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-23  8:09       ` Michal Kazior
@ 2015-03-23  8:59         ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-23  8:59 UTC (permalink / raw)
  To: Michal Kazior; +Cc: Arik Nemtsov, linux-wireless, ath10k

On 23 March 2015 at 09:09, Michal Kazior <michal.kazior@tieto.com> wrote:
> On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
>> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
>> <marek.puzyniak@tieto.com> wrote:
>>> As a part of tdls implementation introduce
>>> tdls related wmi data structures, constant
>>> values and functions.
>>>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>> ---
>>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>>  4 files changed, 285 insertions(+)
>> [...]
>>> +
>>> +       cmd = (void *)tlv->value;
>>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>>> +       cmd->state = __cpu_to_le32(state);
>>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>>> +       cmd->tdls_options = __cpu_to_le32(options);
>>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>>
>> Do the above lines assume all TDLS peers support TDLS buffer-sta
>> (which is required for peer UAPSD)? Especially the value of
>> tdls_puapsd_mask.

No. The function you reffer to configures device itself not TDLS
peers. Currently tdls peer uapsd buffer sta is not implemented as
Michał wrote.

>> I can assure you not all peers support this :) For instance iwlwifi
>> does not (for now).
>>
>> But I might be misinterpreting this - perhaps there some other code in
>> the driver/FW that checks the peer's extended-capabilities IE for
>> buffer-sta support (bit 28)?
>> That would be the best option.

Currently ath10k tdls device also has this bit not set. During tdls
setup phase ath10k creates data structures for tdls peer sta but also
there support for tdls peer sta power save is disabled. I think there
is no information about tdls peer sta power save from mac80211 that's
why ath10k assumes no power save support by tdls peer sta. So bit 28
in extended capabilities IE is even not checked.

>
> ath10k doesn't support buffer-sta as well. Firmware requires
> additional tdls_options flags (WMI_TLV_TDLS_BUFFER_STA_EN and
> WMI_TLV_TDLS_SLEEP_STA_EN) to be set before it considers these values.
>
>
> Michał

Marek

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-23  8:59         ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-23  8:59 UTC (permalink / raw)
  To: Michal Kazior; +Cc: Arik Nemtsov, linux-wireless, ath10k

On 23 March 2015 at 09:09, Michal Kazior <michal.kazior@tieto.com> wrote:
> On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
>> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
>> <marek.puzyniak@tieto.com> wrote:
>>> As a part of tdls implementation introduce
>>> tdls related wmi data structures, constant
>>> values and functions.
>>>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>> ---
>>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>>  4 files changed, 285 insertions(+)
>> [...]
>>> +
>>> +       cmd = (void *)tlv->value;
>>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>>> +       cmd->state = __cpu_to_le32(state);
>>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>>> +       cmd->tdls_options = __cpu_to_le32(options);
>>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>>
>> Do the above lines assume all TDLS peers support TDLS buffer-sta
>> (which is required for peer UAPSD)? Especially the value of
>> tdls_puapsd_mask.

No. The function you reffer to configures device itself not TDLS
peers. Currently tdls peer uapsd buffer sta is not implemented as
Michał wrote.

>> I can assure you not all peers support this :) For instance iwlwifi
>> does not (for now).
>>
>> But I might be misinterpreting this - perhaps there some other code in
>> the driver/FW that checks the peer's extended-capabilities IE for
>> buffer-sta support (bit 28)?
>> That would be the best option.

Currently ath10k tdls device also has this bit not set. During tdls
setup phase ath10k creates data structures for tdls peer sta but also
there support for tdls peer sta power save is disabled. I think there
is no information about tdls peer sta power save from mac80211 that's
why ath10k assumes no power save support by tdls peer sta. So bit 28
in extended capabilities IE is even not checked.

>
> ath10k doesn't support buffer-sta as well. Firmware requires
> additional tdls_options flags (WMI_TLV_TDLS_BUFFER_STA_EN and
> WMI_TLV_TDLS_SLEEP_STA_EN) to be set before it considers these values.
>
>
> Michał

Marek

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-23  8:59         ` Marek Puzyniak
@ 2015-03-23  9:46           ` Arik Nemtsov
  -1 siblings, 0 replies; 40+ messages in thread
From: Arik Nemtsov @ 2015-03-23  9:46 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: Michal Kazior, linux-wireless, ath10k

On Mon, Mar 23, 2015 at 10:59 AM, Marek Puzyniak
<marek.puzyniak@tieto.com> wrote:
> On 23 March 2015 at 09:09, Michal Kazior <michal.kazior@tieto.com> wrote:
>> On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
>>> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
>>> <marek.puzyniak@tieto.com> wrote:
>>>> As a part of tdls implementation introduce
>>>> tdls related wmi data structures, constant
>>>> values and functions.
>>>>
>>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>>> ---
>>>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>>>  4 files changed, 285 insertions(+)
>>> [...]
>>>> +
>>>> +       cmd = (void *)tlv->value;
>>>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>>>> +       cmd->state = __cpu_to_le32(state);
>>>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>>>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>>>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>>>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>>>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>>>> +       cmd->tdls_options = __cpu_to_le32(options);
>>>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>>>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>>>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>>>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>>>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>>>
>>> Do the above lines assume all TDLS peers support TDLS buffer-sta
>>> (which is required for peer UAPSD)? Especially the value of
>>> tdls_puapsd_mask.
>
> No. The function you reffer to configures device itself not TDLS
> peers. Currently tdls peer uapsd buffer sta is not implemented as
> Michał wrote.

If the device configures UAPSD queues for itself, then it requires
buffer-sta support from its peer, not from itself.
But you've reassured me you don't require this from the peer, as it
would hurt ath10k vs. ath10k TDLS connections.

Arik

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-23  9:46           ` Arik Nemtsov
  0 siblings, 0 replies; 40+ messages in thread
From: Arik Nemtsov @ 2015-03-23  9:46 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, Michal Kazior, ath10k

On Mon, Mar 23, 2015 at 10:59 AM, Marek Puzyniak
<marek.puzyniak@tieto.com> wrote:
> On 23 March 2015 at 09:09, Michal Kazior <michal.kazior@tieto.com> wrote:
>> On 22 March 2015 at 08:49, Arik Nemtsov <arik@wizery.com> wrote:
>>> On Fri, Mar 20, 2015 at 1:02 PM, Marek Puzyniak
>>> <marek.puzyniak@tieto.com> wrote:
>>>> As a part of tdls implementation introduce
>>>> tdls related wmi data structures, constant
>>>> values and functions.
>>>>
>>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>>> ---
>>>>  drivers/net/wireless/ath/ath10k/wmi-ops.h |  42 ++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.c | 153 ++++++++++++++++++++++++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi-tlv.h |  53 +++++++++++
>>>>  drivers/net/wireless/ath/ath10k/wmi.h     |  37 ++++++++
>>>>  4 files changed, 285 insertions(+)
>>> [...]
>>>> +
>>>> +       cmd = (void *)tlv->value;
>>>> +       cmd->vdev_id = __cpu_to_le32(vdev_id);
>>>> +       cmd->state = __cpu_to_le32(state);
>>>> +       cmd->notification_interval_ms = __cpu_to_le32(5000);
>>>> +       cmd->tx_discovery_threshold = __cpu_to_le32(100);
>>>> +       cmd->tx_teardown_threshold = __cpu_to_le32(5);
>>>> +       cmd->rssi_teardown_threshold = __cpu_to_le32(-75);
>>>> +       cmd->rssi_delta = __cpu_to_le32(-20);
>>>> +       cmd->tdls_options = __cpu_to_le32(options);
>>>> +       cmd->tdls_peer_traffic_ind_window = __cpu_to_le32(2);
>>>> +       cmd->tdls_peer_traffic_response_timeout_ms = __cpu_to_le32(5000);
>>>> +       cmd->tdls_puapsd_mask = __cpu_to_le32(0xf);
>>>> +       cmd->tdls_puapsd_inactivity_time_ms = __cpu_to_le32(0);
>>>> +       cmd->tdls_puapsd_rx_frame_threshold = __cpu_to_le32(10);
>>>
>>> Do the above lines assume all TDLS peers support TDLS buffer-sta
>>> (which is required for peer UAPSD)? Especially the value of
>>> tdls_puapsd_mask.
>
> No. The function you reffer to configures device itself not TDLS
> peers. Currently tdls peer uapsd buffer sta is not implemented as
> Michał wrote.

If the device configures UAPSD queues for itself, then it requires
buffer-sta support from its peer, not from itself.
But you've reassured me you don't require this from the peer, as it
would hurt ath10k vs. ath10k TDLS connections.

Arik

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-20 11:02   ` Marek Puzyniak
@ 2015-03-23 15:53     ` Kalle Valo
  -1 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-23 15:53 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> As a part of tdls implementation introduce
> tdls related wmi data structures, constant
> values and functions.
>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>

This patch had non-trivial conflicts, please check carefully my
resolution in the pending branch.

  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-23 15:53     ` Kalle Valo
  0 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-23 15:53 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> As a part of tdls implementation introduce
> tdls related wmi data structures, constant
> values and functions.
>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>

This patch had non-trivial conflicts, please check carefully my
resolution in the pending branch.

  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
  CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h

-- 
Kalle Valo

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-23 15:53     ` Kalle Valo
@ 2015-03-24  7:33       ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-24  7:33 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, ath10k

On 23 March 2015 at 11:53, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Marek Puzyniak <marek.puzyniak@tieto.com> writes:
>
>> As a part of tdls implementation introduce
>> tdls related wmi data structures, constant
>> values and functions.
>>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>
> This patch had non-trivial conflicts, please check carefully my
> resolution in the pending branch.
>
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h
>
> --
> Kalle Valo

It looks OK, but there is one small thing in file
drivers/net/wireless/ath/ath10k/wmi-tlv.c.
There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update
and ath10k_wmi_tlv_op_gen_wow_enable.

Thanks,
Marek

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-24  7:33       ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-24  7:33 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, ath10k

On 23 March 2015 at 11:53, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Marek Puzyniak <marek.puzyniak@tieto.com> writes:
>
>> As a part of tdls implementation introduce
>> tdls related wmi data structures, constant
>> values and functions.
>>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>
> This patch had non-trivial conflicts, please check carefully my
> resolution in the pending branch.
>
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h
>
> --
> Kalle Valo

It looks OK, but there is one small thing in file
drivers/net/wireless/ath/ath10k/wmi-tlv.c.
There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update
and ath10k_wmi_tlv_op_gen_wow_enable.

Thanks,
Marek

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
  2015-03-24  7:33       ` Marek Puzyniak
@ 2015-03-24  8:50         ` Kalle Valo
  -1 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-24  8:50 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> On 23 March 2015 at 11:53, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Marek Puzyniak <marek.puzyniak@tieto.com> writes:
>>
>>> As a part of tdls implementation introduce
>>> tdls related wmi data structures, constant
>>> values and functions.
>>>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>
>> This patch had non-trivial conflicts, please check carefully my
>> resolution in the pending branch.
>>
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h
>>
>> --
>> Kalle Valo
>
> It looks OK, but there is one small thing in file
> drivers/net/wireless/ath/ath10k/wmi-tlv.c.
> There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update
> and ath10k_wmi_tlv_op_gen_wow_enable.

Thanks, fixed now.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 5/6] ath10k: add wmi support for tdls
@ 2015-03-24  8:50         ` Kalle Valo
  0 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-24  8:50 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> On 23 March 2015 at 11:53, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Marek Puzyniak <marek.puzyniak@tieto.com> writes:
>>
>>> As a part of tdls implementation introduce
>>> tdls related wmi data structures, constant
>>> values and functions.
>>>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>>
>> This patch had non-trivial conflicts, please check carefully my
>> resolution in the pending branch.
>>
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi.h
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.h
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-tlv.c
>>   CONFLICT (content): Merge conflict in drivers/net/wireless/ath/ath10k/wmi-ops.h
>>
>> --
>> Kalle Valo
>
> It looks OK, but there is one small thing in file
> drivers/net/wireless/ath/ath10k/wmi-tlv.c.
> There are two new lines between functions ath10k_wmi_tlv_op_gen_tdls_peer_update
> and ath10k_wmi_tlv_op_gen_wow_enable.

Thanks, fixed now.

-- 
Kalle Valo

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
  2015-03-20 11:02   ` Marek Puzyniak
@ 2015-03-26  9:27     ` Michal Kazior
  -1 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-26  9:27 UTC (permalink / raw)
  To: Marek Puzyniak, Kalle Valo; +Cc: linux-wireless, ath10k

On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
> From: Michal Kazior <michal.kazior@tieto.com>
>
> There are a few different tx paths depending on
> firmware and frame itself.
>
> Creating a uniform decision will make it possible
> to switch between different txmode easier, both
> for testing and for future features as well.
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
[...]

This patch apparently breaks AP operation. I need to investigate this.


Michał

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
@ 2015-03-26  9:27     ` Michal Kazior
  0 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-26  9:27 UTC (permalink / raw)
  To: Marek Puzyniak, Kalle Valo; +Cc: linux-wireless, ath10k

On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
> From: Michal Kazior <michal.kazior@tieto.com>
>
> There are a few different tx paths depending on
> firmware and frame itself.
>
> Creating a uniform decision will make it possible
> to switch between different txmode easier, both
> for testing and for future features as well.
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
[...]

This patch apparently breaks AP operation. I need to investigate this.


Michał

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
  2015-03-26  9:27     ` Michal Kazior
@ 2015-03-26 10:03       ` Michal Kazior
  -1 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-26 10:03 UTC (permalink / raw)
  To: Marek Puzyniak, Kalle Valo; +Cc: linux-wireless, ath10k

On 26 March 2015 at 10:27, Michal Kazior <michal.kazior@tieto.com> wrote:
> On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>> From: Michal Kazior <michal.kazior@tieto.com>
>>
>> There are a few different tx paths depending on
>> firmware and frame itself.
>>
>> Creating a uniform decision will make it possible
>> to switch between different txmode easier, both
>> for testing and for future features as well.
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> [...]
>
> This patch apparently breaks AP operation. I need to investigate this.

Ok - htt.freq missed clearing and in some cases it contained garbage
leading to HTT discarding packets.

@Kalle: I've posted a patch `ath10k: clear htt.freq` which addresses
the problem separately. Please apply it _before_ you apply TDLS
patches (which are fine, including this patch) to avoid breakage
in-between commits.


Michał

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
@ 2015-03-26 10:03       ` Michal Kazior
  0 siblings, 0 replies; 40+ messages in thread
From: Michal Kazior @ 2015-03-26 10:03 UTC (permalink / raw)
  To: Marek Puzyniak, Kalle Valo; +Cc: linux-wireless, ath10k

On 26 March 2015 at 10:27, Michal Kazior <michal.kazior@tieto.com> wrote:
> On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>> From: Michal Kazior <michal.kazior@tieto.com>
>>
>> There are a few different tx paths depending on
>> firmware and frame itself.
>>
>> Creating a uniform decision will make it possible
>> to switch between different txmode easier, both
>> for testing and for future features as well.
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> [...]
>
> This patch apparently breaks AP operation. I need to investigate this.

Ok - htt.freq missed clearing and in some cases it contained garbage
leading to HTT discarding packets.

@Kalle: I've posted a patch `ath10k: clear htt.freq` which addresses
the problem separately. Please apply it _before_ you apply TDLS
patches (which are fine, including this patch) to avoid breakage
in-between commits.


Michał

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
  2015-03-26 10:03       ` Michal Kazior
@ 2015-03-27 12:41         ` Kalle Valo
  -1 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-27 12:41 UTC (permalink / raw)
  To: Michal Kazior; +Cc: Marek Puzyniak, linux-wireless, ath10k

Michal Kazior <michal.kazior@tieto.com> writes:

> On 26 March 2015 at 10:27, Michal Kazior <michal.kazior@tieto.com> wrote:
>> On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>>> From: Michal Kazior <michal.kazior@tieto.com>
>>>
>>> There are a few different tx paths depending on
>>> firmware and frame itself.
>>>
>>> Creating a uniform decision will make it possible
>>> to switch between different txmode easier, both
>>> for testing and for future features as well.
>>>
>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> [...]
>>
>> This patch apparently breaks AP operation. I need to investigate this.
>
> Ok - htt.freq missed clearing and in some cases it contained garbage
> leading to HTT discarding packets.
>
> @Kalle: I've posted a patch `ath10k: clear htt.freq` which addresses
> the problem separately. Please apply it _before_ you apply TDLS
> patches (which are fine, including this patch) to avoid breakage
> in-between commits.

Ack, I'll do that. Thanks for fixing this.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 1/6] ath10k: unify tx mode and dispatch
@ 2015-03-27 12:41         ` Kalle Valo
  0 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-27 12:41 UTC (permalink / raw)
  To: Michal Kazior; +Cc: Marek Puzyniak, linux-wireless, ath10k

Michal Kazior <michal.kazior@tieto.com> writes:

> On 26 March 2015 at 10:27, Michal Kazior <michal.kazior@tieto.com> wrote:
>> On 20 March 2015 at 12:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>>> From: Michal Kazior <michal.kazior@tieto.com>
>>>
>>> There are a few different tx paths depending on
>>> firmware and frame itself.
>>>
>>> Creating a uniform decision will make it possible
>>> to switch between different txmode easier, both
>>> for testing and for future features as well.
>>>
>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> [...]
>>
>> This patch apparently breaks AP operation. I need to investigate this.
>
> Ok - htt.freq missed clearing and in some cases it contained garbage
> leading to HTT discarding packets.
>
> @Kalle: I've posted a patch `ath10k: clear htt.freq` which addresses
> the problem separately. Please apply it _before_ you apply TDLS
> patches (which are fine, including this patch) to avoid breakage
> in-between commits.

Ack, I'll do that. Thanks for fixing this.

-- 
Kalle Valo

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 6/6] ath10k: introduce basic tdls functionality
  2015-03-20 11:02   ` Marek Puzyniak
@ 2015-03-27 14:33     ` Marek Puzyniak
  -1 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-27 14:33 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Puzyniak, Michal Kazior, Marek Kwaczynski

Hi Kalle,

On 20 March 2015 at 07:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
> This patch introduces tdls without tdls peer uapsd
> and tdls channel switching.
> Transmitting tdls data frames works only for ethernet
> type frames, that's why data addressed to tdls sta
> is in ethernet format.
>
> This patch depends on:
> mac80211: initialize rate control earlier for tdls station
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
> Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> ---
[...]

> +static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
[...]
> +               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
[...]

I found typo in my patch. This can be fixed by

diff --git a/drivers/net/wireless/ath/ath10k/mac.c
b/drivers/net/wireless/ath/ath10k/mac.c
index 4e2be87..5eb6c98 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4613,7 +4613,7 @@ static void ath10k_mac_tdls_vifs_count_iter(void
*data, u8 *mac,
                (*num_tdls_vifs)++;
 }

-static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
+static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
 {
        int num_tdls_vifs = 0;

@@ -4704,7 +4704,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                        goto exit;

                num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
-               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
+               num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);

                if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
                    num_tdls_stations == 0) {


Should I resend this patch or whole patch-set, or maybe it can be
handled in another way.

Marek

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 6/6] ath10k: introduce basic tdls functionality
@ 2015-03-27 14:33     ` Marek Puzyniak
  0 siblings, 0 replies; 40+ messages in thread
From: Marek Puzyniak @ 2015-03-27 14:33 UTC (permalink / raw)
  To: linux-wireless, ath10k; +Cc: Marek Kwaczynski, Marek Puzyniak, Michal Kazior

Hi Kalle,

On 20 March 2015 at 07:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
> This patch introduces tdls without tdls peer uapsd
> and tdls channel switching.
> Transmitting tdls data frames works only for ethernet
> type frames, that's why data addressed to tdls sta
> is in ethernet format.
>
> This patch depends on:
> mac80211: initialize rate control earlier for tdls station
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
> Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
> ---
[...]

> +static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
[...]
> +               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
[...]

I found typo in my patch. This can be fixed by

diff --git a/drivers/net/wireless/ath/ath10k/mac.c
b/drivers/net/wireless/ath/ath10k/mac.c
index 4e2be87..5eb6c98 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4613,7 +4613,7 @@ static void ath10k_mac_tdls_vifs_count_iter(void
*data, u8 *mac,
                (*num_tdls_vifs)++;
 }

-static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
+static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
 {
        int num_tdls_vifs = 0;

@@ -4704,7 +4704,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                        goto exit;

                num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
-               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
+               num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);

                if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
                    num_tdls_stations == 0) {


Should I resend this patch or whole patch-set, or maybe it can be
handled in another way.

Marek

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 6/6] ath10k: introduce basic tdls functionality
  2015-03-27 14:33     ` Marek Puzyniak
@ 2015-03-27 17:43       ` Kalle Valo
  -1 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-27 17:43 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k, Marek Kwaczynski, Michal Kazior

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> Hi Kalle,
>
> On 20 March 2015 at 07:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>> This patch introduces tdls without tdls peer uapsd
>> and tdls channel switching.
>> Transmitting tdls data frames works only for ethernet
>> type frames, that's why data addressed to tdls sta
>> is in ethernet format.
>>
>> This patch depends on:
>> mac80211: initialize rate control earlier for tdls station
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>> Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> ---
> [...]
>
>> +static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
> [...]
>> +               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
> [...]
>
> I found typo in my patch. This can be fixed by

Thanks, I fixed this directly in the pending branch.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 6/6] ath10k: introduce basic tdls functionality
@ 2015-03-27 17:43       ` Kalle Valo
  0 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-27 17:43 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: Marek Kwaczynski, linux-wireless, Michal Kazior, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> Hi Kalle,
>
> On 20 March 2015 at 07:02, Marek Puzyniak <marek.puzyniak@tieto.com> wrote:
>> This patch introduces tdls without tdls peer uapsd
>> and tdls channel switching.
>> Transmitting tdls data frames works only for ethernet
>> type frames, that's why data addressed to tdls sta
>> is in ethernet format.
>>
>> This patch depends on:
>> mac80211: initialize rate control earlier for tdls station
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>> Signed-off-by: Marek Kwaczynski <marek.kwaczynski@tieto.com>
>> Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
>> ---
> [...]
>
>> +static int ath10_mac_tdls_vifs_count(struct ieee80211_hw *hw)
> [...]
>> +               num_tdls_vifs = ath10_mac_tdls_vifs_count(hw);
> [...]
>
> I found typo in my patch. This can be fixed by

Thanks, I fixed this directly in the pending branch.

-- 
Kalle Valo

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 0/6] ath10k: add basic tdls support
  2015-03-20 11:02 ` Marek Puzyniak
@ 2015-03-30 12:06   ` Kalle Valo
  -1 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-30 12:06 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> This patchset introduces tdls funtionality without tdls peer uapsd
> and tdls channel switching. Tdls is supported by qca6174 hardware 
> what is indicated by firmware through supported services.
> Tdls station when authorized requires some parameters that are filled in 
> by rate control initialization. Rate control for tdls is initialized
> at proper time in mac80211 patch:
> mac80211: initialize rate control earlier for tdls station
>
> So tdls funtionality implemented by this patchset depends on 
> mac80211: initialize rate control earlier for tdls station
>
> v2:
> -introduce tdls peer counter
> -minor changes after review
>
> v3:
> -more minor changes after review
> -replace tdls peer counter variable by iterate station function
>
> v4:
> -provide functions for counting tdls station per vif and tdls vifs
> -handle maximum number of tdls vifs
> -split code into more patches
>
> Marek Puzyniak (5):
>   ath10k: make peer type configurable
>   ath10k: store max tdls vdevs that fw can handle
>   ath10k: update station counting
>   ath10k: add wmi support for tdls
>   ath10k: introduce basic tdls functionality
>
> Michal Kazior (1):
>   ath10k: unify tx mode and dispatch

Thanks, all applied.

For the record, I had to pull mac80211-next to ath-next to solve the
dependency:

commit 23d6660d7f0feacb4c0e24c5cb8f29674aa38567
Merge: 53513c302f35 5d8325ecb9c2
Author: Kalle Valo <kvalo@qca.qualcomm.com>
Date:   Mon Mar 30 10:07:12 2015 +0300

    Merge mac80211-next into ath-next
    
    Patch "ath10k: introduce basic tdls functionality" depends on this mac80211
    patch:
    
    c23e31cf7b55 mac80211: initialize rate control earlier for tdls station


-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v4 0/6] ath10k: add basic tdls support
@ 2015-03-30 12:06   ` Kalle Valo
  0 siblings, 0 replies; 40+ messages in thread
From: Kalle Valo @ 2015-03-30 12:06 UTC (permalink / raw)
  To: Marek Puzyniak; +Cc: linux-wireless, ath10k

Marek Puzyniak <marek.puzyniak@tieto.com> writes:

> This patchset introduces tdls funtionality without tdls peer uapsd
> and tdls channel switching. Tdls is supported by qca6174 hardware 
> what is indicated by firmware through supported services.
> Tdls station when authorized requires some parameters that are filled in 
> by rate control initialization. Rate control for tdls is initialized
> at proper time in mac80211 patch:
> mac80211: initialize rate control earlier for tdls station
>
> So tdls funtionality implemented by this patchset depends on 
> mac80211: initialize rate control earlier for tdls station
>
> v2:
> -introduce tdls peer counter
> -minor changes after review
>
> v3:
> -more minor changes after review
> -replace tdls peer counter variable by iterate station function
>
> v4:
> -provide functions for counting tdls station per vif and tdls vifs
> -handle maximum number of tdls vifs
> -split code into more patches
>
> Marek Puzyniak (5):
>   ath10k: make peer type configurable
>   ath10k: store max tdls vdevs that fw can handle
>   ath10k: update station counting
>   ath10k: add wmi support for tdls
>   ath10k: introduce basic tdls functionality
>
> Michal Kazior (1):
>   ath10k: unify tx mode and dispatch

Thanks, all applied.

For the record, I had to pull mac80211-next to ath-next to solve the
dependency:

commit 23d6660d7f0feacb4c0e24c5cb8f29674aa38567
Merge: 53513c302f35 5d8325ecb9c2
Author: Kalle Valo <kvalo@qca.qualcomm.com>
Date:   Mon Mar 30 10:07:12 2015 +0300

    Merge mac80211-next into ath-next
    
    Patch "ath10k: introduce basic tdls functionality" depends on this mac80211
    patch:
    
    c23e31cf7b55 mac80211: initialize rate control earlier for tdls station


-- 
Kalle Valo

_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2015-03-30 12:07 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-20 11:02 [PATCH v4 0/6] ath10k: add basic tdls support Marek Puzyniak
2015-03-20 11:02 ` Marek Puzyniak
2015-03-20 11:02 ` [PATCH v4 1/6] ath10k: unify tx mode and dispatch Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-26  9:27   ` Michal Kazior
2015-03-26  9:27     ` Michal Kazior
2015-03-26 10:03     ` Michal Kazior
2015-03-26 10:03       ` Michal Kazior
2015-03-27 12:41       ` Kalle Valo
2015-03-27 12:41         ` Kalle Valo
2015-03-20 11:02 ` [PATCH v4 2/6] ath10k: make peer type configurable Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-20 11:02 ` [PATCH v4 3/6] ath10k: store max tdls vdevs that fw can handle Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-20 11:02 ` [PATCH v4 4/6] ath10k: update station counting Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-20 11:02 ` [PATCH v4 5/6] ath10k: add wmi support for tdls Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-22  7:49   ` Arik Nemtsov
2015-03-22  7:49     ` Arik Nemtsov
2015-03-23  8:09     ` Michal Kazior
2015-03-23  8:09       ` Michal Kazior
2015-03-23  8:59       ` Marek Puzyniak
2015-03-23  8:59         ` Marek Puzyniak
2015-03-23  9:46         ` Arik Nemtsov
2015-03-23  9:46           ` Arik Nemtsov
2015-03-23 15:53   ` Kalle Valo
2015-03-23 15:53     ` Kalle Valo
2015-03-24  7:33     ` Marek Puzyniak
2015-03-24  7:33       ` Marek Puzyniak
2015-03-24  8:50       ` Kalle Valo
2015-03-24  8:50         ` Kalle Valo
2015-03-20 11:02 ` [PATCH v4 6/6] ath10k: introduce basic tdls functionality Marek Puzyniak
2015-03-20 11:02   ` Marek Puzyniak
2015-03-27 14:33   ` Marek Puzyniak
2015-03-27 14:33     ` Marek Puzyniak
2015-03-27 17:43     ` Kalle Valo
2015-03-27 17:43       ` Kalle Valo
2015-03-30 12:06 ` [PATCH v4 0/6] ath10k: add basic tdls support Kalle Valo
2015-03-30 12:06   ` Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.