summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath12k/wow.c
diff options
context:
space:
mode:
authorSriram R <quic_srirrama@quicinc.com>2024-10-15 20:14:06 +0300
committerJeff Johnson <quic_jjohnson@quicinc.com>2024-10-16 18:36:19 +0300
commit3dd2c68f206ef7020d12b9f85cbfe05ca8662cf4 (patch)
treea025df3d174bd8da0e56d5bcec14267d28c3a093 /drivers/net/wireless/ath/ath12k/wow.c
parent25ff1ae52139b53c1a69f55ce235077528245b55 (diff)
downloadlinux-3dd2c68f206ef7020d12b9f85cbfe05ca8662cf4.tar.xz
wifi: ath12k: prepare vif data structure for MLO handling
To prepare the driver for MLO support, split the driver vif data structure to scale for multiple links. This requires changing the use of arvif to per link and not per hw which can now comprise of multiple links. Also since most configurations from mac80211 are done per link, do refactoring of the driver functions to apply these configurations at link level. Split ath12k_vif which is the driver private of ieee80211_vif to store link specific information as ath12k_link_vif. For default use cases the ath12k vif will have a preallocated link vif called deflink which will be used by non ML and the first link vif of ML vif. With MLO support to be added, remaining link vifs will be allocated during channel assignment where vdev create/start happens. These link vifs will be freed during interface down. Current ath12k_vif(arvif) structure +---------------+ +---------------+ +---------------+ | ieee80211_vif | | ieee80211_vif | | ieee80211_vif | | private data | | private data | | private data | | | | | | | | ath12k_vif | | ath12k_vif | | ath12k_vif | | (arvif) | | (arvif) | | (arvif) | | | | | | | | +----------+ | | +----------+ | | +----------+ | | |*ar (2GHz)| | | |*ar (5GHz)| | | |*ar (2GHz)| | | +----------+ | | +----------+ | | +----------+ | | | | | | | +---------------+ +---------------+ +---------------+ The new ath12k_vif (ahvif) containing ath12k_link_vif(s) (arvif) (deflink is preallocated member which is always the first link if ieee80211_vif is MLD and is the only link otherwise): +---------------------------------+ | ieee80211_vif | | private data | | | | ath12k_vif(ahvif) | | | | +-------------------------------+ | |ath12k_link_vif deflink (arvif)| | | +---------------+ | | | | *ar(2GHz) | | | +-------------------------------+ | +-------------------------------+ | | ath12k_link_vif *link (arvif)| | | +---------------+ | | | | *ar(5GHz) | | | +-------------------------------+ | +-------------------------------+ | | ath12k_link_vif *link (arvif)| | | +---------------+ | | | | *ar(6GHz) | | | +-------------------------------+ | | +---------------------------------+ To refactor existing ath12k_vif to make use of link vifs, following changes are made: 1. ath12k_vif now called by variable name ahvif storing multiple arvifs (struct ah12k_link_vif) and also has a back pointer to ieee80211_vif. 2. In this patch set, only deflink is used to be on par with the existing code. When MLO support is added the link id will be used to fetch the arvif. 3. For mac80211 ops which doesn't use specific link_id, the config or info is common for the vif, hence apply the config to all link vifs. The links_map in the ahvif, will be used to identify all the link vifs that are setup. 4. Change ath12k_vif_to_arvif() as ath12k_vif_to_ahvif() to fetch the hw level vif. The link vif can be fetched from ahvif->link[], or the deflink can be accessed via ahvif->deflink. API to access link vif (arvif) by passing link_id can be introduced with MLO Support. 5. The ieee80211_vif can be accessed from ahvif using ath12k_ahvif_to_vif(). The locking continues to use wiphy_lock() for protecting access to most data in struct ath12k&co, there are no changes in that regard. Though struct ath12k_vif::link[] is protected with RCU. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Sriram R <quic_srirrama@quicinc.com> Co-developed-by: Rameshkumar Sundaram <quic_ramess@quicinc.com> Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://patch.msgid.link/20241015171416.518022-2-kvalo@kernel.org Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath12k/wow.c')
-rw-r--r--drivers/net/wireless/ath/ath12k/wow.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c
index a6bb860a4eaa..9e1c0bfd212f 100644
--- a/drivers/net/wireless/ath/ath12k/wow.c
+++ b/drivers/net/wireless/ath/ath12k/wow.c
@@ -29,11 +29,11 @@ static const struct wiphy_wowlan_support ath12k_wowlan_support = {
.max_pkt_offset = WOW_MAX_PKT_OFFSET,
};
-static inline bool ath12k_wow_is_p2p_vdev(struct ath12k_vif *arvif)
+static inline bool ath12k_wow_is_p2p_vdev(struct ath12k_vif *ahvif)
{
- return (arvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_DEVICE ||
- arvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_CLIENT ||
- arvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_GO);
+ return (ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_DEVICE ||
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_CLIENT ||
+ ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_P2P_GO);
}
int ath12k_wow_enable(struct ath12k *ar)
@@ -101,7 +101,7 @@ int ath12k_wow_wakeup(struct ath12k *ar)
return 0;
}
-static int ath12k_wow_vif_cleanup(struct ath12k_vif *arvif)
+static int ath12k_wow_vif_cleanup(struct ath12k_link_vif *arvif)
{
struct ath12k *ar = arvif->ar;
int i, ret;
@@ -129,7 +129,7 @@ static int ath12k_wow_vif_cleanup(struct ath12k_vif *arvif)
static int ath12k_wow_cleanup(struct ath12k *ar)
{
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
@@ -354,7 +354,7 @@ ath12k_wow_pno_check_and_convert(struct ath12k *ar, u32 vdev_id,
return 0;
}
-static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif,
+static int ath12k_wow_vif_set_wakeups(struct ath12k_link_vif *arvif,
struct cfg80211_wowlan *wowlan)
{
const struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
@@ -364,7 +364,7 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif,
int ret, i, j;
/* Setup requested WOW features */
- switch (arvif->vdev_type) {
+ switch (arvif->ahvif->vdev_type) {
case WMI_VDEV_TYPE_IBSS:
__set_bit(WOW_BEACON_EVENT, &wow_mask);
fallthrough;
@@ -473,13 +473,13 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_vif *arvif,
static int ath12k_wow_set_wakeups(struct ath12k *ar,
struct cfg80211_wowlan *wowlan)
{
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (ath12k_wow_is_p2p_vdev(arvif))
+ if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
continue;
ret = ath12k_wow_vif_set_wakeups(arvif, wowlan);
if (ret) {
@@ -518,11 +518,11 @@ out:
return ret;
}
-static int ath12k_wow_vif_clean_nlo(struct ath12k_vif *arvif)
+static int ath12k_wow_vif_clean_nlo(struct ath12k_link_vif *arvif)
{
struct ath12k *ar = arvif->ar;
- switch (arvif->vdev_type) {
+ switch (arvif->ahvif->vdev_type) {
case WMI_VDEV_TYPE_STA:
return ath12k_wow_vdev_clean_nlo(ar, arvif->vdev_id);
default:
@@ -532,13 +532,13 @@ static int ath12k_wow_vif_clean_nlo(struct ath12k_vif *arvif)
static int ath12k_wow_nlo_cleanup(struct ath12k *ar)
{
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (ath12k_wow_is_p2p_vdev(arvif))
+ if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
continue;
ret = ath12k_wow_vif_clean_nlo(arvif);
@@ -555,13 +555,13 @@ static int ath12k_wow_nlo_cleanup(struct ath12k *ar)
static int ath12k_wow_set_hw_filter(struct ath12k *ar)
{
struct wmi_hw_data_filter_arg arg;
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+ if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA)
continue;
arg.vdev_id = arvif->vdev_id;
@@ -581,13 +581,13 @@ static int ath12k_wow_set_hw_filter(struct ath12k *ar)
static int ath12k_wow_clear_hw_filter(struct ath12k *ar)
{
struct wmi_hw_data_filter_arg arg;
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+ if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA)
continue;
arg.vdev_id = arvif->vdev_id;
@@ -626,10 +626,10 @@ static void ath12k_wow_generate_ns_mc_addr(struct ath12k_base *ab,
}
}
-static void ath12k_wow_prepare_ns_offload(struct ath12k_vif *arvif,
+static void ath12k_wow_prepare_ns_offload(struct ath12k_link_vif *arvif,
struct wmi_arp_ns_offload_arg *offload)
{
- struct net_device *ndev = ieee80211_vif_to_wdev(arvif->vif)->netdev;
+ struct net_device *ndev = ieee80211_vif_to_wdev(arvif->ahvif->vif)->netdev;
struct ath12k_base *ab = arvif->ar->ab;
struct inet6_ifaddr *ifa6;
struct ifacaddr6 *ifaca6;
@@ -710,10 +710,10 @@ unlock:
ath12k_wow_generate_ns_mc_addr(ab, offload);
}
-static void ath12k_wow_prepare_arp_offload(struct ath12k_vif *arvif,
+static void ath12k_wow_prepare_arp_offload(struct ath12k_link_vif *arvif,
struct wmi_arp_ns_offload_arg *offload)
{
- struct ieee80211_vif *vif = arvif->vif;
+ struct ieee80211_vif *vif = arvif->ahvif->vif;
struct ieee80211_vif_cfg vif_cfg = vif->cfg;
struct ath12k_base *ab = arvif->ar->ab;
u32 ipv4_cnt;
@@ -732,7 +732,8 @@ static void ath12k_wow_prepare_arp_offload(struct ath12k_vif *arvif,
static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
{
struct wmi_arp_ns_offload_arg *offload;
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
+ struct ath12k_vif *ahvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
@@ -742,12 +743,14 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
return -ENOMEM;
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+ ahvif = arvif->ahvif;
+
+ if (ahvif->vdev_type != WMI_VDEV_TYPE_STA)
continue;
memset(offload, 0, sizeof(*offload));
- memcpy(offload->mac_addr, arvif->vif->addr, ETH_ALEN);
+ memcpy(offload->mac_addr, ahvif->vif->addr, ETH_ALEN);
ath12k_wow_prepare_ns_offload(arvif, offload);
ath12k_wow_prepare_arp_offload(arvif, offload);
@@ -766,13 +769,13 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
static int ath12k_gtk_rekey_offload(struct ath12k *ar, bool enable)
{
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
list_for_each_entry(arvif, &ar->arvifs, list) {
- if (arvif->vdev_type != WMI_VDEV_TYPE_STA ||
+ if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA ||
!arvif->is_up ||
!arvif->rekey_data.enable_offload)
continue;
@@ -824,7 +827,7 @@ static int ath12k_wow_set_keepalive(struct ath12k *ar,
enum wmi_sta_keepalive_method method,
u32 interval)
{
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
int ret;
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);