wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch
John Crispin 43d7ca31d6 wifi-ax/mac80211: make the 11.4 ath11k work inside the v5.4 kernel
Fixes: WIFI-7570
Signed-off-by: John Crispin <john@phrozen.org>
2022-05-27 10:05:52 +02:00

212 lines
6.5 KiB
Diff

From 6f51430f2614ca2fb2a1e45cc81464c6d7a29f03 Mon Sep 17 00:00:00 2001
From: Sathishkumar Muruganandam <murugana@codeaurora.org>
Date: Fri, 8 Jan 2021 00:34:09 +0530
Subject: [PATCH 2/3] ath11k: extend ext vdev in NSS for dynamic VLAN handling
- add ext vdev NSS API callbacks required for dynamic AP_VLAN vif
- existing ext vdev NSS API callbacks are used for both WDS and
dynamic VLAN di_types.
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/nss.c | 101 +++++++++++++++++++++++++++++++---
drivers/net/wireless/ath/ath11k/nss.h | 17 ++++++
2 files changed, 109 insertions(+), 9 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/nss.c
+++ b/drivers/net/wireless/ath/ath11k/nss.c
@@ -1483,14 +1483,11 @@ static int ath11k_nss_ext_vdev_register(
struct ath11k *ar = arvif->ar;
struct ath11k_base *ab = ar->ab;
nss_tx_status_t status;
- enum nss_dynamic_interface_type di_type;
u32 features = 0;
if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx)
return -EINVAL;
- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS;
-
arvif->nss.ctx = nss_wifi_ext_vdev_register_if(arvif->nss.if_num,
ath11k_nss_ext_vdev_data_receive,
ath11k_nss_ext_vdev_special_data_receive,
@@ -1518,7 +1515,8 @@ static void ath11k_nss_ext_vdev_free(str
status = nss_dynamic_interface_dealloc_node(
arvif->nss.if_num,
- NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS);
+ arvif->nss.di_type);
+
if (status != NSS_TX_SUCCESS)
ath11k_warn(ab, "failed to free nss ext vdev err:%d\n",
status);
@@ -1527,14 +1525,19 @@ static void ath11k_nss_ext_vdev_free(str
"nss ext vdev interface deallocated\n");
}
-static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif)
+static int ath11k_nss_ext_vdev_alloc(struct ath11k_vif *arvif,
+ struct wireless_dev *wdev)
{
struct ath11k_base *ab = arvif->ar->ab;
enum nss_dynamic_interface_type di_type;
int if_num;
- di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS;
+ if (wdev->use_4addr)
+ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS;
+ else
+ di_type = NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_VLAN;
+ arvif->nss.di_type = di_type;
if_num = nss_dynamic_interface_alloc_node(di_type);
if (if_num < 0) {
ath11k_warn(ab, "failed to allocate nss ext vdev\n");
@@ -1543,8 +1546,8 @@ static int ath11k_nss_ext_vdev_alloc(str
arvif->nss.if_num = if_num;
ath11k_dbg(ab, ATH11K_DBG_NSS_WDS,
- "nss ext vdev interface %pM allocated if_num %d\n",
- arvif->vif->addr, if_num);
+ "nss ext vdev interface %pM di_type %d allocated if_num %d\n",
+ arvif->vif->addr, di_type, if_num);
return 0;
}
@@ -1573,7 +1576,7 @@ int ath11k_nss_ext_vdev_create(struct at
return -EINVAL;
}
- ret = ath11k_nss_ext_vdev_alloc(arvif);
+ ret = ath11k_nss_ext_vdev_alloc(arvif, wdev);
if (ret)
return ret;
@@ -1684,6 +1687,86 @@ free:
return ret;
}
+int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id)
+{
+ struct ath11k *ar = arvif->ar;
+ struct nss_wifi_ext_vdev_msg *ext_vdev_msg = NULL;
+ struct nss_wifi_ext_vdev_vlan_msg *cfg_dyn_vlan_msg = NULL;
+ nss_tx_status_t status;
+ int ret;
+
+ if (!ar->ab->nss.enabled)
+ return 0;
+
+ if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN)
+ return -EINVAL;
+
+ ext_vdev_msg = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_ATOMIC);
+ if (!ext_vdev_msg)
+ return -ENOMEM;
+
+ cfg_dyn_vlan_msg = &ext_vdev_msg->msg.vmsg;
+ cfg_dyn_vlan_msg->vlan_id = vlan_id;
+
+ nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num,
+ NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_VLAN,
+ sizeof(struct nss_wifi_ext_vdev_vlan_msg),
+ NULL, arvif);
+
+ status = nss_wifi_ext_vdev_tx_msg_sync(arvif->nss.ctx, ext_vdev_msg);
+ if (status != NSS_TX_SUCCESS) {
+ ath11k_warn(ar->ab, "failed to configure dyn vlan nss_err:%d\n",
+ status);
+ ret = -EINVAL;
+ goto free;
+ }
+
+ ret = 0;
+free:
+ kfree(ext_vdev_msg);
+
+ return ret;
+}
+
+int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id,
+ u16 group_key)
+{
+ struct nss_wifi_vdev_msg *vdev_msg = NULL;
+ struct nss_wifi_vdev_set_vlan_group_key *vlan_group_key;
+ struct ath11k *ar = arvif->ar;
+ nss_tx_status_t status;
+ int ret = 0;
+
+ if (!ar->ab->nss.enabled)
+ return 0;
+
+ vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC);
+ if (!vdev_msg)
+ return -ENOMEM;
+
+ vlan_group_key = &vdev_msg->msg.vlan_group_key;
+ vlan_group_key->vlan_id = vlan_id;
+ vlan_group_key->group_key = group_key;
+
+ nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num,
+ NSS_WIFI_VDEV_SET_GROUP_KEY,
+ sizeof(struct nss_wifi_vdev_set_vlan_group_key),
+ NULL, NULL);
+
+ status = nss_wifi_vdev_tx_msg(ar->nss.ctx, vdev_msg);
+ if (status != NSS_TX_SUCCESS) {
+ ath11k_warn(ar->ab, "nss vdev set vlan group key error %d\n", status);
+ ret = -EINVAL;
+ goto free;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_WDS, "nss vdev set vlan group key success\n");
+free:
+ kfree(vdev_msg);
+ return ret;
+
+}
+
/*----------------------------Peer Setup/Config -----------------------------*/
int ath11k_nss_set_peer_sec_type(struct ath11k *ar,
--- a/drivers/net/wireless/ath/ath11k/nss.h
+++ b/drivers/net/wireless/ath/ath11k/nss.h
@@ -150,6 +150,8 @@ struct arvif_nss {
bool added;
/* Flag to notify if ext vdev is up/down */
bool ext_vdev_up;
+ /* Keep the copy of di_type for nss */
+ enum nss_dynamic_interface_type di_type;
/* WDS cfg should be done only once for ext vdev */
bool wds_cfg_done;
bool created;
@@ -215,6 +217,9 @@ void ath11k_nss_ext_vdev_unregister(stru
int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif);
int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif);
void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif);
+int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif, u16 vlan_id);
+int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif, u16 vlan_id,
+ u16 group_key);
int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer,
struct ieee80211_key_conf *key_conf);
void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif,
@@ -343,6 +348,18 @@ static inline int ath11k_nss_ext_vdev_do
{
return 0;
}
+
+static inline int ath11k_nss_ext_vdev_cfg_dyn_vlan(struct ath11k_vif *arvif,
+ u16 vlan_id)
+{
+ return 0;
+}
+
+static inline int ath11k_nss_dyn_vlan_set_group_key(struct ath11k_vif *arvif,
+ u16 vlan_id, u16 group_key)
+{
+ return 0;
+}
static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar)
{