From: Sriram R <quic_srirrama@xxxxxxxxxxx>
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)| |
| +----------+ | | +----------+ | | +----------+ |
| | | | | |
+---------------+ +---------------+ +---------------+
Proposed 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 stores multiple
arvifs(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_vif_to_vif()
Locking:
Currently modifications to members of arvif and arsta are protected by ar->conf_mutex
and it stays as such.
Now with these hw level structure (ahvif) being introduced, any modifications
to its members and link objects (i.e., arvifs[] which are dynamically allocated)
needs to be protected for writing and ah->conf_mutex is used for the same.
Also, atomic contexts(say WMI events and certain mac_ops) that we currently have in driver
will not(shouldn't be allowed) do any modifications but can read them and
rcu_read_lock() is used for the same.
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@xxxxxxxxxxx>
Co-developed-by: Rameshkumar Sundaram <quic_ramess@xxxxxxxxxxx>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@xxxxxxxxxxx>
---
drivers/net/wireless/ath/ath12k/core.h | 69 ++-
drivers/net/wireless/ath/ath12k/dp.c | 21 +-
drivers/net/wireless/ath/ath12k/dp.h | 3 +-
drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +-
drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +-
drivers/net/wireless/ath/ath12k/dp_tx.c | 9 +-
drivers/net/wireless/ath/ath12k/dp_tx.h | 2 +-
drivers/net/wireless/ath/ath12k/mac.c | 733 ++++++++++++++++--------
drivers/net/wireless/ath/ath12k/mac.h | 9 +-
drivers/net/wireless/ath/ath12k/p2p.c | 17 +-
drivers/net/wireless/ath/ath12k/p2p.h | 2 +-
drivers/net/wireless/ath/ath12k/peer.c | 7 +-
drivers/net/wireless/ath/ath12k/peer.h | 4 +-
drivers/net/wireless/ath/ath12k/wmi.c | 12 +-
14 files changed, 592 insertions(+), 300 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index b483899ca136..d47b6413aaad 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -229,10 +229,8 @@ struct ath12k_vif_cache {
u32 bss_conf_changed;
};
-struct ath12k_vif {
+struct ath12k_link_vif {
u32 vdev_id;
- enum wmi_vdev_type vdev_type;
- enum wmi_vdev_subtype vdev_subtype;
u32 beacon_interval;
u32 dtim_period;
u16 ast_hash;
@@ -242,13 +240,38 @@ struct ath12k_vif {
u8 search_type;
struct ath12k *ar;
- struct ieee80211_vif *vif;
int bank_id;
u8 vdev_id_check_en;
struct wmi_wmm_params_all_arg wmm_params;
struct list_head list;
+
+ bool is_created;
+ bool is_started;
+ bool is_up;
+ u8 bssid[ETH_ALEN];
+ struct cfg80211_bitrate_mask bitrate_mask;
+ struct delayed_work connection_loss_work;
+ int num_legacy_stations;
+ int rtscts_prot_mode;
+ int txpower;
+ bool rsnie_present;
+ bool wpaie_present;
+ struct ieee80211_chanctx_conf chanctx;
+ u8 vdev_stats_id;
+ u32 punct_bitmap;
+ u8 link_id;
+ struct ath12k_vif *ahvif;
+ struct ath12k_vif_cache *cache;
+};
+
+struct ath12k_vif {
+ enum wmi_vdev_type vdev_type;
+ enum wmi_vdev_subtype vdev_subtype;
+ struct ieee80211_vif *vif;
+ struct ath12k_hw *ah;
+
union {
struct {
u32 uapsd;
@@ -266,31 +289,21 @@ struct ath12k_vif {
} ap;
} u;
- bool is_created;
- bool is_started;
- bool is_up;
u32 aid;
- u8 bssid[ETH_ALEN];
- struct cfg80211_bitrate_mask bitrate_mask;
- struct delayed_work connection_loss_work;
- int num_legacy_stations;
- int rtscts_prot_mode;
- int txpower;
- bool rsnie_present;
- bool wpaie_present;
- struct ieee80211_chanctx_conf chanctx;
u32 key_cipher;
u8 tx_encap_type;
- u8 vdev_stats_id;
- u32 punct_bitmap;
bool ps;
- struct ath12k_vif_cache *cache;
+
+ struct ath12k_link_vif deflink;
+ struct ath12k_link_vif __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
+ /* indicates bitmap of link vif created in FW */
+ u16 links_map;
};
struct ath12k_vif_iter {
u32 vdev_id;
struct ath12k *ar;
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
};
#define HAL_AST_IDX_INVALID 0xFFFF
@@ -426,7 +439,7 @@ struct ath12k_wbm_tx_stats {
};
struct ath12k_sta {
- struct ath12k_vif *arvif;
+ struct ath12k_link_vif *arvif;
/* the following are protected by ar->data_lock */
u32 changed; /* IEEE80211_RC_* */
@@ -543,7 +556,7 @@ struct ath12k {
*/
struct mutex conf_mutex;
/* protects the radio specific data like debug stats, ppdu_stats_info stats,
- * vdev_stop_status info, scan data, ath12k_sta info, ath12k_vif info,
+ * vdev_stop_status info, scan data, ath12k_sta info, ath12k_link_vif info,
* channel context data, survey info, test mode data.
*/
spinlock_t data_lock;
@@ -639,6 +652,11 @@ struct ath12k_hw {
enum ath12k_hw_state state;
bool regd_updated;
bool use_6ghz_regd;
+
+ /* To synchronize concurrent access of ahvif->link[]
+ * between mac80211 operations.
+ */
+ struct mutex conf_mutex;
u8 num_radio;
/* Keep last */
@@ -995,7 +1013,7 @@ static inline struct ath12k_skb_rxcb *ATH12K_SKB_RXCB(struct sk_buff *skb)
return (struct ath12k_skb_rxcb *)skb->cb;
}
-static inline struct ath12k_vif *ath12k_vif_to_arvif(struct ieee80211_vif *vif)
+static inline struct ath12k_vif *ath12k_vif_to_ahvif(struct ieee80211_vif *vif)
{
return (struct ath12k_vif *)vif->drv_priv;
}
@@ -1005,6 +1023,11 @@ static inline struct ath12k_sta *ath12k_sta_to_arsta(struct ieee80211_sta *sta)
return (struct ath12k_sta *)sta->drv_priv;
}
+static inline struct ieee80211_vif *ath12k_vif_to_vif(struct ath12k_vif *ahvif)