This is important for brcmfmac as the firmware may pick different
channel than requested. This has been tested with BCM4366B1 (in D-Link
DIR-885L).

Signed-off-by: Rafał Miłecki <zaj...@gmail.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 597495d..4fb9e3a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4892,6 +4892,64 @@ exit:
        return err;
 }
 
+static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
+                                     struct wireless_dev *wdev,
+                                     struct cfg80211_chan_def *chandef)
+{
+       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+       struct net_device *ndev = wdev->netdev;
+       struct brcmf_if *ifp = netdev_priv(ndev);
+       struct brcmu_chan ch;
+       enum nl80211_band band = 0;
+       enum nl80211_chan_width width = 0;
+       u32 chanspec;
+       int freq, err;
+
+       err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
+       if (err) {
+               brcmf_err("chanspec failed (%d)\n", err);
+               return err;
+       }
+
+       ch.chspec = chanspec;
+       cfg->d11inf.decchspec(&ch);
+
+       switch (ch.band) {
+       case BRCMU_CHAN_BAND_2G:
+               band = NL80211_BAND_2GHZ;
+               break;
+       case BRCMU_CHAN_BAND_5G:
+               band = NL80211_BAND_5GHZ;
+               break;
+       }
+
+       switch (ch.bw) {
+       case BRCMU_CHAN_BW_80:
+               width = NL80211_CHAN_WIDTH_80;
+               break;
+       case BRCMU_CHAN_BW_40:
+               width = NL80211_CHAN_WIDTH_40;
+               break;
+       case BRCMU_CHAN_BW_20:
+               width = NL80211_CHAN_WIDTH_20;
+               break;
+       case BRCMU_CHAN_BW_80P80:
+               width = NL80211_CHAN_WIDTH_80P80;
+               break;
+       case BRCMU_CHAN_BW_160:
+               width = NL80211_CHAN_WIDTH_160;
+               break;
+       }
+
+       freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
+       chandef->chan = ieee80211_get_channel(wiphy, freq);
+       chandef->width = width;
+       chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
+       chandef->center_freq2 = 0;
+
+       return 0;
+}
+
 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
                                           struct wireless_dev *wdev,
                                           enum nl80211_crit_proto_id proto,
@@ -5054,6 +5112,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
        .mgmt_tx = brcmf_cfg80211_mgmt_tx,
        .remain_on_channel = brcmf_p2p_remain_on_channel,
        .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
+       .get_channel = brcmf_cfg80211_get_channel,
        .start_p2p_device = brcmf_p2p_start_device,
        .stop_p2p_device = brcmf_p2p_stop_device,
        .crit_proto_start = brcmf_cfg80211_crit_proto_start,
-- 
1.8.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to