From patchwork Fri Oct 22 12:37:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: P Praneesh X-Patchwork-Id: 12577689 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 378F0C433F5 for ; Fri, 22 Oct 2021 12:39:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A56360F4F for ; Fri, 22 Oct 2021 12:39:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232323AbhJVMlz (ORCPT ); Fri, 22 Oct 2021 08:41:55 -0400 Received: from m43-7.mailgun.net ([69.72.43.7]:52910 "EHLO m43-7.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232495AbhJVMly (ORCPT ); Fri, 22 Oct 2021 08:41:54 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1634906377; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=3C40W8P7lgashJSjwBkbZqBPS1J6Tm+NF6xKlFLB9ks=; b=S15u0+M87N9b3WPivSHoBrRVqQF9AZxssgA3UnAdjwnDgpHffPr3Pdj6+ZVqAhmXh4kdDBoP cdNKNb1o+W/tZK+rSaxNEgikVmzQLosA8Ws1E7n2LlGnAqw6l8iNYYHq1HBy71B+NT5ngwBP vCD+vlU+5OMi9jUH6mDu+zwka20= X-Mailgun-Sending-Ip: 69.72.43.7 X-Mailgun-Sid: WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n06.prod.us-east-1.postgun.com with SMTP id 6172b0f414914866fa34b9f6 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 22 Oct 2021 12:39:16 GMT Sender: ppranees=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id C1595C43619; Fri, 22 Oct 2021 12:39:15 +0000 (UTC) Received: from ppranees-linux.qualcomm.com (blr-c-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: ppranees) by smtp.codeaurora.org (Postfix) with ESMTPSA id 1321DC43460; Fri, 22 Oct 2021 12:39:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 smtp.codeaurora.org 1321DC43460 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=codeaurora.org From: P Praneesh To: ath11k@lists.infradead.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, P Praneesh , Sathishkumar Muruganandam Subject: [PATCH v3 1/3] nl80211: Extended ROC support for 40-80 MHz bandwidth Date: Fri, 22 Oct 2021 18:07:05 +0530 Message-Id: <1634906227-22028-2-git-send-email-ppranees@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1634906227-22028-1-git-send-email-ppranees@codeaurora.org> References: <1634906227-22028-1-git-send-email-ppranees@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Replace struct ieee80211_channel with struct cfg80211_chan_def in remain on channel apis, because the channel width information is needed to handle centre frequency of 80MHz, and it is available in cfg80211_chan_def. Co-developed-by: Sathishkumar Muruganandam Signed-off-by: Sathishkumar Muruganandam Signed-off-by: P Praneesh --- drivers/net/wireless/ath/ath10k/mac.c | 3 +- drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +- drivers/net/wireless/ath/ath9k/main.c | 4 +- drivers/net/wireless/ath/wil6210/cfg80211.c | 3 +- .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 3 +- .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +- drivers/net/wireless/mac80211_hwsim.c | 3 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 3 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 3 +- drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 +- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 3 +- drivers/net/wireless/ti/wlcore/main.c | 3 +- include/net/cfg80211.h | 2 +- include/net/mac80211.h | 2 +- net/mac80211/driver-ops.h | 6 +-- net/mac80211/ieee80211_i.h | 4 +- net/mac80211/offchannel.c | 56 ++++++++++++++-------- net/mac80211/trace.h | 11 +++-- net/wireless/nl80211.c | 2 +- net/wireless/rdev-ops.h | 6 +-- net/wireless/trace.h | 6 +-- 22 files changed, 82 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c272b29..e652e21 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -7805,12 +7805,13 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw, static int ath10k_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type) { struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = (void *)vif->drv_priv; + struct ieee80211_channel *chan = chandef->chan; struct wmi_start_scan_arg arg; int ret = 0; u32 scan_time_msec; diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index fefdc67..4a2c132 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -3023,12 +3023,13 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); struct ath6kl *ar = ath6kl_priv(vif->ndev); + struct ieee80211_channel *chan = chandef->chan; u32 id; /* TODO: if already pending or ongoing remain-on-channel, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1398315..8f0fc64 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2466,11 +2466,13 @@ static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw, static int ath9k_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, int duration, + struct cfg80211_chan_def *chandef, + int duration, enum ieee80211_roc_type type) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_channel *chan = chandef->chan; int ret = 0; mutex_lock(&sc->mutex); diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 1ff2679..9ed172f 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1734,11 +1734,12 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy, static int wil_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { struct wil6210_priv *wil = wiphy_to_wil(wiphy); + struct ieee80211_channel *chan = chandef->chan; int rc; wil_dbg_misc(wil, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 9ac0d8c..e9cd84e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -972,10 +972,11 @@ brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) * @cookie: cookie. */ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *channel, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct ieee80211_channel *channel = chandef->chan; struct brcmf_p2p_info *p2p = &cfg->p2p; s32 err; u16 channel_nr; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h index d2ecee5..1646e6e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h @@ -156,7 +156,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy, struct cfg80211_scan_request *request, struct brcmf_cfg80211_vif *vif); int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *channel, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie); int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp, const struct brcmf_event_msg *e, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 70ebecb..09a775a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3792,7 +3792,7 @@ static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm, static int iwl_mvm_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *channel, + struct cfg80211_chan_def *chandefcfg, int duration, enum ieee80211_roc_type type) { @@ -3800,6 +3800,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct cfg80211_chan_def chandef; struct iwl_mvm_phy_ctxt *phy_ctxt; + struct ieee80211_channel *channel = chandefcfg->chan; bool band_change_removal; int ret, i; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ffa894f..9692b58 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2475,11 +2475,12 @@ static void hw_roc_done(struct work_struct *work) static int mac80211_hwsim_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type) { struct mac80211_hwsim_data *hwsim = hw->priv; + struct ieee80211_channel *chan = chandef->chan; mutex_lock(&hwsim->mutex); if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 0961f4a..aee8338 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -292,10 +292,11 @@ mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy, static int mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); + struct ieee80211_channel *chan = chandef->chan; int ret; if (!chan || !cookie) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index dada43d..e517268 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -1128,11 +1128,12 @@ mt7615_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) static int mt7615_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type) { struct mt7615_phy *phy = mt7615_hw_phy(hw); + struct ieee80211_channel *chan = chandef->chan; int err; if (test_and_set_bit(MT76_STATE_ROC, &phy->mt76->state)) diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index 96973ec..75e097b 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -1060,12 +1060,13 @@ static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie) static int remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { int ret = 0; struct wilc_vif *vif = netdev_priv(wdev->netdev); struct wilc_priv *priv = &vif->priv; + struct ieee80211_channel *chan = chandef->chan; u64 id; if (wdev->iftype == NL80211_IFTYPE_AP) { diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index b66975f..0284676 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -1788,11 +1788,12 @@ void rsi_roc_timeout(struct timer_list *t) } static int rsi_mac80211_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, int duration, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type) { struct rsi_hw *adapter = (struct rsi_hw *)hw->priv; struct rsi_common *common = (struct rsi_common *)adapter->priv; + struct ieee80211_channel *chan = chandef->chan; int status = 0; rsi_dbg(INFO_ZONE, "***** Remain on channel *****\n"); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 5669f17..48f2d42 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5640,13 +5640,14 @@ static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271 *wl = hw->priv; int channel, active_roc, ret = 0; + struct ieee80211_channel *chan = chandef->chan; channel = ieee80211_frequency_to_channel(chan->center_freq); diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 62dd842..c0a3146 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4181,7 +4181,7 @@ struct cfg80211_ops { int (*remain_on_channel)(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie); int (*cancel_remain_on_channel)(struct wiphy *wiphy, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index af0fc13..13bbab7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4107,7 +4107,7 @@ struct ieee80211_ops { int (*remain_on_channel)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, int duration, enum ieee80211_roc_type type); int (*cancel_remain_on_channel)(struct ieee80211_hw *hw, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index cd3731c..dff861c 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -675,7 +675,7 @@ static inline int drv_get_antenna(struct ieee80211_local *local, static inline int drv_remain_on_channel(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, enum ieee80211_roc_type type) { @@ -683,9 +683,9 @@ static inline int drv_remain_on_channel(struct ieee80211_local *local, might_sleep(); - trace_drv_remain_on_channel(local, sdata, chan, duration, type); + trace_drv_remain_on_channel(local, sdata, chandef, duration, type); ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, - chan, duration, type); + chandef, duration, type); trace_drv_return_int(local, ret); return ret; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 159af6c..8c2a8a8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -337,7 +337,7 @@ struct ieee80211_roc_work { struct ieee80211_sub_if_data *sdata; - struct ieee80211_channel *chan; + struct cfg80211_chan_def chandef; bool started, abort, hw_begun, notified; bool on_channel; @@ -1886,7 +1886,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local); void ieee80211_roc_purge(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); int ieee80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie); int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 853c9a3..4e1d010 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -178,12 +178,13 @@ static void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) if (!roc->mgmt_tx_cookie) cfg80211_remain_on_channel_expired(&roc->sdata->wdev, - roc->cookie, roc->chan, + roc->cookie, + roc->chandef.chan, GFP_KERNEL); else cfg80211_tx_mgmt_expired(&roc->sdata->wdev, roc->mgmt_tx_cookie, - roc->chan, GFP_KERNEL); + roc->chandef.chan, GFP_KERNEL); list_del(&roc->list); kfree(roc); @@ -211,6 +212,7 @@ static unsigned long ieee80211_end_finished_rocs(struct ieee80211_local *local, * ROC session before the actual requested time. In such a case * end the ROC session (disregarding the remaining time). */ + if (roc->abort || roc->hw_begun || remaining <= 0) ieee80211_roc_notify_destroy(roc); else @@ -235,21 +237,24 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local, static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc, unsigned long start_time) { + enum nl80211_band band; + if (WARN_ON(roc->notified)) return; + band = roc->chandef.chan->band; roc->start_time = start_time; roc->started = true; if (roc->mgmt_tx_cookie) { if (!WARN_ON(!roc->frame)) { ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7, - roc->chan->band); + band); roc->frame = NULL; } } else { cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie, - roc->chan, roc->req_duration, + roc->chandef.chan, roc->req_duration, GFP_KERNEL); } @@ -311,7 +316,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) list_for_each_entry(tmp, &local->roc_list, list) { if (tmp == roc) continue; - if (tmp->sdata != roc->sdata || tmp->chan != roc->chan) + if (tmp->sdata != roc->sdata || tmp->chandef.chan != roc->chandef.chan) break; max_dur = max(tmp->duration, max_dur); min_dur = min(tmp->duration, min_dur); @@ -319,7 +324,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) } if (local->ops->remain_on_channel) { - int ret = drv_remain_on_channel(local, roc->sdata, roc->chan, + int ret = drv_remain_on_channel(local, roc->sdata, + &roc->chandef, max_dur, type); if (ret) { @@ -331,7 +337,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) */ list_for_each_entry(tmp, &local->roc_list, list) { if (tmp->sdata != roc->sdata || - tmp->chan != roc->chan) + tmp->chandef.chan != roc->chandef.chan) break; tmp->started = true; tmp->abort = true; @@ -342,7 +348,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) /* we'll notify about the start once the HW calls back */ list_for_each_entry(tmp, &local->roc_list, list) { - if (tmp->sdata != roc->sdata || tmp->chan != roc->chan) + if (tmp->sdata != roc->sdata || + tmp->chandef.chan != roc->chandef.chan) break; tmp->started = true; } @@ -352,7 +359,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) * treat it as though the ROC operation started properly, so * other ROC operations won't interfere with this one. */ - roc->on_channel = roc->chan == local->_oper_chandef.chan && + roc->on_channel = roc->chandef.chan == local->_oper_chandef.chan && local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 && local->_oper_chandef.width != NL80211_CHAN_WIDTH_10; @@ -362,7 +369,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) if (!roc->on_channel) { ieee80211_offchannel_stop_vifs(local); - local->tmp_channel = roc->chan; + local->tmp_channel = roc->chandef.chan; ieee80211_hw_config(local, 0); } @@ -371,7 +378,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) /* tell userspace or send frame(s) */ list_for_each_entry(tmp, &local->roc_list, list) { - if (tmp->sdata != roc->sdata || tmp->chan != roc->chan) + if (tmp->sdata != roc->sdata || + tmp->chandef.chan != roc->chandef.chan) break; tmp->on_channel = roc->on_channel; @@ -526,12 +534,13 @@ ieee80211_coalesce_hw_started_roc(struct ieee80211_local *local, static int ieee80211_start_roc_work(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie, struct sk_buff *txskb, enum ieee80211_roc_type type) { struct ieee80211_roc_work *roc, *tmp; + struct ieee80211_channel *channel = chandef->chan; bool queued = false, combine_started = true; int ret; @@ -560,7 +569,10 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, if (!duration) duration = 10; - roc->chan = channel; + roc->chandef.chan = chandef->chan; + roc->chandef.width = chandef->width; + roc->chandef.center_freq1 = chandef->center_freq1; + roc->chandef.center_freq2 = chandef->center_freq2; roc->duration = duration; roc->req_duration = duration; roc->frame = txskb; @@ -590,7 +602,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, /* otherwise actually kick it off here * (for error handling) */ - ret = drv_remain_on_channel(local, sdata, channel, + ret = drv_remain_on_channel(local, sdata, chandef, duration, type); if (ret) { kfree(roc); @@ -606,7 +618,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, /* otherwise handle queueing */ list_for_each_entry(tmp, &local->roc_list, list) { - if (tmp->chan != channel || tmp->sdata != sdata) + if (tmp->chandef.chan != channel || tmp->sdata != sdata) continue; /* @@ -668,7 +680,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, } int ieee80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -676,9 +688,11 @@ int ieee80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, int ret; mutex_lock(&local->mtx); - ret = ieee80211_start_roc_work(local, sdata, chan, - duration, cookie, NULL, - IEEE80211_ROC_TYPE_NORMAL); + if (chandef) { + ret = ieee80211_start_roc_work(local, sdata, chandef, + duration, cookie, NULL, + IEEE80211_ROC_TYPE_NORMAL); + } mutex_unlock(&local->mtx); return ret; @@ -766,6 +780,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); struct ieee80211_local *local = sdata->local; + struct cfg80211_chan_def chandef; struct sk_buff *skb; struct sta_info *sta; const struct ieee80211_mgmt *mgmt = (void *)params->buf; @@ -935,8 +950,9 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, IEEE80211_SKB_CB(skb)->hw_queue = local->hw.offchannel_tx_hw_queue; + chandef.chan = params->chan; /* This will handle all kinds of coalescing and immediate TX */ - ret = ieee80211_start_roc_work(local, sdata, params->chan, + ret = ieee80211_start_roc_work(local, sdata, &chandef, params->wait, cookie, skb, IEEE80211_ROC_TYPE_MGMT_TX); if (ret) diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 9e8381b..2a18c85 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -1226,17 +1226,17 @@ TRACE_EVENT(drv_get_antenna, TRACE_EVENT(drv_remain_on_channel, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, enum ieee80211_roc_type type), - TP_ARGS(local, sdata, chan, duration, type), + TP_ARGS(local, sdata, chandef, duration, type), TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY + CHANDEF_ENTRY __field(int, center_freq) - __field(int, freq_offset) __field(unsigned int, duration) __field(u32, type) ), @@ -1244,8 +1244,9 @@ TRACE_EVENT(drv_remain_on_channel, TP_fast_assign( LOCAL_ASSIGN; VIF_ASSIGN; - __entry->center_freq = chan->center_freq; - __entry->freq_offset = chan->freq_offset; + CHANDEF_ASSIGN(chandef); + __entry->center_freq = chandef->chan->center_freq; + __entry->freq_offset = chandef->chan->freq_offset; __entry->duration = duration; __entry->type = type; ), diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bf7cd47..c71c24c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -11282,7 +11282,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, goto free_msg; } - err = rdev_remain_on_channel(rdev, wdev, chandef.chan, + err = rdev_remain_on_channel(rdev, wdev, &chandef, duration, &cookie); if (err) diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index ce6bf21..07bc258 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -710,12 +710,12 @@ static inline int rdev_flush_pmksa(struct cfg80211_registered_device *rdev, static inline int rdev_remain_on_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration, u64 *cookie) { int ret; - trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, duration); - ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, + trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chandef, duration); + ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chandef, duration, cookie); trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); return ret; diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 19b78d4..26b8f70 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -1900,9 +1900,9 @@ DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa, TRACE_EVENT(rdev_remain_on_channel, TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef, unsigned int duration), - TP_ARGS(wiphy, wdev, chan, duration), + TP_ARGS(wiphy, wdev, chandef, duration), TP_STRUCT__entry( WIPHY_ENTRY WDEV_ENTRY @@ -1912,7 +1912,7 @@ TRACE_EVENT(rdev_remain_on_channel, TP_fast_assign( WIPHY_ASSIGN; WDEV_ASSIGN; - CHAN_ASSIGN(chan); + CHAN_ASSIGN(chandef->chan); __entry->duration = duration; ), TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", duration: %u", From patchwork Fri Oct 22 12:37:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: P Praneesh X-Patchwork-Id: 12577691 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3259BC433F5 for ; Fri, 22 Oct 2021 12:39:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1CC6E60F4F for ; Fri, 22 Oct 2021 12:39:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232390AbhJVMmB (ORCPT ); Fri, 22 Oct 2021 08:42:01 -0400 Received: from m43-7.mailgun.net ([69.72.43.7]:52910 "EHLO m43-7.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232377AbhJVMmA (ORCPT ); Fri, 22 Oct 2021 08:42:00 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1634906383; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=hh1AyxhZ+WchS2mlgkOtAfyd302n9OhM6AjD211FV7M=; b=UpZpWGn4a2Jnw1TcyUJd8kVKK6wLi8dSAXCO6a8dbcL84aj8kDRUVwjgo9S52/qS2Dx+728A x2OKgoxREsciR3gmIrlTCrfheQw1vFp9ZMnwfxeU83mpFtALlDoApNg4hhuLVFHvk2OfMP6J xoQ5GCBSNbIWepIDdFMDyB/ZPBs= X-Mailgun-Sending-Ip: 69.72.43.7 X-Mailgun-Sid: WyI3YTAwOSIsICJsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmciLCAiYmU5ZTRhIl0= Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n04.prod.us-east-1.postgun.com with SMTP id 6172b0fa59612e010095c845 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 22 Oct 2021 12:39:22 GMT Sender: ppranees=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 1BA56C43618; Fri, 22 Oct 2021 12:39:21 +0000 (UTC) Received: from ppranees-linux.qualcomm.com (blr-c-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: ppranees) by smtp.codeaurora.org (Postfix) with ESMTPSA id D9EF2C43618; Fri, 22 Oct 2021 12:39:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 smtp.codeaurora.org D9EF2C43618 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=codeaurora.org From: P Praneesh To: ath11k@lists.infradead.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, P Praneesh , Karthikeyan Periyasamy Subject: [PATCH v3 2/3] ath11k: Refactor update channel list function Date: Fri, 22 Oct 2021 18:07:06 +0530 Message-Id: <1634906227-22028-3-git-send-email-ppranees@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1634906227-22028-1-git-send-email-ppranees@codeaurora.org> References: <1634906227-22028-1-git-send-email-ppranees@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org For sending scan channel list command to firmware through wmi, remain on channel's scan request parameter needs to be updated. Add scan_req_params as an argument to the existing update_scan_chan_list to update scan request parameter through wmi. Also, rename regulatory update scan channel list to the ath11k_wmi_update_scan_chan_list since it is moved to wmi file. Co-developed-by: Karthikeyan Periyasamy Signed-off-by: Karthikeyan Periyasamy Signed-off-by: P Praneesh --- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath11k/reg.c | 96 +------------------------------- drivers/net/wireless/ath/ath11k/reg.h | 1 - drivers/net/wireless/ath/ath11k/wmi.c | 101 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 4 ++ 5 files changed, 107 insertions(+), 97 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 1cc5560..fc2edef 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5256,7 +5256,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) /* TODO: Do we need to enable ANI? */ - ath11k_reg_update_chan_list(ar); + ath11k_wmi_update_scan_chan_list(ar, NULL); ar->num_started_vdevs = 0; ar->num_created_vdevs = 0; diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index a66b5bd..a453329 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -88,100 +88,6 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) "INIT Country code set to fw failed : %d\n", ret); } -int ath11k_reg_update_chan_list(struct ath11k *ar) -{ - struct ieee80211_supported_band **bands; - struct scan_chan_list_params *params; - struct ieee80211_channel *channel; - struct ieee80211_hw *hw = ar->hw; - struct channel_param *ch; - enum nl80211_band band; - int num_channels = 0; - int i, ret; - - bands = hw->wiphy->bands; - for (band = 0; band < NUM_NL80211_BANDS; band++) { - if (!bands[band]) - continue; - - for (i = 0; i < bands[band]->n_channels; i++) { - if (bands[band]->channels[i].flags & - IEEE80211_CHAN_DISABLED) - continue; - - num_channels++; - } - } - - if (WARN_ON(!num_channels)) - return -EINVAL; - - params = kzalloc(struct_size(params, ch_param, num_channels), - GFP_KERNEL); - if (!params) - return -ENOMEM; - - params->pdev_id = ar->pdev->pdev_id; - params->nallchans = num_channels; - - ch = params->ch_param; - - for (band = 0; band < NUM_NL80211_BANDS; band++) { - if (!bands[band]) - continue; - - for (i = 0; i < bands[band]->n_channels; i++) { - channel = &bands[band]->channels[i]; - - if (channel->flags & IEEE80211_CHAN_DISABLED) - continue; - - /* TODO: Set to true/false based on some condition? */ - ch->allow_ht = true; - ch->allow_vht = true; - ch->allow_he = true; - - ch->dfs_set = - !!(channel->flags & IEEE80211_CHAN_RADAR); - ch->is_chan_passive = !!(channel->flags & - IEEE80211_CHAN_NO_IR); - ch->is_chan_passive |= ch->dfs_set; - ch->mhz = channel->center_freq; - ch->cfreq1 = channel->center_freq; - ch->minpower = 0; - ch->maxpower = channel->max_power * 2; - ch->maxregpower = channel->max_reg_power * 2; - ch->antennamax = channel->max_antenna_gain * 2; - - /* TODO: Use appropriate phymodes */ - if (channel->band == NL80211_BAND_2GHZ) - ch->phy_mode = MODE_11G; - else - ch->phy_mode = MODE_11A; - - if (channel->band == NL80211_BAND_6GHZ && - cfg80211_channel_is_psc(channel)) - ch->psc_channel = true; - - ath11k_dbg(ar->ab, ATH11K_DBG_WMI, - "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", - i, params->nallchans, - ch->mhz, ch->maxpower, ch->maxregpower, - ch->antennamax, ch->phy_mode); - - ch++; - /* TODO: use quarrter/half rate, cfreq12, dfs_cfreq2 - * set_agile, reg_class_idx - */ - } - } - - ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); - kfree(params); - - return ret; -} - static void ath11k_copy_regd(struct ieee80211_regdomain *regd_orig, struct ieee80211_regdomain *regd_copy) { @@ -256,7 +162,7 @@ int ath11k_regd_update(struct ath11k *ar) goto err; if (ar->state == ATH11K_STATE_ON) { - ret = ath11k_reg_update_chan_list(ar); + ret = ath11k_wmi_update_scan_chan_list(ar, NULL); if (ret) goto err; } diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h index 5fb9dc0..44830e6 100644 --- a/drivers/net/wireless/ath/ath11k/reg.h +++ b/drivers/net/wireless/ath/ath11k/reg.h @@ -32,5 +32,4 @@ struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, struct cur_regulatory_info *reg_info, bool intersect); int ath11k_regd_update(struct ath11k *ar); -int ath11k_reg_update_chan_list(struct ath11k *ar); #endif diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 5ae2ef4..2fe32cb 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -1950,6 +1950,107 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, return ret; } +int ath11k_wmi_update_scan_chan_list(struct ath11k *ar, + struct scan_req_params *arg) +{ + struct ieee80211_supported_band **bands; + struct scan_chan_list_params *params; + struct channel_param *ch; + struct cfg80211_chan_def *chandef; + struct ieee80211_channel *channel, *req_channel; + enum nl80211_band band; + int num_channels = 0; + int params_len, i, ret; + bool found = false; + + bands = ar->hw->wiphy->bands; + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!bands[band]) + continue; + for (i = 0; i < bands[band]->n_channels; i++) { + if (bands[band]->channels[i].flags & + IEEE80211_CHAN_DISABLED) + continue; + num_channels++; + } + } + + if (WARN_ON(!num_channels)) + return -EINVAL; + + params_len = sizeof(struct scan_chan_list_params) + + num_channels * sizeof(struct channel_param); + params = kzalloc(params_len, GFP_KERNEL); + + if (!params) + return -ENOMEM; + + params->pdev_id = ar->pdev->pdev_id; + params->nallchans = num_channels; + + ch = params->ch_param; + chandef = arg ? arg->chandef : NULL; + req_channel = chandef ? chandef->chan : NULL; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!bands[band]) + continue; + for (i = 0; i < bands[band]->n_channels; i++) { + channel = &bands[band]->channels[i]; + + if (channel->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (req_channel && !found && + req_channel->center_freq == channel->center_freq) { + ch->mhz = arg->freq; + ch->cfreq1 = chandef->center_freq1; + ch->cfreq2 = chandef->center_freq2; + + ch->phy_mode = arg->phymode; + channel = req_channel; + found = true; + } else { + ch->mhz = channel->center_freq; + ch->cfreq1 = channel->center_freq; + ch->phy_mode = (channel->band == NL80211_BAND_2GHZ) ? + MODE_11G : MODE_11A; + } + + /* TODO: Set to true/false based on some condition? */ + ch->allow_ht = true; + ch->allow_vht = true; + ch->allow_he = true; + + ch->dfs_set = !!(channel->flags & IEEE80211_CHAN_RADAR); + ch->is_chan_passive = !!(channel->flags & IEEE80211_CHAN_NO_IR); + ch->is_chan_passive |= ch->dfs_set; + ch->minpower = 0; + ch->maxpower = channel->max_power; + ch->maxregpower = channel->max_reg_power; + ch->antennamax = channel->max_antenna_gain; + + if (channel->band == NL80211_BAND_6GHZ && + cfg80211_channel_is_psc(channel)) + ch->psc_channel = true; + + ath11k_dbg(ar->ab, ATH11K_DBG_WMI, + "mac channel [%d/%d] freq %d maxpower %d regpower %d antenna %d mode %d flag 0x%x chandef: %pK\n", + i, params->nallchans, + ch->mhz, ch->maxpower, ch->maxregpower, + ch->antennamax, ch->phy_mode, channel->flags, + chandef); + + ch++; + } + } + + ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); + kfree(params); + + return ret; +} + void ath11k_wmi_start_scan_init(struct ath11k *ar, struct scan_req_params *arg) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 0584e68..aeec4e9 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -3311,6 +3311,9 @@ struct scan_req_params { u32 num_hint_bssid; struct hint_short_ssid hint_s_ssid[WLAN_SCAN_MAX_HINT_S_SSID]; struct hint_bssid hint_bssid[WLAN_SCAN_MAX_HINT_BSSID]; + u32 phymode; + u32 freq; + struct cfg80211_chan_def *chandef; }; struct wmi_ssid_arg { @@ -5378,6 +5381,7 @@ int ath11k_wmi_send_peer_delete_cmd(struct ath11k *ar, const u8 *peer_addr, u8 vdev_id); int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id); void ath11k_wmi_start_scan_init(struct ath11k *ar, struct scan_req_params *arg); +int ath11k_wmi_update_scan_chan_list(struct ath11k *ar, struct scan_req_params *arg); int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, struct scan_req_params *params); int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar,