ath11k.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes
@ 2021-07-20 21:31 Jouni Malinen
  2021-07-20 21:31 ` [PATCH 2/2] ath11k: fix 4addr multicast packet tx Jouni Malinen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jouni Malinen @ 2021-07-20 21:31 UTC (permalink / raw)
  To: Kalle Valo
  Cc: ath11k, linux-wireless, Sathishkumar Muruganandam, Jouni Malinen

From: Sathishkumar Muruganandam <murugana@codeaurora.org>

Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for
4-addr peers allowing 4-address frame transmission to those peers.

Add ath11k driver callback for sta_set_4addr() to queue new workq
set_4addr_wk only once based on new boolean, use_4addr_set.

sta_set_4addr() will be called during 4-addr STA association cases
applicable for both AP and STA modes.

In ath11k_sta_set_4addr_wk(),

AP mode:
        WMI_PEER_USE_4ADDR will be set for the corresponding
        associated 4-addr STA(s)

STA mode:
        WMI_PEER_USE_4ADDR will be set for the AP to which the
        4-addr STA got associated.

Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1

Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/core.h |  3 ++
 drivers/net/wireless/ath/ath11k/mac.c  | 48 ++++++++++++++++++++++++--
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 018fb2385f2a..11c8dffd0236 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -362,6 +362,7 @@ struct ath11k_sta {
 	enum hal_pn_type pn_type;
 
 	struct work_struct update_wk;
+	struct work_struct set_4addr_wk;
 	struct rate_info txrate;
 	struct rate_info last_txrate;
 	u64 rx_duration;
@@ -374,6 +375,8 @@ struct ath11k_sta {
 	/* protected by conf_mutex */
 	bool aggr_mode;
 #endif
+
+	bool use_4addr_set;
 };
 
 #define ATH11K_MIN_5G_FREQ 4150
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index e9b3689331ec..d42637ecbf1e 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3155,6 +3155,31 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
 	mutex_unlock(&ar->conf_mutex);
 }
 
+static void ath11k_sta_set_4addr_wk(struct work_struct *wk)
+{
+	struct ath11k *ar;
+	struct ath11k_vif *arvif;
+	struct ath11k_sta *arsta;
+	struct ieee80211_sta *sta;
+	int ret = 0;
+
+	arsta = container_of(wk, struct ath11k_sta, set_4addr_wk);
+	sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
+	arvif = arsta->arvif;
+	ar = arvif->ar;
+
+	ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+		   "setting USE_4ADDR for peer %pM\n", sta->addr);
+
+	ret = ath11k_wmi_set_peer_param(ar, sta->addr,
+					arvif->vdev_id,
+					WMI_PEER_USE_4ADDR, 1);
+
+	if (ret)
+		ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n",
+			    sta->addr, ret);
+}
+
 static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,
 				       struct ieee80211_sta *sta)
 {
@@ -3234,11 +3259,13 @@ static int ath11k_mac_station_add(struct ath11k *ar,
 	}
 
 	if (ieee80211_vif_is_mesh(vif)) {
+		ath11k_dbg(ab, ATH11K_DBG_MAC,
+			   "setting USE_4ADDR for mesh STA %pM\n", sta->addr);
 		ret = ath11k_wmi_set_peer_param(ar, sta->addr,
 						arvif->vdev_id,
 						WMI_PEER_USE_4ADDR, 1);
 		if (ret) {
-			ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n",
+			ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n",
 				    sta->addr, ret);
 			goto free_tx_stats;
 		}
@@ -3291,8 +3318,10 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 
 	/* cancel must be done outside the mutex to avoid deadlock */
 	if ((old_state == IEEE80211_STA_NONE &&
-	     new_state == IEEE80211_STA_NOTEXIST))
+	     new_state == IEEE80211_STA_NOTEXIST)) {
 		cancel_work_sync(&arsta->update_wk);
+		cancel_work_sync(&arsta->set_4addr_wk);
+	}
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -3301,6 +3330,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
 		memset(arsta, 0, sizeof(*arsta));
 		arsta->arvif = arvif;
 		INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
+		INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);
 
 		ret = ath11k_mac_station_add(ar, vif, sta);
 		if (ret)
@@ -3395,6 +3425,19 @@ static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw,
 	return ret;
 }
 
+static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,
+					struct ieee80211_vif *vif,
+					struct ieee80211_sta *sta, bool enabled)
+{
+	struct ath11k *ar = hw->priv;
+	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
+
+	if (enabled && !arsta->use_4addr_set) {
+		ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk);
+		arsta->use_4addr_set = true;
+	}
+}
+
 static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
 					struct ieee80211_vif *vif,
 					struct ieee80211_sta *sta,
@@ -6180,6 +6223,7 @@ static const struct ieee80211_ops ath11k_ops = {
 	.cancel_hw_scan                 = ath11k_mac_op_cancel_hw_scan,
 	.set_key                        = ath11k_mac_op_set_key,
 	.sta_state                      = ath11k_mac_op_sta_state,
+	.sta_set_4addr                  = ath11k_mac_op_sta_set_4addr,
 	.sta_set_txpwr			= ath11k_mac_op_sta_set_txpwr,
 	.sta_rc_update			= ath11k_mac_op_sta_rc_update,
 	.conf_tx                        = ath11k_mac_op_conf_tx,
-- 
2.25.1


-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

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

* [PATCH 2/2] ath11k: fix 4addr multicast packet tx
  2021-07-20 21:31 [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Jouni Malinen
@ 2021-07-20 21:31 ` Jouni Malinen
  2021-09-16  9:14 ` [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Kalle Valo
  2021-09-16  9:15 ` Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Jouni Malinen @ 2021-07-20 21:31 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath11k, linux-wireless, Karthikeyan Periyasamy, Jouni Malinen

From: Karthikeyan Periyasamy <periyasa@codeaurora.org>

In 4addr, AP wired backbone to STA wired backbone ping fails due to ARP
request not getting answered. Here 4addr ARP multicast packet is sent in
3addr, so that 4addr STA not honouring the 3addr ARP multicast packet.
Fix this issue by sending out multicast packet in 4addr format, firmware
expects peer meta flag instead of vdev meta flag in Tx descriptor.

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01641-QCAHKSWPL_SILICONZ-1

Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/core.h  |  1 +
 drivers/net/wireless/ath/ath11k/dp_tx.c | 12 ++++++++++--
 drivers/net/wireless/ath/ath11k/dp_tx.h |  2 +-
 drivers/net/wireless/ath/ath11k/mac.c   |  6 +++++-
 drivers/net/wireless/ath/ath11k/peer.c  | 11 +++++++++++
 5 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 11c8dffd0236..6a6cabdd3e30 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -377,6 +377,7 @@ struct ath11k_sta {
 #endif
 
 	bool use_4addr_set;
+	u16 tcl_metadata;
 };
 
 #define ATH11K_MIN_5G_FREQ 4150
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c
index 8bba5234f81f..3acdd4050d5b 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
 }
 
 int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
-		 struct sk_buff *skb)
+		 struct ath11k_sta *arsta, struct sk_buff *skb)
 {
 	struct ath11k_base *ab = ar->ab;
 	struct ath11k_dp *dp = &ab->dp;
@@ -145,7 +145,15 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
 		     FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) |
 		     FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
 	ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
-	ti.meta_data_flags = arvif->tcl_metadata;
+
+	if (ieee80211_has_a4(hdr->frame_control) &&
+	    is_multicast_ether_addr(hdr->addr3) && arsta &&
+	    arsta->use_4addr_set) {
+		ti.meta_data_flags = arsta->tcl_metadata;
+		ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
+	} else {
+		ti.meta_data_flags = arvif->tcl_metadata;
+	}
 
 	if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
 		if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h
index f8a9f9c8e444..698b907b878d 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
@@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status {
 
 int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
 int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
-		 struct sk_buff *skb);
+		 struct ath11k_sta *arsta, struct sk_buff *skb);
 void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id);
 int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
 			      enum hal_reo_cmd_type type,
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index d42637ecbf1e..e8da4af82221 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4356,6 +4356,7 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw,
 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_key_conf *key = info->control.hw_key;
+	struct ath11k_sta *arsta = NULL;
 	u32 info_flags = info->flags;
 	bool is_prb_rsp;
 	int ret;
@@ -4381,7 +4382,10 @@ static void ath11k_mac_op_tx(struct ieee80211_hw *hw,
 		return;
 	}
 
-	ret = ath11k_dp_tx(ar, arvif, skb);
+	if (control->sta)
+		arsta = (struct ath11k_sta *)control->sta->drv_priv;
+
+	ret = ath11k_dp_tx(ar, arvif, arsta, skb);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
 		ieee80211_free_txskb(ar->hw, skb);
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
index f49abefa9618..85471f8b3563 100644
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
 		       struct ieee80211_sta *sta, struct peer_create_params *param)
 {
 	struct ath11k_peer *peer;
+	struct ath11k_sta *arsta;
 	int ret;
 
 	lockdep_assert_held(&ar->conf_mutex);
@@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
 	peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
 	peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
 
+	if (sta) {
+		arsta = (struct ath11k_sta *)sta->drv_priv;
+		arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) |
+				       FIELD_PREP(HTT_TCL_META_DATA_PEER_ID,
+						  peer->peer_id);
+
+		/* set HTT extension valid bit to 0 by default */
+		arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
+	}
+
 	ar->num_peers++;
 
 	spin_unlock_bh(&ar->ab->base_lock);
-- 
2.25.1


-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

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

* Re: [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes
  2021-07-20 21:31 [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Jouni Malinen
  2021-07-20 21:31 ` [PATCH 2/2] ath11k: fix 4addr multicast packet tx Jouni Malinen
@ 2021-09-16  9:14 ` Kalle Valo
  2021-09-16  9:15 ` Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2021-09-16  9:14 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: ath11k, linux-wireless, Sathishkumar Muruganandam

Jouni Malinen <jouni@codeaurora.org> writes:

> From: Sathishkumar Muruganandam <murugana@codeaurora.org>
>
> Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for
> 4-addr peers allowing 4-address frame transmission to those peers.
>
> Add ath11k driver callback for sta_set_4addr() to queue new workq
> set_4addr_wk only once based on new boolean, use_4addr_set.
>
> sta_set_4addr() will be called during 4-addr STA association cases
> applicable for both AP and STA modes.
>
> In ath11k_sta_set_4addr_wk(),
>
> AP mode:
>         WMI_PEER_USE_4ADDR will be set for the corresponding
>         associated 4-addr STA(s)
>
> STA mode:
>         WMI_PEER_USE_4ADDR will be set for the AP to which the
>         4-addr STA got associated.
>
> Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
> Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
> ---
>  drivers/net/wireless/ath/ath11k/core.h |  3 ++
>  drivers/net/wireless/ath/ath11k/mac.c  | 48 ++++++++++++++++++++++++--
>  2 files changed, 49 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
> index 018fb2385f2a..11c8dffd0236 100644
> --- a/drivers/net/wireless/ath/ath11k/core.h
> +++ b/drivers/net/wireless/ath/ath11k/core.h
> @@ -362,6 +362,7 @@ struct ath11k_sta {
>  	enum hal_pn_type pn_type;
>  
>  	struct work_struct update_wk;
> +	struct work_struct set_4addr_wk;
>  	struct rate_info txrate;
>  	struct rate_info last_txrate;
>  	u64 rx_duration;
> @@ -374,6 +375,8 @@ struct ath11k_sta {
>  	/* protected by conf_mutex */
>  	bool aggr_mode;
>  #endif
> +
> +	bool use_4addr_set;
>  };

[...]

> +static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,
> +					struct ieee80211_vif *vif,
> +					struct ieee80211_sta *sta, bool enabled)
> +{
> +	struct ath11k *ar = hw->priv;
> +	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
> +
> +	if (enabled && !arsta->use_4addr_set) {
> +		ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk);
> +		arsta->use_4addr_set = true;
> +	}
> +}

There's no locking for accessing arsta->use_4addr_set. Most likely it's
just a theoretical issue but wanted to point out anyway. Maybe mac80211
handles serialisation of this callback?

I'm going to apply this patch anyway so that I get my patch queue
smaller, we can fix any issues in a followup patch.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

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

* Re: [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes
  2021-07-20 21:31 [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Jouni Malinen
  2021-07-20 21:31 ` [PATCH 2/2] ath11k: fix 4addr multicast packet tx Jouni Malinen
  2021-09-16  9:14 ` [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Kalle Valo
@ 2021-09-16  9:15 ` Kalle Valo
  2 siblings, 0 replies; 4+ messages in thread
From: Kalle Valo @ 2021-09-16  9:15 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: ath11k, linux-wireless, Sathishkumar Muruganandam, Jouni Malinen

Jouni Malinen <jouni@codeaurora.org> wrote:

> Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for
> 4-addr peers allowing 4-address frame transmission to those peers.
> 
> Add ath11k driver callback for sta_set_4addr() to queue new workq
> set_4addr_wk only once based on new boolean, use_4addr_set.
> 
> sta_set_4addr() will be called during 4-addr STA association cases
> applicable for both AP and STA modes.
> 
> In ath11k_sta_set_4addr_wk(),
> 
> AP mode:
>         WMI_PEER_USE_4ADDR will be set for the corresponding
>         associated 4-addr STA(s)
> 
> STA mode:
>         WMI_PEER_USE_4ADDR will be set for the AP to which the
>         4-addr STA got associated.
> 
> Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1
> 
> Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
> Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

2 patches applied to ath-next branch of ath.git, thanks.

34c67dc36641 ath11k: fix 4-addr tx failure for AP and STA modes
e20cfa3b62ae ath11k: fix 4addr multicast packet tx

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20210720213147.90042-1-jouni@codeaurora.org/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

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

end of thread, other threads:[~2021-09-16  9:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-20 21:31 [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Jouni Malinen
2021-07-20 21:31 ` [PATCH 2/2] ath11k: fix 4addr multicast packet tx Jouni Malinen
2021-09-16  9:14 ` [PATCH 1/2] ath11k: fix 4-addr tx failure for AP and STA modes Kalle Valo
2021-09-16  9:15 ` Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).