Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac802...
authorJohn W. Linville <linville@tuxdriver.com>
Wed, 10 Apr 2013 18:09:54 +0000 (14:09 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 10 Apr 2013 18:09:54 +0000 (14:09 -0400)
Conflicts:
drivers/net/wireless/ath/carl9170/debug.c
drivers/net/wireless/ath/carl9170/main.c
net/mac80211/ieee80211_i.h

84 files changed:
drivers/net/wireless/adm8211.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ar5523/ar5523.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/common.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/carl9170/debug.c
drivers/net/wireless/ath/carl9170/mac.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/phy.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_ht.c
drivers/net/wireless/b43/phy_lcn.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/iwlegacy/3945-rs.c
drivers/net/wireless/iwlegacy/4965-rs.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/dvm/rs.c
drivers/net/wireless/iwlwifi/dvm/rxon.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl818x/rtl8180/dev.c
drivers/net/wireless/rtl818x/rtl8180/grf5101.c
drivers/net/wireless/rtl818x/rtl8180/max2820.c
drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
drivers/net/wireless/rtl818x/rtl8180/sa2400.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/rtlwifi/rtl8192de/trx.c
drivers/net/wireless/rtlwifi/rtl8192se/trx.c
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
drivers/net/wireless/ti/wl1251/main.c
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/zd1211rw/zd_mac.c
include/linux/ieee80211.h
include/net/cfg80211.h
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_sta.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mlme.c
net/mac80211/offchannel.c
net/mac80211/pm.c
net/mac80211/scan.c
net/mac80211/trace.h
net/mac80211/tx.c
net/mac80211/util.c

index 3d339e04efb7a760af7b887e31f7956973df424d..f9a24e599dee4c7acf9b8a5bf0a0caa2306d01e5 100644 (file)
@@ -1293,7 +1293,8 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
 {
        struct adm8211_priv *priv = dev->priv;
        struct ieee80211_conf *conf = &dev->conf;
-       int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       int channel =
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
 
        if (channel != priv->channel) {
                priv->channel = channel;
index 5ac5f7ae2721a2e8db91536a10ed94b6116960af..34c8a33cac06f67dfb5e4dc718767d6457449d86 100644 (file)
@@ -1943,12 +1943,12 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
        struct at76_priv *priv = hw->priv;
 
        at76_dbg(DBG_MAC80211, "%s(): channel %d",
-                __func__, hw->conf.channel->hw_value);
+                __func__, hw->conf.chandef.chan->hw_value);
        at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
 
        mutex_lock(&priv->mtx);
 
-       priv->channel = hw->conf.channel->hw_value;
+       priv->channel = hw->conf.chandef.chan->hw_value;
 
        if (is_valid_ether_addr(priv->bssid))
                at76_join(priv);
index afd1e36d308faefdf20fd2f7f4b4c748ef72464a..17d7fece35d2c203eedef5fed0725074a0067cf7 100644 (file)
@@ -457,14 +457,14 @@ static int ar5523_set_chan(struct ar5523 *ar)
        memset(&reset, 0, sizeof(reset));
        reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ);
        reset.flags |= cpu_to_be32(UATH_CHAN_OFDM);
-       reset.freq = cpu_to_be32(conf->channel->center_freq);
+       reset.freq = cpu_to_be32(conf->chandef.chan->center_freq);
        reset.maxrdpower = cpu_to_be32(50);     /* XXX */
        reset.channelchange = cpu_to_be32(1);
        reset.keeprccontent = cpu_to_be32(0);
 
        ar5523_dbg(ar, "set chan flags 0x%x freq %d\n",
                   be32_to_cpu(reset.flags),
-                  conf->channel->center_freq);
+                  conf->chandef.chan->center_freq);
        return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0);
 }
 
@@ -594,7 +594,7 @@ static void ar5523_data_rx_cb(struct urb *urb)
        rx_status = IEEE80211_SKB_RXCB(data->skb);
        memset(rx_status, 0, sizeof(*rx_status));
        rx_status->freq = be32_to_cpu(desc->channel);
-       rx_status->band = hw->conf.channel->band;
+       rx_status->band = hw->conf.chandef.chan->band;
        rx_status->signal = -95 + be32_to_cpu(desc->rssi);
 
        ieee80211_rx_irqsafe(hw, data->skb);
@@ -1153,13 +1153,13 @@ static int ar5523_get_wlan_mode(struct ar5523 *ar,
        struct ieee80211_sta *sta;
        u32 sta_rate_set;
 
-       band = ar->hw->wiphy->bands[ar->hw->conf.channel->band];
+       band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band];
        sta = ieee80211_find_sta(ar->vif, bss_conf->bssid);
        if (!sta) {
                ar5523_info(ar, "STA not found!\n");
                return WLAN_MODE_11b;
        }
-       sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band];
+       sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band];
 
        for (bit = 0; bit < band->n_bitrates; bit++) {
                if (sta_rate_set & 1) {
@@ -1197,11 +1197,11 @@ static void ar5523_create_rateset(struct ar5523 *ar,
                ar5523_info(ar, "STA not found. Cannot set rates\n");
                sta_rate_set = bss_conf->basic_rates;
        } else
-               sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band];
+               sta_rate_set = sta->supp_rates[ar->hw->conf.chandef.chan->band];
 
        ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set);
 
-       band = ar->hw->wiphy->bands[ar->hw->conf.channel->band];
+       band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band];
        for (bit = 0; bit < band->n_bitrates; bit++) {
                BUG_ON(i >= AR5523_MAX_NRATES);
                ar5523_dbg(ar, "Considering rate %d : %d\n",
index 1d264c0f5a9b468285296e706cfef2d367678085..9b20d9ee2719d0ddc78c799ecb24307882f1b503 100644 (file)
@@ -2639,7 +2639,7 @@ int ath5k_start(struct ieee80211_hw *hw)
         * be followed by initialization of the appropriate bits
         * and then setup of the interrupt mask.
         */
-       ah->curchan = ah->hw->conf.channel;
+       ah->curchan = ah->hw->conf.chandef.chan;
        ah->imask = AR5K_INT_RXOK
                | AR5K_INT_RXERR
                | AR5K_INT_RXEOL
index 4264341533eae5384af1a675db255496fa559245..06f86f435711e805c958ee5f98354a60aafe5f41 100644 (file)
@@ -202,7 +202,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
        mutex_lock(&ah->lock);
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ret = ath5k_chan_set(ah, conf->channel);
+               ret = ath5k_chan_set(ah, conf->chandef.chan);
                if (ret < 0)
                        goto unlock;
        }
@@ -678,7 +678,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
 
        memcpy(survey, &ah->survey, sizeof(*survey));
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->noise = ah->ah_noise_floor;
        survey->filled = SURVEY_INFO_NOISE_DBM |
                        SURVEY_INFO_CHANNEL_TIME |
index 5f05c26d1ec4a9a30e67c294d407c082bbcc8d2a..2ff570f7f8ffb49e563d0f7e6cb4d3bace3cc6da 100644 (file)
@@ -79,7 +79,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
        u8 chainmask = ah->txchainmask;
        u8 rate = 0;
 
-       sband = &sc->sbands[common->hw->conf.channel->band];
+       sband = &sc->sbands[common->hw->conf.chandef.chan->band];
        rate = sband->bitrates[rateidx].hw_value;
        if (vif->bss_conf.use_short_preamble)
                rate |= sband->bitrates[rateidx].hw_value_short;
index 7bdd726c7a8f747a13f96a6ed8c921a23dc6ddff..7304e7585009c03ec1faeaa7d013e5ded4eea5d3 100644 (file)
@@ -208,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
                return true;
 
        ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n",
-               currCal->calData->calType, conf->channel->center_freq);
+               currCal->calData->calType, conf->chandef.chan->center_freq);
 
        ah->caldata->CalValid &= ~currCal->calData->calType;
        currCal->calState = CAL_WAITING;
index 905f1b313961914ef3faf81aa6ed210248846196..6c78fe7ca54d4bbb0bf1d62cb67ab8e7cb6cdd05 100644 (file)
@@ -133,13 +133,14 @@ EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
 struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
                                               struct ath_hw *ah)
 {
-       struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ieee80211_channel *curchan = hw->conf.chandef.chan;
        struct ath9k_channel *channel;
        u8 chan_idx;
 
        chan_idx = curchan->hw_value;
        channel = &ah->channels[chan_idx];
-       ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type);
+       ath9k_cmn_update_ichannel(channel, curchan,
+                                 cfg80211_get_chandef_type(&hw->conf.chandef));
 
        return channel;
 }
index a8016d70088aa3d492d15ff76f6f16f8f3c2df2f..098e3545e5127011767ac9dde2bb449287812091 100644 (file)
@@ -190,7 +190,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
 {
        struct ath_hw *ah = priv->ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ieee80211_channel *channel = priv->hw->conf.channel;
+       struct ieee80211_channel *channel = priv->hw->conf.chandef.chan;
        struct ath9k_hw_cal_data *caldata = NULL;
        enum htc_phymode mode;
        __be16 htc_mode;
@@ -250,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
        struct ath_common *common = ath9k_hw_common(ah);
        struct ieee80211_conf *conf = &common->hw->conf;
        bool fastcc;
-       struct ieee80211_channel *channel = hw->conf.channel;
+       struct ieee80211_channel *channel = hw->conf.chandef.chan;
        struct ath9k_hw_cal_data *caldata = NULL;
        enum htc_phymode mode;
        __be16 htc_mode;
@@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
        u32 caps = 0;
        int i, j;
 
-       sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
+       sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];
 
        for (i = 0, j = 0; i < sband->n_bitrates; i++) {
                if (sta->supp_rates[sband->band] & BIT(i)) {
@@ -904,7 +904,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
        struct ath9k_htc_priv *priv = hw->priv;
        struct ath_hw *ah = priv->ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ieee80211_channel *curchan = hw->conf.chandef.chan;
        struct ath9k_channel *init_channel;
        int ret = 0;
        enum htc_phymode mode;
@@ -1193,15 +1193,17 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {
-               struct ieee80211_channel *curchan = hw->conf.channel;
+               struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+               enum nl80211_channel_type channel_type =
+                       cfg80211_get_chandef_type(&hw->conf.chandef);
                int pos = curchan->hw_value;
 
                ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
                        curchan->center_freq);
 
                ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
-                                         hw->conf.channel,
-                                         hw->conf.channel_type);
+                                         hw->conf.chandef.chan,
+                                         channel_type);
 
                if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
                        ath_err(common, "Unable to set channel\n");
index bd8251c1c7494fe69a140d4089d6d2d586c0eaae..2774dd13c786090b8102cf809aa5448980c21996 100644 (file)
@@ -490,7 +490,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
                if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
                        rate->flags |= IEEE80211_TX_RC_SHORT_GI;
        } else {
-               if (cur_conf->channel->band == IEEE80211_BAND_5GHZ)
+               if (cur_conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
                        rate->idx += 4; /* No CCK rates */
        }
 
@@ -939,7 +939,7 @@ static void ath9k_process_rate(struct ieee80211_hw *hw,
                return;
        }
 
-       band = hw->conf.channel->band;
+       band = hw->conf.chandef.chan->band;
        sband = hw->wiphy->bands[band];
 
        for (i = 0; i < sband->n_bitrates; i++) {
@@ -1082,8 +1082,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
        }
 
        rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
-       rx_status->band = hw->conf.channel->band;
-       rx_status->freq = hw->conf.channel->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
        rx_status->signal =  rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
        rx_status->antenna = rxbuf->rxstatus.rs_antenna;
        rx_status->flag |= RX_FLAG_MACTIME_END;
index 3473a797651af0a4cbf3c5119bff352f99cc3c98..8a980a4bf4ec2aca66ac52f0444c752bfecc0435 100644 (file)
@@ -139,7 +139,7 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
                clockrate = 117;
        else if (!ah->curchan) /* should really check for CCK instead */
                clockrate = ATH9K_CLOCK_RATE_CCK;
-       else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+       else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ)
                clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
        else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
                clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
@@ -1110,7 +1110,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
         * BA frames in some implementations, but it has been found to fix ACK
         * timeout issues in other cases as well.
         */
-       if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ &&
+       if (conf->chandef.chan &&
+           conf->chandef.chan->band == IEEE80211_BAND_2GHZ &&
            !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
                acktimeout += 64 - sifstime - ah->slottime;
                ctstimeout += 48 - sifstime - ah->slottime;
index 7fdac6c7b3ea5dc030136d66c4574c4d8373a82e..849259b07370f0966e4b17890e2567e19d9f9cdb 100644 (file)
@@ -214,7 +214,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
        txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
 
        memset(tx_info, 0, sizeof(*tx_info));
-       tx_info->band = hw->conf.channel->band;
+       tx_info->band = hw->conf.chandef.chan->band;
        tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
        tx_info->control.rates[0].idx = 0;
        tx_info->control.rates[0].count = 1;
index 1bf52c88004a7b650d2385dbb459f110e0a033b5..a383483d03878d7f0908408e55ffd4a1a5c885be 100644 (file)
@@ -589,7 +589,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ieee80211_channel *curchan = hw->conf.chandef.chan;
        struct ath9k_channel *init_channel;
        int r;
 
@@ -1188,7 +1188,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
-               struct ieee80211_channel *curchan = hw->conf.channel;
+               struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+               enum nl80211_channel_type channel_type =
+                       cfg80211_get_chandef_type(&conf->chandef);
                int pos = curchan->hw_value;
                int old_pos = -1;
                unsigned long flags;
@@ -1197,7 +1199,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                        old_pos = ah->curchan - &ah->channels[0];
 
                ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n",
-                       curchan->center_freq, conf->channel_type);
+                       curchan->center_freq, channel_type);
 
                /* update survey stats for the old channel before switching */
                spin_lock_irqsave(&common->cc_lock, flags);
@@ -1212,7 +1214,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                        ath9k_hw_getnf(ah, ah->curchan);
 
                ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
-                                         curchan, conf->channel_type);
+                                         curchan, channel_type);
 
                /*
                 * If the operating channel changes, change the survey in-use flags
index 96ac433ba7f685ee454e3219bdea0e12879c3956..aa4d368d8d3df53290a35fb7248c0e733d55deed 100644 (file)
@@ -814,7 +814,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
         * So, set fourth rate in series to be same as third one for
         * above conditions.
         */
-       if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
+       if ((sc->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) &&
            (conf_is_ht(&sc->hw->conf))) {
                u8 dot11rate = rate_table->info[rix].dot11rate;
                u8 phy = rate_table->info[rix].phy;
@@ -1328,7 +1328,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
 
                ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
                        "Operating HT Bandwidth changed to: %d\n",
-                       sc->hw->conf.channel_type);
+                       cfg80211_get_chandef_type(&sc->hw->conf.chandef));
        }
 }
 
index ee7ca5aecdb0648fa4f65b44c5febc4990d46429..e656e4891568c2be6106b5e7632954548ff23eab 100644 (file)
@@ -863,7 +863,7 @@ static int ath9k_process_rate(struct ath_common *common,
        unsigned int i = 0;
        struct ath_softc __maybe_unused *sc = common->priv;
 
-       band = hw->conf.channel->band;
+       band = hw->conf.chandef.chan->band;
        sband = hw->wiphy->bands[band];
 
        if (rx_stats->rs_rate & 0x80) {
@@ -958,8 +958,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
        if (ath9k_process_rate(common, hw, rx_stats, rx_status))
                return -EINVAL;
 
-       rx_status->band = hw->conf.channel->band;
-       rx_status->freq = hw->conf.channel->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
        rx_status->signal = ah->noise + rx_stats->rs_rssi;
        rx_status->antenna = rx_stats->rs_antenna;
        rx_status->flag |= RX_FLAG_MACTIME_END;
index 40109be81f7c7f468386ebb07fcc7c4ebcda6dcf..3d70cd277fd73745b96eeb0fe2042eb9789b68f4 100644 (file)
@@ -654,8 +654,8 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
                goto out;
 
        case 'P':
-               err = carl9170_set_channel(ar, ar->hw->conf.channel,
-                                          ar->hw->conf.channel_type);
+               err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
+                       cfg80211_get_chandef_type(&ar->hw->conf.chandef));
                if (err < 0)
                        count = err;
 
index 24d75ab94f0d36a22f7d025eea336d5197f83f2b..a2f005703c04c38638e0052713e5202ac0335465 100644 (file)
@@ -48,7 +48,7 @@ int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
        if (conf_is_ht40(&ar->hw->conf))
                val = 0x010a;
        else {
-               if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+               if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
                        val = 0x105;
                else
                        val = 0x104;
@@ -66,7 +66,7 @@ int carl9170_set_rts_cts_rate(struct ar9170 *ar)
                rts_rate = 0x1da;
                cts_rate = 0x10a;
        } else {
-               if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+               if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) {
                        /* 11 mbit CCK */
                        rts_rate = 033;
                        cts_rate = 003;
@@ -93,7 +93,7 @@ int carl9170_set_slot_time(struct ar9170 *ar)
                return 0;
        }
 
-       if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+       if ((ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ) ||
            vif->bss_conf.use_short_slot)
                slottime = 9;
 
@@ -120,7 +120,7 @@ int carl9170_set_mac_rates(struct ar9170 *ar)
        basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
        rcu_read_unlock();
 
-       if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+       if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ)
                mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
        else
                mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
index 699c557bc2c778bf51494626a6b0b6d6056dd1da..e9010a481dfdf475d61f567bb0f5f11f2e44dded 100644 (file)
@@ -929,6 +929,9 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               enum nl80211_channel_type channel_type =
+                       cfg80211_get_chandef_type(&hw->conf.chandef);
+
                /* adjust slot time for 5 GHz */
                err = carl9170_set_slot_time(ar);
                if (err)
@@ -938,8 +941,8 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
                if (err)
                        goto out;
 
-               err = carl9170_set_channel(ar, hw->conf.channel,
-                                          hw->conf.channel_type);
+               err = carl9170_set_channel(ar, hw->conf.chandef.chan,
+                                          channel_type);
                if (err)
                        goto out;
 
@@ -957,7 +960,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
+               err = carl9170_set_mac_tpc(ar, ar->hw->conf.chandef.chan);
                if (err)
                        goto out;
        }
index 07f82234c860e35eebbddded079ef267dc2f13ee..ab4ee7d39ad385a0da2c92f80ef0ce5bade8f5b4 100644 (file)
@@ -1331,7 +1331,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
         * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
         */
        ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
-                                       ar->hw->conf.channel->band);
+                                       ar->hw->conf.chandef.chan->band);
 
        /* ctl group not found - either invalid band (NO_CTL) or ww roaming */
        if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
@@ -1341,7 +1341,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
                /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
                return;
 
-       if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+       if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) {
                modes = mode_list_2ghz;
                nr_modes = ARRAY_SIZE(mode_list_2ghz);
        } else {
index f5e840104f4be2f3a266371b8dae386329da26be..7f3d461f7e8d13debc385305bb18140832df3748 100644 (file)
@@ -980,7 +980,7 @@ static inline int b43_is_mode(struct b43_wl *wl, int type)
  */
 static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
 {
-       return wl->hw->conf.channel->band;
+       return wl->hw->conf.chandef.chan->band;
 }
 
 static inline int b43_bus_may_powerdown(struct b43_wldev *wldev)
index 4ac73d2f86058f371226b56d7d55cf61d8de13f5..d377f77d30b536de0ddaeb1ed9cef382619ccfa6 100644 (file)
@@ -3852,7 +3852,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        dev = wl->current_dev;
 
        /* Switch the band (if necessary). This might change the active core. */
-       err = b43_switch_band(wl, conf->channel);
+       err = b43_switch_band(wl, conf->chandef.chan);
        if (err)
                goto out_unlock_mutex;
 
@@ -3882,8 +3882,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
 
        /* Switch to the requested channel.
         * The firmware takes care of races with the TX handler. */
-       if (conf->channel->hw_value != phy->channel)
-               b43_switch_channel(dev, conf->channel->hw_value);
+       if (conf->chandef.chan->hw_value != phy->channel)
+               b43_switch_channel(dev, conf->chandef.chan->hw_value);
 
        dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
 
@@ -5006,7 +5006,7 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = SURVEY_INFO_NOISE_DBM;
        survey->noise = dev->stats.link_noise;
 
index b8667706fc2783379d7b56bacc812e8affa40eba..83239fd870402ec5a59580bb12ba54826c55d184 100644 (file)
@@ -1011,8 +1011,9 @@ static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
 static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev,
                                        unsigned int new_channel)
 {
-       struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
-       enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+       struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+       enum nl80211_channel_type channel_type =
+               cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef);
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
                if ((new_channel < 1) || (new_channel > 14))
index a13e28ef6246af2dd344025d1b394403572fd5f3..0bafa3b17035db8d5767da2632da343dd1ae70c7 100644 (file)
@@ -808,8 +808,9 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on)
 static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev,
                                        unsigned int new_channel)
 {
-       struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
-       enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+       struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+       enum nl80211_channel_type channel_type =
+               cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef);
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
                if ((new_channel < 1) || (new_channel > 14))
index f9339e7ea6af082a8c7360b877b4e00b48c710cb..45d63d70a66bd80e326cc2df4292287742b01595 100644 (file)
@@ -5526,8 +5526,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
 static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
                                      unsigned int new_channel)
 {
-       struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
-       enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
+       struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+       enum nl80211_channel_type channel_type =
+               cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef);
 
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
                if ((new_channel < 1) || (new_channel > 14))
index 8c3f70e1a013078ea85c92a2ac0447e6abd9f754..572668821862e3c8c9b75b46ec1d1e60ea25dcea 100644 (file)
@@ -2720,7 +2720,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
                goto out_unlock_mutex;
 
        /* Switch the PHY mode (if necessary). */
-       switch (conf->channel->band) {
+       switch (conf->chandef.chan->band) {
        case IEEE80211_BAND_2GHZ:
                if (phy->type == B43legacy_PHYTYPE_B)
                        new_phymode = B43legacy_PHYMODE_B;
@@ -2748,8 +2748,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
 
        /* Switch to the requested channel.
         * The firmware takes care of races with the TX handler. */
-       if (conf->channel->hw_value != phy->channel)
-               b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
+       if (conf->chandef.chan->hw_value != phy->channel)
+               b43legacy_radio_selectchannel(dev, conf->chandef.chan->hw_value,
+                                             0);
 
        dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
 
@@ -3558,7 +3559,7 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = SURVEY_INFO_NOISE_DBM;
        survey->noise = dev->stats.link_noise;
 
index 10ee314c42298a7d1d2e7264ae8093d36ed586a2..cc87926f505562335a02c605541c739725cf1a03 100644 (file)
@@ -379,7 +379,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
                         u8 local_constraint_qdbm)
 {
        struct brcms_c_info *wlc = wlc_cm->wlc;
-       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
+       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
        struct txpwr_limits txpwr;
 
        brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
@@ -404,7 +404,7 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
                       struct txpwr_limits *txpwr)
 {
        struct brcms_c_info *wlc = wlc_cm->wlc;
-       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
+       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
        uint i;
        uint chan;
        int maxpwr;
index cd837860cd42cd1d1667ba0960c31efb9592ab04..db663230088dc9c3e8f7abae2f0d3d2f0e3c221f 100644 (file)
@@ -424,10 +424,10 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
                                  new_int);
        }
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               if (conf->channel_type == NL80211_CHAN_HT20 ||
-                   conf->channel_type == NL80211_CHAN_NO_HT)
+               if (conf->chandef.width == NL80211_CHAN_WIDTH_20 ||
+                   conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
                        err = brcms_c_set_channel(wl->wlc,
-                                                 conf->channel->hw_value);
+                                                 conf->chandef.chan->hw_value);
                else
                        err = -ENOTSUPP;
        }
index 59d438409dfbe144c20dba2b71b8094859d97dd0..28e7aeedd184c4cc942ec67259dc978ca542794e 100644 (file)
@@ -5135,7 +5135,7 @@ int brcms_c_up(struct brcms_c_info *wlc)
        wlc->pub->up = true;
 
        if (wlc->bandinit_pending) {
-               ch = wlc->pub->ieee_hw->conf.channel;
+               ch = wlc->pub->ieee_hw->conf.chandef.chan;
                brcms_c_suspend_mac_and_wait(wlc);
                brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value));
                wlc->bandinit_pending = false;
@@ -7919,7 +7919,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
 void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
 {
        struct bcma_device *core = wlc->hw->d11core;
-       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
+       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.chandef.chan;
        u16 chanspec;
 
        brcms_dbg_info(core, "wl%d\n", wlc->pub->unit);
index d4fd29ad90dc6cf6b3182f41fe68491ee138cf1a..c9f197d9ca1eecddf8d6f651c4f8598950986502 100644 (file)
@@ -347,7 +347,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
 
        psta = (struct il3945_sta_priv *)sta->drv_priv;
        rs_sta = &psta->rs_sta;
-       sband = hw->wiphy->bands[conf->channel->band];
+       sband = hw->wiphy->bands[conf->chandef.chan->band];
 
        rs_sta->il = il;
 
index 6c7493c2d698e6a2c83de679131890726aff6456..1fc0b227e120d5d74054be24356f07ef2852824f 100644 (file)
@@ -2300,7 +2300,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
 
        sta_priv = (struct il_station_priv *)sta->drv_priv;
        lq_sta = &sta_priv->lq_sta;
-       sband = hw->wiphy->bands[conf->channel->band];
+       sband = hw->wiphy->bands[conf->chandef.chan->band];
 
        lq_sta->lq.sta_id = sta_id;
 
index 1a518feb4b261b679717022102552ef32e9486d9..65becfe57a7d31bdec6b0ff8b04c341e1f25e674 100644 (file)
@@ -4974,7 +4974,7 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
        struct il_priv *il = hw->priv;
        const struct il_channel_info *ch_info;
        struct ieee80211_conf *conf = &hw->conf;
-       struct ieee80211_channel *channel = conf->channel;
+       struct ieee80211_channel *channel = conf->chandef.chan;
        struct il_ht_config *ht_conf = &il->current_ht_config;
        unsigned long flags = 0;
        int ret = 0;
index abe3042672619b2029e5ba0896203d497592044f..907bd6e50aadce652145a32d496223b0a365e92b 100644 (file)
@@ -2831,7 +2831,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
 
        sta_priv = (struct iwl_station_priv *) sta->drv_priv;
        lq_sta = &sta_priv->lq_sta;
-       sband = hw->wiphy->bands[conf->channel->band];
+       sband = hw->wiphy->bands[conf->chandef.chan->band];
 
 
        lq_sta->lq.sta_id = sta_id;
index a82b6b39d4ff6df26375334963aa3d42114f7c32..2a349004f18d765fa5723ef3942e5abcbb38c180 100644 (file)
@@ -78,8 +78,9 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
                ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
-       ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value);
-       priv->band = priv->hw->conf.channel->band;
+       ctx->staging.channel =
+               cpu_to_le16(priv->hw->conf.chandef.chan->hw_value);
+       priv->band = priv->hw->conf.chandef.chan->band;
 
        iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
 
@@ -951,7 +952,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
                unsigned long basic = ctx->vif->bss_conf.basic_rates;
                int i;
 
-               sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
+               sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];
 
                for_each_set_bit(i, &basic, BITS_PER_LONG) {
                        int hw = sband->bitrates[i].hw_value;
@@ -1181,7 +1182,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_rxon_context *ctx;
        struct ieee80211_conf *conf = &hw->conf;
-       struct ieee80211_channel *channel = conf->channel;
+       struct ieee80211_channel *channel = conf->chandef.chan;
        int ret = 0;
 
        IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed);
index 86e312a4f6291d53c1bb366ed13e7d2e1a73381d..e6eca4d66f6c8bf2b0b9ada40a6ca9fe9ab83ce4 100644 (file)
@@ -669,6 +669,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
                                           u32 action)
 {
        struct iwl_mac_ctx_cmd cmd = {};
+       struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr;
 
        WARN_ON(vif->type != NL80211_IFTYPE_STATION || !vif->p2p);
 
@@ -678,7 +679,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
        /* Fill the data specific for station mode */
        iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta);
 
-       cmd.p2p_sta.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
+       cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
+                                       IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
 
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
@@ -919,6 +921,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
                                   u32 action)
 {
        struct iwl_mac_ctx_cmd cmd = {};
+       struct ieee80211_p2p_noa_attr *noa = &vif->bss_conf.p2p_noa_attr;
 
        WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
 
@@ -929,8 +932,11 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
        iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
                                     action == FW_CTXT_ACTION_ADD);
 
-       cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow);
-       cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps);
+       cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow &
+                                       IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
+       cmd.go.opp_ps_enabled =
+                       cpu_to_le32(!!(noa->oppps_ctwindow &
+                                       IEEE80211_P2P_OPPPS_ENABLE_BIT));
 
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
index 7001856241e60354e9ff5cbed505ba6fc8bac415..088de9d25c39ecd4eb3dabc9177c72c3cd9619a4 100644 (file)
@@ -412,9 +412,9 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
        struct ieee80211_conf *conf = &hw->conf;
        lbtf_deb_enter(LBTF_DEB_MACOPS);
 
-       if (conf->channel->center_freq != priv->cur_freq) {
-               priv->cur_freq = conf->channel->center_freq;
-               lbtf_set_channel(priv, conf->channel->hw_value);
+       if (conf->chandef.chan->center_freq != priv->cur_freq) {
+               priv->cur_freq = conf->chandef.chan->center_freq;
+               lbtf_set_channel(priv, conf->chandef.chan->hw_value);
        }
        lbtf_deb_leave(LBTF_DEB_MACOPS);
        return 0;
@@ -537,7 +537,7 @@ static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = SURVEY_INFO_NOISE_DBM;
        survey->noise = priv->noise;
 
index 0064d38276bf6a714d86e7c310f49f1ef91a5d35..70b6ce61fea9a25833b543a080fcb78a6ce1ce96 100644 (file)
@@ -1062,11 +1062,13 @@ out:
        return HRTIMER_NORESTART;
 }
 
-static const char *hwsim_chantypes[] = {
-       [NL80211_CHAN_NO_HT] = "noht",
-       [NL80211_CHAN_HT20] = "ht20",
-       [NL80211_CHAN_HT40MINUS] = "ht40-",
-       [NL80211_CHAN_HT40PLUS] = "ht40+",
+static const char * const hwsim_chanwidths[] = {
+       [NL80211_CHAN_WIDTH_20_NOHT] = "noht",
+       [NL80211_CHAN_WIDTH_20] = "ht20",
+       [NL80211_CHAN_WIDTH_40] = "ht40",
+       [NL80211_CHAN_WIDTH_80] = "vht80",
+       [NL80211_CHAN_WIDTH_80P80] = "vht80p80",
+       [NL80211_CHAN_WIDTH_160] = "vht160",
 };
 
 static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
@@ -1080,18 +1082,28 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
                [IEEE80211_SMPS_DYNAMIC] = "dynamic",
        };
 
-       wiphy_debug(hw->wiphy,
-                   "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
-                   __func__,
-                   conf->channel ? conf->channel->center_freq : 0,
-                   hwsim_chantypes[conf->channel_type],
-                   !!(conf->flags & IEEE80211_CONF_IDLE),
-                   !!(conf->flags & IEEE80211_CONF_PS),
-                   smps_modes[conf->smps_mode]);
+       if (conf->chandef.chan)
+               wiphy_debug(hw->wiphy,
+                           "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
+                           __func__,
+                           conf->chandef.chan->center_freq,
+                           conf->chandef.center_freq1,
+                           conf->chandef.center_freq2,
+                           hwsim_chanwidths[conf->chandef.width],
+                           !!(conf->flags & IEEE80211_CONF_IDLE),
+                           !!(conf->flags & IEEE80211_CONF_PS),
+                           smps_modes[conf->smps_mode]);
+       else
+               wiphy_debug(hw->wiphy,
+                           "%s (freq=0 idle=%d ps=%d smps=%s)\n",
+                           __func__,
+                           !!(conf->flags & IEEE80211_CONF_IDLE),
+                           !!(conf->flags & IEEE80211_CONF_PS),
+                           smps_modes[conf->smps_mode]);
 
        data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
-       data->channel = conf->channel;
+       data->channel = conf->chandef.chan;
 
        WARN_ON(data->channel && channels > 1);
 
@@ -1277,7 +1289,7 @@ static int mac80211_hwsim_get_survey(
                return -ENOENT;
 
        /* Current channel */
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
 
        /*
         * Magically conjured noise level --- this is only ok for simulated hardware.
@@ -2298,9 +2310,6 @@ static int __init init_mac80211_hwsim(void)
 
                        hw->wiphy->bands[band] = sband;
 
-                       if (channels == 1)
-                               continue;
-
                        sband->vht_cap.vht_supported = true;
                        sband->vht_cap.cap =
                                IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
index 956c1084ebf13ade0959fff0ad894a4910b60108..ee1778cf270fc194ae6bdc0a4aac1b00b16746c8 100644 (file)
@@ -2852,7 +2852,9 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
                                     struct ieee80211_conf *conf,
                                     unsigned short pwr)
 {
-       struct ieee80211_channel *channel = conf->channel;
+       struct ieee80211_channel *channel = conf->chandef.chan;
+       enum nl80211_channel_type channel_type =
+               cfg80211_get_chandef_type(&conf->chandef);
        struct mwl8k_cmd_tx_power *cmd;
        int rc;
        int i;
@@ -2872,14 +2874,14 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
 
        cmd->channel = cpu_to_le16(channel->hw_value);
 
-       if (conf->channel_type == NL80211_CHAN_NO_HT ||
-           conf->channel_type == NL80211_CHAN_HT20) {
+       if (channel_type == NL80211_CHAN_NO_HT ||
+           channel_type == NL80211_CHAN_HT20) {
                cmd->bw = cpu_to_le16(0x2);
        } else {
                cmd->bw = cpu_to_le16(0x4);
-               if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+               if (channel_type == NL80211_CHAN_HT40MINUS)
                        cmd->sub_ch = cpu_to_le16(0x3);
-               else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+               else if (channel_type == NL80211_CHAN_HT40PLUS)
                        cmd->sub_ch = cpu_to_le16(0x1);
        }
 
@@ -3023,7 +3025,9 @@ struct mwl8k_cmd_set_rf_channel {
 static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
                                    struct ieee80211_conf *conf)
 {
-       struct ieee80211_channel *channel = conf->channel;
+       struct ieee80211_channel *channel = conf->chandef.chan;
+       enum nl80211_channel_type channel_type =
+               cfg80211_get_chandef_type(&conf->chandef);
        struct mwl8k_cmd_set_rf_channel *cmd;
        int rc;
 
@@ -3041,12 +3045,12 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
        else if (channel->band == IEEE80211_BAND_5GHZ)
                cmd->channel_flags |= cpu_to_le32(0x00000004);
 
-       if (conf->channel_type == NL80211_CHAN_NO_HT ||
-           conf->channel_type == NL80211_CHAN_HT20)
+       if (channel_type == NL80211_CHAN_NO_HT ||
+           channel_type == NL80211_CHAN_HT20)
                cmd->channel_flags |= cpu_to_le32(0x00000080);
-       else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
+       else if (channel_type == NL80211_CHAN_HT40MINUS)
                cmd->channel_flags |= cpu_to_le32(0x000001900);
-       else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
+       else if (channel_type == NL80211_CHAN_HT40PLUS)
                cmd->channel_flags |= cpu_to_le32(0x000000900);
 
        rc = mwl8k_post_cmd(hw, &cmd->header);
@@ -3965,7 +3969,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
        memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
        cmd->stn_id = cpu_to_le16(sta->aid);
        cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
-       if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+       if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
                rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
        else
                rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
@@ -4400,7 +4404,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
        p->ht_caps = cpu_to_le16(sta->ht_cap.cap);
        p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
                ((sta->ht_cap.ampdu_density & 7) << 2);
-       if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+       if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
                rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
        else
                rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
@@ -4881,7 +4885,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        goto out;
                }
 
-               if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+               if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) {
                        ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
                } else {
                        ap_legacy_rates =
@@ -4913,7 +4917,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        if (idx)
                                idx--;
 
-                       if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+                       if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
                                rate = mwl8k_rates_24[idx].hw_value;
                        else
                                rate = mwl8k_rates_50[idx].hw_value;
@@ -4986,7 +4990,7 @@ mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                if (idx)
                        idx--;
 
-               if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+               if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
                        rate = mwl8k_rates_24[idx].hw_value;
                else
                        rate = mwl8k_rates_50[idx].hw_value;
@@ -5259,7 +5263,7 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = SURVEY_INFO_NOISE_DBM;
        survey->noise = priv->noise;
 
index 9ba85106eec0a0cc337732f0858d862e26e5a380..b3879fbf53688bcea74ba9b639d5b6c8ddab860d 100644 (file)
@@ -402,7 +402,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
        struct p54_rssi_db_entry *rssi_data;
        unsigned int i;
        void *entry;
-       __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
+       __le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq);
 
        skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
                            2 + sizeof(*iq_autocal) + sizeof(*body) +
@@ -532,7 +532,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
 err:
        wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
                  ieee80211_frequency_to_channel(
-                         priv->hw->conf.channel->center_freq));
+                         priv->hw->conf.chandef.chan->center_freq));
 
        dev_kfree_skb_any(skb);
        return -EINVAL;
index ee654a691f388660c9f33ab6b0ea5538e532f694..067e6f2fd050fcad0ddc4eb00565ba3324397894 100644 (file)
@@ -340,7 +340,7 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
                 * TODO: Use the LM_SCAN_TRAP to determine the current
                 * operating channel.
                 */
-               priv->curchan = priv->hw->conf.channel;
+               priv->curchan = priv->hw->conf.chandef.chan;
                p54_reset_stats(priv);
                WARN_ON(p54_fetch_statistics(priv));
        }
@@ -480,7 +480,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
                p54_set_edcf(priv);
        }
        if (changed & BSS_CHANGED_BASIC_RATES) {
-               if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
+               if (dev->conf.chandef.chan->band == IEEE80211_BAND_5GHZ)
                        priv->basic_rate_mask = (info->basic_rates << 4);
                else
                        priv->basic_rate_mask = info->basic_rates;
index 12f0a34477f231cff73a591f3bc5a2af300ce9d0..f95de0d162166e1de1e9035d1d3be9db238869fe 100644 (file)
@@ -354,13 +354,13 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
        rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
        if (hdr->rate & 0x10)
                rx_status->flag |= RX_FLAG_SHORTPRE;
-       if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+       if (priv->hw->conf.chandef.chan->band == IEEE80211_BAND_5GHZ)
                rx_status->rate_idx = (rate < 4) ? 0 : rate - 4;
        else
                rx_status->rate_idx = rate;
 
        rx_status->freq = freq;
-       rx_status->band =  priv->hw->conf.channel->band;
+       rx_status->band =  priv->hw->conf.chandef.chan->band;
        rx_status->antenna = hdr->antenna;
 
        tsf32 = le32_to_cpu(hdr->tsf32);
index 7deac4d2459f9b754dab33ed7564cb850fe20bbe..72bbb962579f874b63c872cec86d1f33829575aa 100644 (file)
@@ -3147,7 +3147,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
 
 void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
 {
-       rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel,
+       rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.chandef.chan,
                              rt2x00dev->tx_power);
 }
 EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
@@ -3282,11 +3282,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
        if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
                rt2800_config_channel(rt2x00dev, libconf->conf,
                                      &libconf->rf, &libconf->channel);
-               rt2800_config_txpower(rt2x00dev, libconf->conf->channel,
+               rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan,
                                      libconf->conf->power_level);
        }
        if (flags & IEEE80211_CONF_CHANGE_POWER)
-               rt2800_config_txpower(rt2x00dev, libconf->conf->channel,
+               rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan,
                                      libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt2800_config_retry_limit(rt2x00dev, libconf);
@@ -6340,7 +6340,7 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
 
        rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
        rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
index 49a63e973934b30a87117babb8305fe5c8609631..8cb43f8f3efcb96958ead840e055be1462f3f2f8 100644 (file)
@@ -184,7 +184,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
        /*
         * Initialize center channel to current channel.
         */
-       center_channel = spec->channels[conf->channel->hw_value].channel;
+       center_channel = spec->channels[conf->chandef.chan->hw_value].channel;
 
        /*
         * Adjust center channel to HT40+ and HT40- operation.
@@ -199,7 +199,7 @@ static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
                        return i;
 
        WARN_ON(1);
-       return conf->channel->hw_value;
+       return conf->chandef.chan->hw_value;
 }
 
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
@@ -227,7 +227,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                        hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
                } else {
                        clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
-                       hw_value = conf->channel->hw_value;
+                       hw_value = conf->chandef.chan->hw_value;
                }
 
                memcpy(&libconf.rf,
@@ -279,8 +279,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
        else
                clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
 
-       rt2x00dev->curr_band = conf->channel->band;
-       rt2x00dev->curr_freq = conf->channel->center_freq;
+       rt2x00dev->curr_band = conf->chandef.chan->band;
+       rt2x00dev->curr_freq = conf->chandef.chan->center_freq;
        rt2x00dev->tx_power = conf->power_level;
        rt2x00dev->short_retry = conf->short_frame_max_tx_count;
        rt2x00dev->long_retry = conf->long_frame_max_tx_count;
index 9e3c8ff53e3fd9e0b4f723e96671eba005d75d62..9d630b4ee3e547d4687f010aa47ed73a47b9abf7 100644 (file)
@@ -848,7 +848,7 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
        u16 eeprom;
        short lna_gain = 0;
 
-       if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+       if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) {
                if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
                        lna_gain += 14;
 
index 24eec66e9fd2049ae14aa709e7e2ecab0294751c..a3387b146bb5f77c17ff1e247a6a203d1781faf2 100644 (file)
@@ -739,7 +739,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
        u16 eeprom;
        short lna_gain = 0;
 
-       if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+       if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) {
                if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
                        lna_gain += 14;
 
index 1b3c2843221d2a38ded783270009d7838d89b4b4..91a04e2b8ece4c94f1d02946d5d33500a3a98ac5 100644 (file)
@@ -147,8 +147,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                                signal = priv->rf->calc_rssi(agc, sq);
                        }
                        rx_status.signal = signal;
-                       rx_status.freq = dev->conf.channel->center_freq;
-                       rx_status.band = dev->conf.channel->band;
+                       rx_status.freq = dev->conf.chandef.chan->center_freq;
+                       rx_status.band = dev->conf.chandef.chan->band;
                        rx_status.mactime = le64_to_cpu(entry->tsft);
                        rx_status.flag |= RX_FLAG_MACTIME_START;
                        if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
index 5ee7589dd546d017bd505772002ee598faed9bb6..077ff92cc1397d8c5d0e3a941c1d5b0a4f584363 100644 (file)
@@ -82,7 +82,8 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
                                   struct ieee80211_conf *conf)
 {
        struct rtl8180_priv *priv = dev->priv;
-       int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       int channel =
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
        u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
        u32 chan = channel - 1;
 
index 667b3363d4371c20bbe59996dc6d0d74387c7323..4715000c94dd65edfe8437c0a451c1cf1dae5dc7 100644 (file)
@@ -95,7 +95,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev,
 {
        struct rtl8180_priv *priv = dev->priv;
        int channel = conf ?
-               ieee80211_frequency_to_channel(conf->channel->center_freq) : 1;
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq) : 1;
        unsigned int chan_idx = channel - 1;
        u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
        u32 chan = max2820_chan[chan_idx];
index 7c4574ba9d7509017003afe16e38ae32ab572817..cc2a5412c1f08d6ab4acc6688d400f8afbba08be 100644 (file)
@@ -719,7 +719,8 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
                                   struct ieee80211_conf *conf)
 {
        struct rtl8180_priv *priv = dev->priv;
-       int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       int chan =
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
 
        if (priv->rf->init == rtl8225_rf_init)
                rtl8225_rf_set_tx_power(dev, chan);
index 44771a6286af6968eac3e87b5845093dc214198c..b3ec40f6bd23de804099609e351760119f84bcb4 100644 (file)
@@ -105,7 +105,8 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
                                  struct ieee80211_conf *conf)
 {
        struct rtl8180_priv *priv = dev->priv;
-       int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       int channel =
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
        u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
        u32 chan = sa2400_chan[channel - 1];
 
index 4574bd213705c7b51f875d8c8ec2c4bd3dee44fd..f49220e234b0bc79881229589770ac0221f3a7c6 100644 (file)
@@ -379,8 +379,8 @@ static void rtl8187_rx_cb(struct urb *urb)
        rate = (flags >> 20) & 0xF;
        skb_trim(skb, flags & 0x0FFF);
        rx_status.rate_idx = rate;
-       rx_status.freq = dev->conf.channel->center_freq;
-       rx_status.band = dev->conf.channel->band;
+       rx_status.freq = dev->conf.chandef.chan->center_freq;
+       rx_status.band = dev->conf.chandef.chan->band;
        rx_status.flag |= RX_FLAG_MACTIME_START;
        if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
                rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
index 908903f721f5dada520369c780568a96fe6fb279..f0bf35fedbaf2f94058b0397ed54dff48ce1e8f7 100644 (file)
@@ -905,7 +905,8 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
                                   struct ieee80211_conf *conf)
 {
        struct rtl8187_priv *priv = dev->priv;
-       int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       int chan =
+               ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
 
        if (priv->rf->init == rtl8225_rf_init)
                rtl8225_rf_set_tx_power(dev, chan);
index cac1fa912e8c70049f48fb0f3d5ab76a001108f3..af59dd5718e1b90eab623b8b04bf94b0332fce45 100644 (file)
@@ -722,7 +722,7 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
        int rate_idx;
 
        if (false == isht) {
-               if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) {
+               if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
                        switch (desc_rate) {
                        case DESC92_RATE1M:
                                rate_idx = 0;
@@ -987,8 +987,8 @@ static bool addbareq_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
        if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) {
                skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid);
                if (skb_delba) {
-                       rx_status.freq = hw->conf.channel->center_freq;
-                       rx_status.band = hw->conf.channel->band;
+                       rx_status.freq = hw->conf.chandef.chan->center_freq;
+                       rx_status.band = hw->conf.chandef.chan->band;
                        rx_status.flag |= RX_FLAG_DECRYPTED;
                        rx_status.flag |= RX_FLAG_MACTIME_END;
                        rx_status.rate_idx = 0;
@@ -1593,7 +1593,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
                sta_entry->mimo_ps = smps;
 
                info->control.rates[0].idx = 0;
-               info->band = hw->conf.channel->band;
+               info->band = hw->conf.chandef.chan->band;
                rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc);
        }
        return 1;
index 2201b5cee08f5187b167a77c287f80e6ec0455c0..ee84844be0080c2e1bcef681f7e53a7f42f93125 100644 (file)
@@ -370,7 +370,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               struct ieee80211_channel *channel = hw->conf.channel;
+               struct ieee80211_channel *channel = hw->conf.chandef.chan;
                u8 wide_chan = (u8) channel->hw_value;
 
                if (mac->act_scanning)
@@ -392,7 +392,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
                 *info for cisco1253 bw20, so we modify
                 *it here based on UPPER & LOWER
                 */
-               switch (hw->conf.channel_type) {
+               switch (cfg80211_get_chandef_type(&hw->conf.chandef)) {
                case NL80211_CHAN_HT20:
                case NL80211_CHAN_NO_HT:
                        /* SC */
@@ -450,7 +450,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
                rtlpriv->cfg->ops->switch_channel(hw);
                rtlpriv->cfg->ops->set_channel_access(hw);
                rtlpriv->cfg->ops->set_bw_mode(hw,
-                                              hw->conf.channel_type);
+                               cfg80211_get_chandef_type(&hw->conf.chandef));
        }
 
        mutex_unlock(&rtlpriv->locks.conf_mutex);
index d075237add512960364169eb840bb1dbf974f31d..a8871d66d56a25ed5bc5b68026be3850acafe65c 100644 (file)
@@ -421,8 +421,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
                RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
                         "Get Wakeup Packet!! WakeMatch =%d\n",
                         status->wake_match);
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
 
        if (status->crc)
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
index 65bf5fb970023bbea4ecaadb7d62c1e83bbfbc83..6ad23b413eb3e6e4251e2242fc4dc912e3b7b6e5 100644 (file)
@@ -363,8 +363,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
 
        stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc);
 
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
 
        hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
                        + stats->rx_bufshift);
index 710f7904ecdff632549d6763958960ad030fba05..763cf1defab5b4027b22604c3771e4c8465a4405 100644 (file)
@@ -324,8 +324,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
                                   && (GET_RX_DESC_FAGGR(pdesc) == 1));
        stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
        stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
        if (GET_RX_DESC_CRC32(pdesc))
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
        if (!GET_RX_DESC_SWDEC(pdesc))
@@ -395,8 +395,8 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
        stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc);
        /* TODO: is center_freq changed when doing scan? */
        /* TODO: Shall we add protection or just skip those two step? */
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
        if (GET_RX_DESC_CRC32(rxdesc))
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
        if (!GET_RX_DESC_SWDEC(rxdesc))
index 941080e03c06b5d7cd499eaf30659189e9df0428..b8ec718a0fabbf348df84820fa530f8e28031699 100644 (file)
@@ -499,8 +499,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
                                         && (GET_RX_DESC_FAGGR(pdesc) == 1));
        stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
        stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
        if (GET_RX_DESC_CRC32(pdesc))
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
        if (!GET_RX_DESC_SWDEC(pdesc))
index 960bc28cc51e5227431b4ef154fa2c1f3372b0c9..c7095118de6e8c23bbfd0ee5727fc353969db9fd 100644 (file)
@@ -281,8 +281,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
        if (stats->hwerror)
                return false;
 
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
 
        if (stats->crc)
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
index 6c64365308d3780f1bd84e1f6c4dcb5177fb9be1..c72758d8f4edc682a777950154c1025978fb31f8 100644 (file)
@@ -304,8 +304,8 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,
 
        status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate);
 
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.chandef.chan->center_freq;
+       rx_status->band = hw->conf.chandef.chan->band;
 
        if (status->crc)
                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
index bbbf68cf50a754a121e4bd3015afe880c544fa79..3291ffa952736ac9f6ac2784c758db39b498d37c 100644 (file)
@@ -572,7 +572,8 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
        struct ieee80211_conf *conf = &hw->conf;
        int channel, ret = 0;
 
-       channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+       channel = ieee80211_frequency_to_channel(
+                       conf->chandef.chan->center_freq);
 
        wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
                     channel,
@@ -1223,7 +1224,7 @@ static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
  
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = SURVEY_INFO_NOISE_DBM;
        survey->noise = wl->noise;
  
index d10954c0c181a9d793c735728a28d88c771e077d..953111a502ee83a0b8834e35cff965c0787666c5 100644 (file)
@@ -4502,7 +4502,7 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
        if (idx != 0)
                return -ENOENT;
 
-       survey->channel = conf->channel;
+       survey->channel = conf->chandef.chan;
        survey->filled = 0;
        return 0;
 }
index 114364b5d46638f3597e66761c5caff45903cc80..c6208a7988e4736c54883e2fab67bdb1fd85d514 100644 (file)
@@ -1156,10 +1156,10 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
        struct ieee80211_conf *conf = &hw->conf;
 
        spin_lock_irq(&mac->lock);
-       mac->channel = conf->channel->hw_value;
+       mac->channel = conf->chandef.chan->hw_value;
        spin_unlock_irq(&mac->lock);
 
-       return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
+       return zd_chip_set_channel(&mac->chip, conf->chandef.chan->hw_value);
 }
 
 static void zd_beacon_done(struct zd_mac *mac)
index 4cf0c9e4dd996b4e728510fa737800764fe70f14..e46fea8b972e9c61f7347731e8240c3aab96761f 100644 (file)
@@ -1027,6 +1027,26 @@ enum ieee80211_p2p_attr_id {
        IEEE80211_P2P_ATTR_MAX
 };
 
+/* Notice of Absence attribute - described in P2P spec 4.1.14 */
+/* Typical max value used here */
+#define IEEE80211_P2P_NOA_DESC_MAX     4
+
+struct ieee80211_p2p_noa_desc {
+       u8 count;
+       __le32 duration;
+       __le32 interval;
+       __le32 start_time;
+} __packed;
+
+struct ieee80211_p2p_noa_attr {
+       u8 index;
+       u8 oppps_ctwindow;
+       struct ieee80211_p2p_noa_desc desc[IEEE80211_P2P_NOA_DESC_MAX];
+} __packed;
+
+#define IEEE80211_P2P_OPPPS_ENABLE_BIT         BIT(7)
+#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK      0x7F
+
 /**
  * struct ieee80211_bar - HT Block Ack Request
  *
@@ -1935,6 +1955,16 @@ enum ieee80211_timeout_interval_type {
        WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */,
 };
 
+/**
+ * struct ieee80211_timeout_interval_ie - Timeout Interval element
+ * @type: type, see &enum ieee80211_timeout_interval_type
+ * @value: timeout interval value
+ */
+struct ieee80211_timeout_interval_ie {
+       u8 type;
+       __le32 value;
+} __packed;
+
 /* BACK action code */
 enum ieee80211_back_actioncode {
        WLAN_ACTION_ADDBA_REQ = 0,
index bdba9b619064b9c2fa683c2356821348df6d793d..57870b6469748b9f68f8912c6f8efe0978c26395 100644 (file)
@@ -1998,6 +1998,10 @@ struct cfg80211_update_ft_ies_params {
  *     advertise the support for MAC based ACL have to implement this callback.
  *
  * @start_radar_detection: Start radar detection in the driver.
+ *
+ * @update_ft_ies: Provide updated Fast BSS Transition information to the
+ *     driver. If the SME is in the driver/firmware, this information can be
+ *     used in building Authentication and Reassociation Request frames.
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
index dd73b8c6746bdd1654c08bc5e2c10f77b59a0a1f..64faf015dd1e1faec85a4274eea2d385160eb275 100644 (file)
@@ -330,8 +330,7 @@ enum ieee80211_rssi_event {
  * @ssid_len: Length of SSID given in @ssid.
  * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
  * @txpower: TX power in dBm
- * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces
- * @p2p_oppps: P2P opportunistic PS is enabled
+ * @p2p_noa_attr: P2P NoA attribute for P2P powersave
  */
 struct ieee80211_bss_conf {
        const u8 *bssid;
@@ -365,8 +364,7 @@ struct ieee80211_bss_conf {
        size_t ssid_len;
        bool hidden_ssid;
        int txpower;
-       u8 p2p_ctwindow;
-       bool p2p_oppps;
+       struct ieee80211_p2p_noa_attr p2p_noa_attr;
 };
 
 /**
@@ -976,8 +974,7 @@ enum ieee80211_smps_mode {
  * @power_level: requested transmit power (in dBm), backward compatibility
  *     value only that is set to the minimum of all interfaces
  *
- * @channel: the channel to tune to
- * @channel_type: the channel (HT) type
+ * @chandef: the channel definition to tune to
  * @radar_enabled: whether radar detection is enabled
  *
  * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
@@ -1003,8 +1000,7 @@ struct ieee80211_conf {
 
        u8 long_frame_max_tx_count, short_frame_max_tx_count;
 
-       struct ieee80211_channel *channel;
-       enum nl80211_channel_type channel_type;
+       struct cfg80211_chan_def chandef;
        bool radar_enabled;
        enum ieee80211_smps_mode smps_mode;
 };
@@ -1536,6 +1532,17 @@ enum ieee80211_hw_flags {
  * @netdev_features: netdev features to be set in each netdev created
  *     from this HW. Note only HW checksum features are currently
  *     compatible with mac80211. Other feature bits will be rejected.
+ *
+ * @uapsd_queues: This bitmap is included in (re)association frame to indicate
+ *     for each access category if it is uAPSD trigger-enabled and delivery-
+ *     enabled. Use IEEE80211_WMM_IE_STA_QOSINFO_AC_* to set this bitmap.
+ *     Each bit corresponds to different AC. Value '1' in specific bit means
+ *     that corresponding AC is both trigger- and delivery-enabled. '0' means
+ *     neither enabled.
+ *
+ * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may
+ *     deliver to a WMM STA during any Service Period triggered by the WMM STA.
+ *     Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values.
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
@@ -1561,6 +1568,8 @@ struct ieee80211_hw {
        u8 radiotap_mcs_details;
        u16 radiotap_vht_details;
        netdev_features_t netdev_features;
+       u8 uapsd_queues;
+       u8 uapsd_max_sp_len;
 };
 
 /**
@@ -4205,31 +4214,33 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
 static inline bool
 conf_is_ht20(struct ieee80211_conf *conf)
 {
-       return conf->channel_type == NL80211_CHAN_HT20;
+       return conf->chandef.width == NL80211_CHAN_WIDTH_20;
 }
 
 static inline bool
 conf_is_ht40_minus(struct ieee80211_conf *conf)
 {
-       return conf->channel_type == NL80211_CHAN_HT40MINUS;
+       return conf->chandef.width == NL80211_CHAN_WIDTH_40 &&
+              conf->chandef.center_freq1 < conf->chandef.chan->center_freq;
 }
 
 static inline bool
 conf_is_ht40_plus(struct ieee80211_conf *conf)
 {
-       return conf->channel_type == NL80211_CHAN_HT40PLUS;
+       return conf->chandef.width == NL80211_CHAN_WIDTH_40 &&
+              conf->chandef.center_freq1 > conf->chandef.chan->center_freq;
 }
 
 static inline bool
 conf_is_ht40(struct ieee80211_conf *conf)
 {
-       return conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf);
+       return conf->chandef.width == NL80211_CHAN_WIDTH_40;
 }
 
 static inline bool
 conf_is_ht(struct ieee80211_conf *conf)
 {
-       return conf->channel_type != NL80211_CHAN_NO_HT;
+       return conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
 }
 
 static inline enum nl80211_iftype
index c50c19402588807482ef7d7aad715818eed4bb90..764dd9a6a072a0bc8392ea4a2196a344e30c487b 100644 (file)
@@ -805,8 +805,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
                                        IEEE80211_CHANCTX_EXCLUSIVE);
                }
        } else if (local->open_count == local->monitors) {
-               local->_oper_channel = chandef->chan;
-               local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
+               local->_oper_chandef = *chandef;
                ieee80211_hw_config(local, 0);
        }
 
@@ -965,8 +964,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
        sdata->vif.bss_conf.hidden_ssid =
                (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
 
-       sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
-       sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
+       memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
+              sizeof(sdata->vif.bss_conf.p2p_noa_attr));
+       sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow =
+               params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
+       if (params->p2p_opp_ps)
+               sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
+                                       IEEE80211_P2P_OPPPS_ENABLE_BIT;
 
        err = ieee80211_assign_beacon(sdata, &params->beacon);
        if (err < 0)
@@ -1536,7 +1540,6 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
        struct mesh_path *mpath;
        struct sta_info *sta;
-       int err;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -1547,17 +1550,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
                return -ENOENT;
        }
 
-       err = mesh_path_add(sdata, dst);
-       if (err) {
+       mpath = mesh_path_add(sdata, dst);
+       if (IS_ERR(mpath)) {
                rcu_read_unlock();
-               return err;
+               return PTR_ERR(mpath);
        }
 
-       mpath = mesh_path_lookup(sdata, dst);
-       if (!mpath) {
-               rcu_read_unlock();
-               return -ENXIO;
-       }
        mesh_path_fix_nexthop(mpath, sta);
 
        rcu_read_unlock();
@@ -1961,12 +1959,20 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
        }
 
        if (params->p2p_ctwindow >= 0) {
-               sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
+               sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
+                                       ~IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
+               sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
+                       params->p2p_ctwindow & IEEE80211_P2P_OPPPS_CTWINDOW_MASK;
                changed |= BSS_CHANGED_P2P_PS;
        }
 
-       if (params->p2p_opp_ps >= 0) {
-               sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
+       if (params->p2p_opp_ps > 0) {
+               sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
+                                       IEEE80211_P2P_OPPPS_ENABLE_BIT;
+               changed |= BSS_CHANGED_P2P_PS;
+       } else if (params->p2p_opp_ps == 0) {
+               sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow &=
+                                       ~IEEE80211_P2P_OPPPS_ENABLE_BIT;
                changed |= BSS_CHANGED_P2P_PS;
        }
 
@@ -3362,9 +3368,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
                if (local->use_chanctx)
                        *chandef = local->monitor_chandef;
                else
-                       cfg80211_chandef_create(chandef,
-                                               local->_oper_channel,
-                                               local->_oper_channel_type);
+                       *chandef = local->_oper_chandef;
                ret = 0;
        }
        rcu_read_unlock();
index 931be419ab5aece83990b530afa5979b2053294c..7d0baa89c784888926b98d2a84fc329f04c75122 100644 (file)
@@ -22,7 +22,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
        drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
 
        if (!local->use_chanctx) {
-               local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
+               local->_oper_chandef = *chandef;
                ieee80211_hw_config(local, 0);
        }
 }
@@ -85,9 +85,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
                ieee80211_hw_config(local, changed);
 
        if (!local->use_chanctx) {
-               local->_oper_channel_type =
-                       cfg80211_get_chandef_type(chandef);
-               local->_oper_channel = chandef->chan;
+               local->_oper_chandef = *chandef;
                ieee80211_hw_config(local, 0);
        } else {
                err = drv_add_chanctx(local, ctx);
@@ -117,7 +115,10 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
        WARN_ON_ONCE(ctx->refcount != 0);
 
        if (!local->use_chanctx) {
-               local->_oper_channel_type = NL80211_CHAN_NO_HT;
+               struct cfg80211_chan_def *chandef = &local->_oper_chandef;
+               chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
+               chandef->center_freq1 = chandef->chan->center_freq;
+               chandef->center_freq2 = 0;
                ieee80211_hw_config(local, 0);
        } else {
                drv_remove_chanctx(local, ctx);
index ddb426867904d55c3b14ab4d7642bef3b0cd66cd..14abcf44f974309de5495908d413eeeae2f3595e 100644 (file)
@@ -124,6 +124,15 @@ static ssize_t ieee80211_if_fmt_##name(                                    \
        return scnprintf(buf, buflen, "%d\n", sdata->field / 16);       \
 }
 
+#define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field)                    \
+static ssize_t ieee80211_if_fmt_##name(                                        \
+       const struct ieee80211_sub_if_data *sdata,                      \
+       char *buf, int buflen)                                          \
+{                                                                      \
+       return scnprintf(buf, buflen, "%d\n",                           \
+                        jiffies_to_msecs(sdata->field));               \
+}
+
 #define __IEEE80211_IF_FILE(name, _write)                              \
 static ssize_t ieee80211_if_read_##name(struct file *file,             \
                                        char __user *userbuf,           \
@@ -197,6 +206,7 @@ IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
 IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
 IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
 IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
+IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS);
 
 static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
                              enum ieee80211_smps_mode smps_mode)
@@ -542,6 +552,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(aid);
        DEBUGFS_ADD(last_beacon);
        DEBUGFS_ADD(ave_beacon);
+       DEBUGFS_ADD(beacon_timeout);
        DEBUGFS_ADD_MODE(smps, 0600);
        DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
        DEBUGFS_ADD_MODE(uapsd_queues, 0600);
index 4f841fe559df3d834516bf50c60709929d1c4639..44e201d60a13991f0144954ac1dd1ebd00cb4672 100644 (file)
@@ -54,6 +54,7 @@ STA_FILE(aid, sta.aid, D);
 STA_FILE(dev, sdata->name, S);
 STA_FILE(last_signal, last_signal, D);
 STA_FILE(last_ack_signal, last_ack_signal, D);
+STA_FILE(beacon_loss_count, beacon_loss_count, D);
 
 static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
                              size_t count, loff_t *ppos)
@@ -434,6 +435,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
        DEBUGFS_ADD(agg_status);
        DEBUGFS_ADD(dev);
        DEBUGFS_ADD(last_signal);
+       DEBUGFS_ADD(beacon_loss_count);
        DEBUGFS_ADD(ht_capa);
        DEBUGFS_ADD(vht_capa);
        DEBUGFS_ADD(last_ack_signal);
index 539d4a11b47bc9be2d30625ef0d79c97c9d9cdd5..2a0b2186d98f39f38d3d2f4475aa2256cf485a9d 100644 (file)
@@ -44,7 +44,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        int rates, i;
-       struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
        u8 *pos;
        struct ieee80211_supported_band *sband;
@@ -52,20 +51,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        u32 bss_change;
        u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
        struct cfg80211_chan_def chandef;
+       struct beacon_data *presp;
+       int frame_len;
 
        lockdep_assert_held(&ifibss->mtx);
 
        /* Reset own TSF to allow time synchronization work. */
        drv_reset_tsf(local, sdata);
 
-       skb = ifibss->skb;
-       RCU_INIT_POINTER(ifibss->presp, NULL);
-       synchronize_rcu();
-       skb->data = skb->head;
-       skb->len = 0;
-       skb_reset_tail_pointer(skb);
-       skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
-
        if (!ether_addr_equal(ifibss->bssid, bssid))
                sta_info_flush(sdata);
 
@@ -73,10 +66,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        if (sdata->vif.bss_conf.ibss_joined) {
                sdata->vif.bss_conf.ibss_joined = false;
                sdata->vif.bss_conf.ibss_creator = false;
+               sdata->vif.bss_conf.enable_beacon = false;
                netif_carrier_off(sdata->dev);
-               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS);
+               ieee80211_bss_info_change_notify(sdata,
+                                                BSS_CHANGED_IBSS |
+                                                BSS_CHANGED_BEACON_ENABLED);
        }
 
+       presp = rcu_dereference_protected(ifibss->presp,
+                                         lockdep_is_held(&ifibss->mtx));
+       rcu_assign_pointer(ifibss->presp, NULL);
+       if (presp)
+               kfree_rcu(presp, rcu_head);
+
        sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
 
        cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
@@ -98,19 +100,24 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 
        sband = local->hw.wiphy->bands[chan->band];
 
-       /* build supported rates array */
-       pos = supp_rates;
-       for (i = 0; i < sband->n_bitrates; i++) {
-               int rate = sband->bitrates[i].bitrate;
-               u8 basic = 0;
-               if (basic_rates & BIT(i))
-                       basic = 0x80;
-               *pos++ = basic | (u8) (rate / 5);
-       }
-
        /* Build IBSS probe response */
-       mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
-       memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
+       frame_len = sizeof(struct ieee80211_hdr_3addr) +
+                   12 /* struct ieee80211_mgmt.u.beacon */ +
+                   2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
+                   2 + 8 /* max Supported Rates */ +
+                   3 /* max DS params */ +
+                   4 /* IBSS params */ +
+                   2 + (IEEE80211_MAX_SUPP_RATES - 8) +
+                   2 + sizeof(struct ieee80211_ht_cap) +
+                   2 + sizeof(struct ieee80211_ht_operation) +
+                   ifibss->ie_len;
+       presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL);
+       if (!presp)
+               return;
+
+       presp->head = (void *)(presp + 1);
+
+       mgmt = (void *) presp->head;
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_PROBE_RESP);
        eth_broadcast_addr(mgmt->da);
@@ -120,27 +127,30 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
        mgmt->u.beacon.capab_info = cpu_to_le16(capability);
 
-       pos = skb_put(skb, 2 + ifibss->ssid_len);
+       pos = (u8 *)mgmt + offsetof(struct ieee80211_mgmt, u.beacon.variable);
+
        *pos++ = WLAN_EID_SSID;
        *pos++ = ifibss->ssid_len;
        memcpy(pos, ifibss->ssid, ifibss->ssid_len);
+       pos += ifibss->ssid_len;
 
-       rates = sband->n_bitrates;
-       if (rates > 8)
-               rates = 8;
-       pos = skb_put(skb, 2 + rates);
+       rates = min_t(int, 8, sband->n_bitrates);
        *pos++ = WLAN_EID_SUPP_RATES;
        *pos++ = rates;
-       memcpy(pos, supp_rates, rates);
+       for (i = 0; i < rates; i++) {
+               int rate = sband->bitrates[i].bitrate;
+               u8 basic = 0;
+               if (basic_rates & BIT(i))
+                       basic = 0x80;
+               *pos++ = basic | (u8) (rate / 5);
+       }
 
        if (sband->band == IEEE80211_BAND_2GHZ) {
-               pos = skb_put(skb, 2 + 1);
                *pos++ = WLAN_EID_DS_PARAMS;
                *pos++ = 1;
                *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
        }
 
-       pos = skb_put(skb, 2 + 2);
        *pos++ = WLAN_EID_IBSS_PARAMS;
        *pos++ = 2;
        /* FIX: set ATIM window based on scan results */
@@ -148,23 +158,25 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        *pos++ = 0;
 
        if (sband->n_bitrates > 8) {
-               rates = sband->n_bitrates - 8;
-               pos = skb_put(skb, 2 + rates);
                *pos++ = WLAN_EID_EXT_SUPP_RATES;
-               *pos++ = rates;
-               memcpy(pos, &supp_rates[8], rates);
+               *pos++ = sband->n_bitrates - 8;
+               for (i = 8; i < sband->n_bitrates; i++) {
+                       int rate = sband->bitrates[i].bitrate;
+                       u8 basic = 0;
+                       if (basic_rates & BIT(i))
+                               basic = 0x80;
+                       *pos++ = basic | (u8) (rate / 5);
+               }
        }
 
-       if (ifibss->ie_len)
-               memcpy(skb_put(skb, ifibss->ie_len),
-                      ifibss->ie, ifibss->ie_len);
+       if (ifibss->ie_len) {
+               memcpy(pos, ifibss->ie, ifibss->ie_len);
+               pos += ifibss->ie_len;
+       }
 
        /* add HT capability and information IEs */
        if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
            sband->ht_cap.ht_supported) {
-               pos = skb_put(skb, 4 +
-                                  sizeof(struct ieee80211_ht_cap) +
-                                  sizeof(struct ieee80211_ht_operation));
                pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
                                                sband->ht_cap.cap);
                /*
@@ -177,7 +189,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        }
 
        if (local->hw.queues >= IEEE80211_NUM_ACS) {
-               pos = skb_put(skb, 9);
                *pos++ = WLAN_EID_VENDOR_SPECIFIC;
                *pos++ = 7; /* len */
                *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
@@ -189,7 +200,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                *pos++ = 0; /* U-APSD no in use */
        }
 
-       rcu_assign_pointer(ifibss->presp, skb);
+       presp->head_len = pos - presp->head;
+       if (WARN_ON(presp->head_len > frame_len))
+               return;
+
+       rcu_assign_pointer(ifibss->presp, presp);
 
        sdata->vif.bss_conf.enable_beacon = true;
        sdata->vif.bss_conf.beacon_int = beacon_int;
@@ -227,7 +242,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                  round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
 
        bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan,
-                                       mgmt, skb->len, 0, GFP_KERNEL);
+                                       mgmt, presp->head_len, 0, GFP_KERNEL);
        cfg80211_put_bss(local->hw.wiphy, bss);
        netif_carrier_on(sdata->dev);
        cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
@@ -448,7 +463,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
        bool rates_updated = false;
 
-       if (elems->ds_params && elems->ds_params_len == 1)
+       if (elems->ds_params)
                freq = ieee80211_channel_to_frequency(elems->ds_params[0],
                                                      band);
        else
@@ -822,8 +837,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        int tx_last_beacon, len = req->len;
        struct sk_buff *skb;
-       struct ieee80211_mgmt *resp;
-       struct sk_buff *presp;
+       struct beacon_data *presp;
        u8 *pos, *end;
 
        lockdep_assert_held(&ifibss->mtx);
@@ -864,13 +878,15 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        }
 
        /* Reply with ProbeResp */
-       skb = skb_copy(presp, GFP_KERNEL);
+       skb = dev_alloc_skb(local->tx_headroom + presp->head_len);
        if (!skb)
                return;
 
-       resp = (struct ieee80211_mgmt *) skb->data;
-       memcpy(resp->da, mgmt->sa, ETH_ALEN);
-       ibss_dbg(sdata, "Sending ProbeResp to %pM\n", resp->da);
+       skb_reserve(skb, local->tx_headroom);
+       memcpy(skb_put(skb, presp->head_len), presp->head, presp->head_len);
+
+       memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN);
+       ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa);
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
        ieee80211_tx_skb(sdata, skb);
 }
@@ -1020,23 +1036,8 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
 int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
                        struct cfg80211_ibss_params *params)
 {
-       struct sk_buff *skb;
        u32 changed = 0;
 
-       skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
-                           sizeof(struct ieee80211_hdr_3addr) +
-                           12 /* struct ieee80211_mgmt.u.beacon */ +
-                           2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
-                           2 + 8 /* max Supported Rates */ +
-                           3 /* max DS params */ +
-                           4 /* IBSS params */ +
-                           2 + (IEEE80211_MAX_SUPP_RATES - 8) +
-                           2 + sizeof(struct ieee80211_ht_cap) +
-                           2 + sizeof(struct ieee80211_ht_operation) +
-                           params->ie_len);
-       if (!skb)
-               return -ENOMEM;
-
        mutex_lock(&sdata->u.ibss.mtx);
 
        if (params->bssid) {
@@ -1065,7 +1066,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
                        sdata->u.ibss.ie_len = params->ie_len;
        }
 
-       sdata->u.ibss.skb = skb;
        sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
        sdata->u.ibss.ibss_join_req = jiffies;
 
@@ -1101,13 +1101,13 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 
 int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 {
-       struct sk_buff *skb;
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        struct cfg80211_bss *cbss;
        u16 capability;
        int active_ibss;
        struct sta_info *sta;
+       struct beacon_data *presp;
 
        mutex_lock(&sdata->u.ibss.mtx);
 
@@ -1153,8 +1153,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 
        /* remove beacon */
        kfree(sdata->u.ibss.ie);
-       skb = rcu_dereference_protected(sdata->u.ibss.presp,
-                                       lockdep_is_held(&sdata->u.ibss.mtx));
+       presp = rcu_dereference_protected(ifibss->presp,
+                                         lockdep_is_held(&sdata->u.ibss.mtx));
        RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
        sdata->vif.bss_conf.ibss_joined = false;
        sdata->vif.bss_conf.ibss_creator = false;
@@ -1163,7 +1163,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
                                                BSS_CHANGED_IBSS);
        synchronize_rcu();
-       kfree_skb(skb);
+       kfree(presp);
 
        skb_queue_purge(&sdata->skb_queue);
 
index 0b09716d22ad6b43a24fef2be6e6551a515c8bb4..135ab463cfd99043db705d83dc49a970951f3fb5 100644 (file)
@@ -443,7 +443,7 @@ struct ieee80211_if_managed {
 
        u8 use_4addr;
 
-       u8 p2p_noa_index;
+       s16 p2p_noa_index;
 
        /* Signal strength from the last Beacon frame in the current BSS. */
        int last_beacon_signal;
@@ -509,8 +509,7 @@ struct ieee80211_if_ibss {
 
        unsigned long ibss_join_req;
        /* probe response/beacon for IBSS */
-       struct sk_buff __rcu *presp;
-       struct sk_buff *skb;
+       struct beacon_data __rcu *presp;
 
        spinlock_t incomplete_lock;
        struct list_head incomplete_stations;
@@ -1023,8 +1022,7 @@ struct ieee80211_local {
        struct ieee80211_sub_if_data __rcu *scan_sdata;
        struct ieee80211_channel *csa_channel;
        /* For backward compatibility only -- do not use */
-       struct ieee80211_channel *_oper_channel;
-       enum nl80211_channel_type _oper_channel_type;
+       struct cfg80211_chan_def _oper_chandef;
 
        /* Temporary remain-on-channel for off-channel operations */
        struct ieee80211_channel *tmp_channel;
@@ -1160,11 +1158,8 @@ struct ieee802_11_elems {
        /* pointers to IEs */
        const u8 *ssid;
        const u8 *supp_rates;
-       const u8 *fh_params;
        const u8 *ds_params;
-       const u8 *cf_params;
        const struct ieee80211_tim_ie *tim;
-       const u8 *ibss_params;
        const u8 *challenge;
        const u8 *rsn;
        const u8 *erp_info;
@@ -1186,21 +1181,15 @@ struct ieee802_11_elems {
        const struct ieee80211_channel_sw_ie *ch_switch_ie;
        const u8 *country_elem;
        const u8 *pwr_constr_elem;
-       const u8 *quiet_elem;   /* first quite element */
-       const u8 *timeout_int;
+       const struct ieee80211_timeout_interval_ie *timeout_int;
        const u8 *opmode_notif;
 
        /* length of them, respectively */
        u8 ssid_len;
        u8 supp_rates_len;
-       u8 fh_params_len;
-       u8 ds_params_len;
-       u8 cf_params_len;
        u8 tim_len;
-       u8 ibss_params_len;
        u8 challenge_len;
        u8 rsn_len;
-       u8 erp_info_len;
        u8 ext_supp_rates_len;
        u8 wmm_info_len;
        u8 wmm_param_len;
@@ -1210,9 +1199,6 @@ struct ieee802_11_elems {
        u8 prep_len;
        u8 perr_len;
        u8 country_elem_len;
-       u8 quiet_elem_len;
-       u8 num_of_quiet_elem;   /* can be more the one */
-       u8 timeout_int_len;
 
        /* whether a parse error occurred while retrieving these elements */
        bool parse_error;
@@ -1330,7 +1316,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
 void ieee80211_offchannel_return(struct ieee80211_local *local);
 void ieee80211_roc_setup(struct ieee80211_local *local);
 void ieee80211_start_next_roc(struct ieee80211_local *local);
-void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
+void ieee80211_roc_purge(struct ieee80211_local *local,
+                        struct ieee80211_sub_if_data *sdata);
 void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free);
 void ieee80211_sw_roc_work(struct work_struct *work);
 void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
@@ -1351,6 +1338,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
                                    const int offset);
 int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up);
 void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
+int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
+void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
 
 bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
@@ -1505,11 +1494,15 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
        ieee80211_tx_skb_tid(sdata, skb, 7);
 }
 
-void ieee802_11_parse_elems(u8 *start, size_t len,
-                           struct ieee802_11_elems *elems);
 u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                               struct ieee802_11_elems *elems,
                               u64 filter, u32 crc);
+static inline void ieee802_11_parse_elems(u8 *start, size_t len,
+                                         struct ieee802_11_elems *elems)
+{
+       ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
+}
+
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
                              enum ieee80211_band band);
 
index 69aaba79a9f782ac337c0dfc2ae221f2f8d4962e..146b1320af4e5946a27b17d7bb6ddb557ed62b12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Interface handling (except master interface)
+ * Interface handling
  *
  * Copyright 2002-2005, Instant802 Networks, Inc.
  * Copyright 2005-2006, Devicescape Software, Inc.
@@ -346,7 +346,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
        sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
 }
 
-static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
+int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
        int ret;
@@ -399,7 +399,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
        return 0;
 }
 
-static void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
+void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
 
@@ -584,7 +584,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                case NL80211_IFTYPE_P2P_DEVICE:
                        break;
                default:
-                       netif_carrier_on(dev);
+                       /* not reached */
+                       WARN_ON(1);
                }
 
                /*
@@ -641,8 +642,28 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 
        ieee80211_recalc_ps(local, -1);
 
-       if (dev)
-               netif_tx_start_all_queues(dev);
+       if (dev) {
+               unsigned long flags;
+               int n_acs = IEEE80211_NUM_ACS;
+               int ac;
+
+               if (local->hw.queues < IEEE80211_NUM_ACS)
+                       n_acs = 1;
+
+               spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+               if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE ||
+                   (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 &&
+                    skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) {
+                       for (ac = 0; ac < n_acs; ac++) {
+                               int ac_queue = sdata->vif.hw_queue[ac];
+
+                               if (local->queue_stop_reasons[ac_queue] == 0 &&
+                                   skb_queue_empty(&local->pending[ac_queue]))
+                                       netif_start_subqueue(dev, ac);
+                       }
+               }
+               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+       }
 
        return 0;
  err_del_interface:
@@ -696,7 +717,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        if (sdata->dev)
                netif_tx_stop_all_queues(sdata->dev);
 
-       ieee80211_roc_purge(sdata);
+       ieee80211_roc_purge(local, sdata);
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION)
                ieee80211_mgd_stop(sdata);
@@ -721,12 +742,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
                     (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
 
-       /*
-        * Don't count this interface for promisc/allmulti while it
-        * is down. dev_mc_unsync() will invoke set_multicast_list
-        * on the master interface which will sync these down to the
-        * hardware as filter flags.
-        */
+       /* don't count this interface for promisc/allmulti while it is down */
        if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
                atomic_dec(&local->iff_allmultis);
 
@@ -747,8 +763,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                                 sdata->dev->addr_len);
                spin_unlock_bh(&local->filter_lock);
                netif_addr_unlock_bh(sdata->dev);
-
-               ieee80211_configure_filter(local);
        }
 
        del_timer_sync(&local->dynamic_ps_timer);
@@ -759,6 +773,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
 
        if (sdata->wdev.cac_started) {
+               WARN_ON(local->suspended);
                mutex_lock(&local->iflist_mtx);
                ieee80211_vif_release_channel(sdata);
                mutex_unlock(&local->iflist_mtx);
@@ -809,14 +824,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                if (local->monitors == 0) {
                        local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
                        hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
-                       ieee80211_del_virtual_monitor(local);
                }
 
                ieee80211_adjust_monitor_flags(sdata, -1);
-               ieee80211_configure_filter(local);
-               mutex_lock(&local->mtx);
-               ieee80211_recalc_idle(local);
-               mutex_unlock(&local->mtx);
                break;
        case NL80211_IFTYPE_P2P_DEVICE:
                /* relies on synchronize_rcu() below */
@@ -846,27 +856,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                /* fall through */
        case NL80211_IFTYPE_AP:
                skb_queue_purge(&sdata->skb_queue);
-
-               if (going_down)
-                       drv_remove_interface(local, sdata);
        }
 
        sdata->bss = NULL;
 
-       ieee80211_recalc_ps(local, -1);
-
-       if (local->open_count == 0) {
-               ieee80211_clear_tx_pending(local);
-               ieee80211_stop_device(local);
-
-               /* no reconfiguring after stop! */
-               hw_reconf_flags = 0;
-       }
-
-       /* do after stop to avoid reconfiguring when we stop anyway */
-       if (hw_reconf_flags)
-               ieee80211_hw_config(local, hw_reconf_flags);
-
        spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
        for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
                skb_queue_walk_safe(&local->pending[i], skb, tmp) {
@@ -879,7 +872,54 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        }
        spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
-       if (local->monitors == local->open_count && local->monitors > 0)
+       if (local->open_count == 0)
+               ieee80211_clear_tx_pending(local);
+
+       /*
+        * If the interface goes down while suspended, presumably because
+        * the device was unplugged and that happens before our resume,
+        * then the driver is already unconfigured and the remainder of
+        * this function isn't needed.
+        * XXX: what about WoWLAN? If the device has software state, e.g.
+        *      memory allocated, it might expect teardown commands from
+        *      mac80211 here?
+        */
+       if (local->suspended) {
+               WARN_ON(local->wowlan);
+               WARN_ON(rtnl_dereference(local->monitor_sdata));
+               return;
+       }
+
+       switch (sdata->vif.type) {
+       case NL80211_IFTYPE_AP_VLAN:
+               break;
+       case NL80211_IFTYPE_MONITOR:
+               if (local->monitors == 0)
+                       ieee80211_del_virtual_monitor(local);
+
+               mutex_lock(&local->mtx);
+               ieee80211_recalc_idle(local);
+               mutex_unlock(&local->mtx);
+               break;
+       default:
+               if (going_down)
+                       drv_remove_interface(local, sdata);
+       }
+
+       ieee80211_recalc_ps(local, -1);
+
+       if (local->open_count == 0) {
+               ieee80211_stop_device(local);
+
+               /* no reconfiguring after stop! */
+               return;
+       }
+
+       /* do after stop to avoid reconfiguring when we stop anyway */
+       ieee80211_configure_filter(local);
+       ieee80211_hw_config(local, hw_reconf_flags);
+
+       if (local->monitors == local->open_count)
                ieee80211_add_virtual_monitor(local);
 }
 
index c6f81ecc36a15bd0375aaeaef0ac5f85e4afc575..52136fd5ba97b63701e70acc1650ded849fcac3b 100644 (file)
@@ -95,42 +95,47 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
 static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_channel *chan;
+       struct cfg80211_chan_def chandef = {};
        u32 changed = 0;
        int power;
-       enum nl80211_channel_type channel_type;
        u32 offchannel_flag;
 
        offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
+
        if (local->scan_channel) {
-               chan = local->scan_channel;
+               chandef.chan = local->scan_channel;
                /* If scanning on oper channel, use whatever channel-type
                 * is currently in use.
                 */
-               if (chan == local->_oper_channel)
-                       channel_type = local->_oper_channel_type;
-               else
-                       channel_type = NL80211_CHAN_NO_HT;
+               if (chandef.chan == local->_oper_chandef.chan) {
+                       chandef = local->_oper_chandef;
+               } else {
+                       chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+                       chandef.center_freq1 = chandef.chan->center_freq;
+               }
        } else if (local->tmp_channel) {
-               chan = local->tmp_channel;
-               channel_type = NL80211_CHAN_NO_HT;
-       } else {
-               chan = local->_oper_channel;
-               channel_type = local->_oper_channel_type;
-       }
-
-       if (chan != local->_oper_channel ||
-           channel_type != local->_oper_channel_type)
+               chandef.chan = local->tmp_channel;
+               chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+               chandef.center_freq1 = chandef.chan->center_freq;
+       } else
+               chandef = local->_oper_chandef;
+
+       WARN(!cfg80211_chandef_valid(&chandef),
+            "control:%d MHz width:%d center: %d/%d MHz",
+            chandef.chan->center_freq, chandef.width,
+            chandef.center_freq1, chandef.center_freq2);
+
+       if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef))
                local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
        else
                local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
 
        offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 
-       if (offchannel_flag || chan != local->hw.conf.channel ||
-           channel_type != local->hw.conf.channel_type) {
-               local->hw.conf.channel = chan;
-               local->hw.conf.channel_type = channel_type;
+       if (offchannel_flag ||
+           !cfg80211_chandef_identical(&local->hw.conf.chandef,
+                                       &local->_oper_chandef)) {
+               local->hw.conf.chandef = chandef;
                changed |= IEEE80211_CONF_CHANGE_CHANNEL;
        }
 
@@ -146,7 +151,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
                changed |= IEEE80211_CONF_CHANGE_SMPS;
        }
 
-       power = chan->max_power;
+       power = chandef.chan->max_power;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
@@ -587,6 +592,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                                         IEEE80211_RADIOTAP_MCS_HAVE_BW;
        local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
                                         IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
+       local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+       local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
        local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
        wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
        wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;
@@ -738,11 +745,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                sband = local->hw.wiphy->bands[band];
                if (!sband)
                        continue;
-               if (!local->use_chanctx && !local->_oper_channel) {
+               if (!local->use_chanctx && !local->_oper_chandef.chan) {
                        /* init channel we're on */
-                       local->hw.conf.channel =
-                       local->_oper_channel = &sband->channels[0];
-                       local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
+                       struct cfg80211_chan_def chandef = {
+                               .chan = &sband->channels[0],
+                               .width = NL80211_CHAN_NO_HT,
+                               .center_freq1 = sband->channels[0].center_freq,
+                               .center_freq2 = 0
+                       };
+                       local->hw.conf.chandef = local->_oper_chandef = chandef;
                }
                cfg80211_chandef_create(&local->monitor_chandef,
                                        &sband->channels[0],
@@ -829,22 +840,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (supp_ht)
                local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
 
-       if (supp_vht) {
+       if (supp_vht)
                local->scan_ies_len +=
                        2 + sizeof(struct ieee80211_vht_cap);
 
-               /*
-                * (for now at least), drivers wanting to use VHT must
-                * support channel contexts, as they contain all the
-                * necessary VHT information and the global hw config
-                * doesn't (yet)
-                */
-               if (WARN_ON(!local->use_chanctx)) {
-                       result = -EINVAL;
-                       goto fail_wiphy_register;
-               }
-       }
-
        if (!local->ops->hw_scan) {
                /* For hw_scan, driver needs to set these up. */
                local->hw.wiphy->max_scan_ssids = 4;
index 123a300cef574de7b695399a413549f1d0fb3f5a..fd1024ef393b1518bf71f348771b7834374ceb4a 100644 (file)
@@ -907,7 +907,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
            (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
                return;
 
-       if (elems.ds_params && elems.ds_params_len == 1)
+       if (elems.ds_params)
                freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
        else
                freq = rx_status->freq;
index 6ffabbe99c4633989b2a45ab7f8bf18c376b75c2..da158774eebb69eac8abf0a23472f766532cf00a 100644 (file)
@@ -275,7 +275,8 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
 void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
 void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
                            struct ieee80211_mgmt *mgmt, size_t len);
-int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst);
+struct mesh_path *
+mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst);
 
 int mesh_path_add_gate(struct mesh_path *mpath);
 int mesh_path_send_to_gates(struct mesh_path *mpath);
index bdb8d3b145870d9f212ca4a0dfc5b3de596f60c0..c82d5e6a24c03977ee40d7fbdf0e98ab6a210318 100644 (file)
@@ -144,7 +144,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
                *pos++ = WLAN_EID_PREQ;
                break;
        case MPATH_PREP:
-               mhwmp_dbg(sdata, "sending PREP to %pM\n", target);
+               mhwmp_dbg(sdata, "sending PREP to %pM\n", orig_addr);
                ie_len = 31;
                pos = skb_put(skb, 2 + ie_len);
                *pos++ = WLAN_EID_PREP;
@@ -445,9 +445,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
                                }
                        }
                } else {
-                       mesh_path_add(sdata, orig_addr);
-                       mpath = mesh_path_lookup(sdata, orig_addr);
-                       if (!mpath) {
+                       mpath = mesh_path_add(sdata, orig_addr);
+                       if (IS_ERR(mpath)) {
                                rcu_read_unlock();
                                return 0;
                        }
@@ -486,9 +485,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
                                        (last_hop_metric > mpath->metric)))
                                fresh_info = false;
                } else {
-                       mesh_path_add(sdata, ta);
-                       mpath = mesh_path_lookup(sdata, ta);
-                       if (!mpath) {
+                       mpath = mesh_path_add(sdata, ta);
+                       if (IS_ERR(mpath)) {
                                rcu_read_unlock();
                                return 0;
                        }
@@ -661,7 +659,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
        u32 target_sn, orig_sn, lifetime;
 
        mhwmp_dbg(sdata, "received PREP from %pM\n",
-                 PREP_IE_ORIG_ADDR(prep_elem));
+                 PREP_IE_TARGET_ADDR(prep_elem));
 
        orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
        if (ether_addr_equal(orig_addr, sdata->vif.addr))
@@ -804,9 +802,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
 
        mpath = mesh_path_lookup(sdata, orig_addr);
        if (!mpath) {
-               mesh_path_add(sdata, orig_addr);
-               mpath = mesh_path_lookup(sdata, orig_addr);
-               if (!mpath) {
+               mpath = mesh_path_add(sdata, orig_addr);
+               if (IS_ERR(mpath)) {
                        rcu_read_unlock();
                        sdata->u.mesh.mshstats.dropped_frames_no_route++;
                        return;
@@ -1098,11 +1095,10 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
        /* no nexthop found, start resolving */
        mpath = mesh_path_lookup(sdata, target_addr);
        if (!mpath) {
-               mesh_path_add(sdata, target_addr);
-               mpath = mesh_path_lookup(sdata, target_addr);
-               if (!mpath) {
+               mpath = mesh_path_add(sdata, target_addr);
+               if (IS_ERR(mpath)) {
                        mesh_path_discard_frame(sdata, skb);
-                       err = -ENOSPC;
+                       err = PTR_ERR(mpath);
                        goto endlookup;
                }
        }
index dc7c8df40c2c3093c0ec81c7af1fbeeac973ecd9..89aacfd2756d627287ce4d381e7038d0b0ebdd5e 100644 (file)
@@ -493,7 +493,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
  *
  * State: the initial state of the new path is set to 0
  */
-int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
+struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
+                               const u8 *dst)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
        struct ieee80211_local *local = sdata->local;
@@ -502,18 +503,33 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
        struct mpath_node *node, *new_node;
        struct hlist_head *bucket;
        int grow = 0;
-       int err = 0;
+       int err;
        u32 hash_idx;
 
        if (ether_addr_equal(dst, sdata->vif.addr))
                /* never add ourselves as neighbours */
-               return -ENOTSUPP;
+               return ERR_PTR(-ENOTSUPP);
 
        if (is_multicast_ether_addr(dst))
-               return -ENOTSUPP;
+               return ERR_PTR(-ENOTSUPP);
 
        if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0)
-               return -ENOSPC;
+               return ERR_PTR(-ENOSPC);
+
+       read_lock_bh(&pathtbl_resize_lock);
+       tbl = resize_dereference_mesh_paths();
+
+       hash_idx = mesh_table_hash(dst, sdata, tbl);
+       bucket = &tbl->hash_buckets[hash_idx];
+
+       spin_lock(&tbl->hashwlock[hash_idx]);
+
+       hlist_for_each_entry(node, bucket, list) {
+               mpath = node->mpath;
+               if (mpath->sdata == sdata &&
+                   ether_addr_equal(dst, mpath->dst))
+                       goto found;
+       }
 
        err = -ENOMEM;
        new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC);
@@ -524,7 +540,6 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
        if (!new_node)
                goto err_node_alloc;
 
-       read_lock_bh(&pathtbl_resize_lock);
        memcpy(new_mpath->dst, dst, ETH_ALEN);
        eth_broadcast_addr(new_mpath->rann_snd_addr);
        new_mpath->is_root = false;
@@ -538,21 +553,6 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
        spin_lock_init(&new_mpath->state_lock);
        init_timer(&new_mpath->timer);
 
-       tbl = resize_dereference_mesh_paths();
-
-       hash_idx = mesh_table_hash(dst, sdata, tbl);
-       bucket = &tbl->hash_buckets[hash_idx];
-
-       spin_lock(&tbl->hashwlock[hash_idx]);
-
-       err = -EEXIST;
-       hlist_for_each_entry(node, bucket, list) {
-               mpath = node->mpath;
-               if (mpath->sdata == sdata &&
-                   ether_addr_equal(dst, mpath->dst))
-                       goto err_exists;
-       }
-
        hlist_add_head_rcu(&new_node->list, bucket);
        if (atomic_inc_return(&tbl->entries) >=
            tbl->mean_chain_len * (tbl->hash_mask + 1))
@@ -560,23 +560,23 @@ int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
 
        mesh_paths_generation++;
 
-       spin_unlock(&tbl->hashwlock[hash_idx]);
-       read_unlock_bh(&pathtbl_resize_lock);
        if (grow) {
                set_bit(MESH_WORK_GROW_MPATH_TABLE,  &ifmsh->wrkq_flags);
                ieee80211_queue_work(&local->hw, &sdata->work);
        }
-       return 0;
-
-err_exists:
+       mpath = new_mpath;
+found:
        spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
-       kfree(new_node);
+       return mpath;
+
 err_node_alloc:
        kfree(new_mpath);
 err_path_alloc:
        atomic_dec(&sdata->u.mesh.mpaths);
-       return err;
+       spin_unlock(&tbl->hashwlock[hash_idx]);
+       read_unlock_bh(&pathtbl_resize_lock);
+       return ERR_PTR(err);
 }
 
 static void mesh_table_free_rcu(struct rcu_head *rcu)
index e06dbbf8cb4c2bfe5e88855c21b473b38618fadc..9c4968938472683c6e07d1f35c9ec396720563f8 100644 (file)
@@ -56,7 +56,10 @@ MODULE_PARM_DESC(max_probe_tries,
  * probe on beacon miss before declaring the connection lost
  * default to what we want.
  */
-#define IEEE80211_BEACON_LOSS_COUNT    7
+static int beacon_loss_count = 7;
+module_param(beacon_loss_count, int, 0644);
+MODULE_PARM_DESC(beacon_loss_count,
+                "Number of beacon intervals before we decide beacon was lost.");
 
 /*
  * Time the connection can be idle before we probe
@@ -985,6 +988,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 {
        struct ieee80211_sub_if_data *sdata =
                container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
        if (!ieee80211_sdata_running(sdata))
@@ -994,21 +998,30 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        if (!ifmgd->associated)
                goto out;
 
-       sdata->local->_oper_channel = sdata->local->csa_channel;
-       if (!sdata->local->ops->channel_switch) {
+       /*
+        * FIXME: Here we are downgrading to NL80211_CHAN_WIDTH_20_NOHT
+        * and don't adjust our ht/vht settings
+        * This is wrong - we should behave according to the CSA params
+        */
+       local->_oper_chandef.chan = local->csa_channel;
+       local->_oper_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
+       local->_oper_chandef.center_freq1 =
+               local->_oper_chandef.chan->center_freq;
+       local->_oper_chandef.center_freq2 = 0;
+
+       if (!local->ops->channel_switch) {
                /* call "hw_config" only if doing sw channel switch */
-               ieee80211_hw_config(sdata->local,
-                       IEEE80211_CONF_CHANGE_CHANNEL);
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
        } else {
                /* update the device channel directly */
-               sdata->local->hw.conf.channel = sdata->local->_oper_channel;
+               local->hw.conf.chandef = local->_oper_chandef;
        }
 
        /* XXX: shouldn't really modify cfg80211-owned data! */
-       ifmgd->associated->channel = sdata->local->_oper_channel;
+       ifmgd->associated->channel = local->_oper_chandef.chan;
 
        /* XXX: wait for a beacon first? */
-       ieee80211_wake_queues_by_reason(&sdata->local->hw,
+       ieee80211_wake_queues_by_reason(&local->hw,
                                        IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_CSA);
  out:
@@ -1430,13 +1443,11 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
 
        if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
            !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
-               netif_tx_stop_all_queues(sdata->dev);
-
-               if (drv_tx_frames_pending(local))
+               if (drv_tx_frames_pending(local)) {
                        mod_timer(&local->dynamic_ps_timer, jiffies +
                                  msecs_to_jiffies(
                                  local->hw.conf.dynamic_ps_timeout));
-               else {
+               else {
                        ieee80211_send_nullfunc(local, sdata, 1);
                        /* Flush to get the tx status of nullfunc frame */
                        ieee80211_flush_queues(local, sdata);
@@ -1450,9 +1461,6 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
                local->hw.conf.flags |= IEEE80211_CONF_PS;
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
        }
-
-       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
-               netif_tx_wake_all_queues(sdata->dev);
 }
 
 void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -1645,7 +1653,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value);
 
        sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
-               IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
+               beacon_loss_count * bss_conf->beacon_int));
 
        sdata->u.mgd.associated = cbss;
        memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
@@ -1658,18 +1666,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                rcu_read_lock();
                ies = rcu_dereference(cbss->ies);
                if (ies) {
-                       u8 noa[2];
                        int ret;
 
                        ret = cfg80211_get_p2p_attr(
                                        ies->data, ies->len,
                                        IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
-                                       noa, sizeof(noa));
+                                       (u8 *) &bss_conf->p2p_noa_attr,
+                                       sizeof(bss_conf->p2p_noa_attr));
                        if (ret >= 2) {
-                               bss_conf->p2p_oppps = noa[1] & 0x80;
-                               bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+                               sdata->u.mgd.p2p_noa_index =
+                                       bss_conf->p2p_noa_attr.index;
                                bss_info_changed |= BSS_CHANGED_P2P_PS;
-                               sdata->u.mgd.p2p_noa_index = noa[0];
                        }
                }
                rcu_read_unlock();
@@ -1713,7 +1720,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        ieee80211_recalc_smps(sdata);
        ieee80211_recalc_ps_vif(sdata);
 
-       netif_tx_start_all_queues(sdata->dev);
        netif_carrier_on(sdata->dev);
 }
 
@@ -1736,22 +1742,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        ieee80211_stop_poll(sdata);
 
        ifmgd->associated = NULL;
-
-       /*
-        * we need to commit the associated = NULL change because the
-        * scan code uses that to determine whether this iface should
-        * go to/wake up from powersave or not -- and could otherwise
-        * wake the queues erroneously.
-        */
-       smp_mb();
-
-       /*
-        * Thus, we can only afterwards stop the queues -- to account
-        * for the case where another CPU is finishing a scan at this
-        * time -- we don't want the scan code to enable queues.
-        */
-
-       netif_tx_stop_all_queues(sdata->dev);
        netif_carrier_off(sdata->dev);
 
        /*
@@ -1794,8 +1784,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        changed |= BSS_CHANGED_ASSOC;
        sdata->vif.bss_conf.assoc = false;
 
-       sdata->vif.bss_conf.p2p_ctwindow = 0;
-       sdata->vif.bss_conf.p2p_oppps = false;
+       ifmgd->p2p_noa_index = -1;
+       memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
+              sizeof(sdata->vif.bss_conf.p2p_noa_attr));
 
        /* on the next assoc, re-program HT/VHT parameters */
        memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
@@ -1975,12 +1966,15 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
                goto out;
        }
 
-       if (beacon)
+       if (beacon) {
                mlme_dbg_ratelimited(sdata,
-                                    "detected beacon loss from AP - probing\n");
+                                    "detected beacon loss from AP (missed %d beacons) - probing\n",
+                                    beacon_loss_count);
 
-       ieee80211_cqm_rssi_notify(&sdata->vif,
-               NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL);
+               ieee80211_cqm_rssi_notify(&sdata->vif,
+                                         NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
+                                         GFP_KERNEL);
+       }
 
        /*
         * The driver/our work has already reported this event or the
@@ -2613,10 +2607,10 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 
        if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
-           elems.timeout_int && elems.timeout_int_len == 5 &&
-           elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
+           elems.timeout_int &&
+           elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
                u32 tu, ms;
-               tu = get_unaligned_le32(elems.timeout_int + 1);
+               tu = le32_to_cpu(elems.timeout_int->value);
                ms = tu * 1024 / 1000;
                sdata_info(sdata,
                           "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
@@ -2679,7 +2673,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                }
        }
 
-       if (elems->ds_params && elems->ds_params_len == 1)
+       if (elems->ds_params)
                freq = ieee80211_channel_to_frequency(elems->ds_params[0],
                                                      rx_status->band);
        else
@@ -2957,22 +2951,30 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        }
 
        if (sdata->vif.p2p) {
-               u8 noa[2];
+               struct ieee80211_p2p_noa_attr noa = {};
                int ret;
 
                ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable,
                                            len - baselen,
                                            IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
-                                           noa, sizeof(noa));
-               if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) {
-                       bss_conf->p2p_oppps = noa[1] & 0x80;
-                       bss_conf->p2p_ctwindow = noa[1] & 0x7f;
+                                           (u8 *) &noa, sizeof(noa));
+               if (ret >= 2) {
+                       if (sdata->u.mgd.p2p_noa_index != noa.index) {
+                               /* valid noa_attr and index changed */
+                               sdata->u.mgd.p2p_noa_index = noa.index;
+                               memcpy(&bss_conf->p2p_noa_attr, &noa, sizeof(noa));
+                               changed |= BSS_CHANGED_P2P_PS;
+                               /*
+                                * make sure we update all information, the CRC
+                                * mechanism doesn't look at P2P attributes.
+                                */
+                               ifmgd->beacon_crc_valid = false;
+                       }
+               } else if (sdata->u.mgd.p2p_noa_index != -1) {
+                       /* noa_attr not found and we had valid noa_attr before */
+                       sdata->u.mgd.p2p_noa_index = -1;
+                       memset(&bss_conf->p2p_noa_attr, 0, sizeof(bss_conf->p2p_noa_attr));
                        changed |= BSS_CHANGED_P2P_PS;
-                       sdata->u.mgd.p2p_noa_index = noa[0];
-                       /*
-                        * make sure we update all information, the CRC
-                        * mechanism doesn't look at P2P attributes.
-                        */
                        ifmgd->beacon_crc_valid = false;
                }
        }
@@ -3014,7 +3016,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                changed |= BSS_CHANGED_DTIM_PERIOD;
        }
 
-       if (elems.erp_info && elems.erp_info_len >= 1) {
+       if (elems.erp_info) {
                erp_valid = true;
                erp_value = elems.erp_info[0];
        } else {
@@ -3513,8 +3515,9 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 
        ifmgd->flags = 0;
        ifmgd->powersave = sdata->wdev.ps;
-       ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
-       ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
+       ifmgd->uapsd_queues = sdata->local->hw.uapsd_queues;
+       ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
+       ifmgd->p2p_noa_index = -1;
 
        mutex_init(&ifmgd->mtx);
 
@@ -4063,7 +4066,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        rcu_read_unlock();
 
        if (bss->wmm_used && bss->uapsd_supported &&
-           (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
+           (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) &&
+           sdata->wmm_acm != 0xff) {
                assoc_data->uapsd = true;
                ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
        } else {
index cce795871ab1fa2373a7828d4c9872695bb0ef1e..acd1f71adc0386ab588f0939309e2367330f2b29 100644 (file)
@@ -445,15 +445,15 @@ void ieee80211_roc_setup(struct ieee80211_local *local)
        INIT_LIST_HEAD(&local->roc_list);
 }
 
-void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
+void ieee80211_roc_purge(struct ieee80211_local *local,
+                        struct ieee80211_sub_if_data *sdata)
 {
-       struct ieee80211_local *local = sdata->local;
        struct ieee80211_roc_work *roc, *tmp;
        LIST_HEAD(tmp_list);
 
        mutex_lock(&local->mtx);
        list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
-               if (roc->sdata != sdata)
+               if (sdata && roc->sdata != sdata)
                        continue;
 
                if (roc->started && local->ops->remain_on_channel) {
index 3d16f4e6174388f27e030f9612a64bbd752c04ea..d1c021b62fe5abbe1609f25546895f5db0ed91bc 100644 (file)
@@ -19,6 +19,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 
        ieee80211_dfs_cac_cancel(local);
 
+       ieee80211_roc_purge(local, NULL);
+
+       ieee80211_del_virtual_monitor(local);
+
        if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
                mutex_lock(&local->sta_mtx);
                list_for_each_entry(sta, &local->sta_list, list) {
@@ -101,10 +105,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
                drv_remove_interface(local, sdata);
        }
 
-       sdata = rtnl_dereference(local->monitor_sdata);
-       if (sdata)
-               drv_remove_interface(local, sdata);
-
        /*
         * We disconnected on all interfaces before suspend, all channel
         * contexts should be released.
index cb34cbbaa20ce9f003b22f17e5def519d83873af..33fbf104569047826078c4d528c5b7d0e14abdd2 100644 (file)
@@ -98,9 +98,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
        }
 
        /* save the ERP value so that it is available at association time */
-       if (elems->erp_info && elems->erp_info_len >= 1 &&
-                       (!elems->parse_error ||
-                        !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
+       if (elems->erp_info && (!elems->parse_error ||
+                               !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
                bss->erp_value = elems->erp_info[0];
                bss->has_erp_value = true;
                if (!elems->parse_error)
@@ -384,7 +383,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
 {
        int i;
        struct ieee80211_sub_if_data *sdata;
-       enum ieee80211_band band = local->hw.conf.channel->band;
+       enum ieee80211_band band = local->hw.conf.chandef.chan->band;
        u32 tx_flags;
 
        tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
@@ -401,7 +400,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
                        local->scan_req->ssids[i].ssid_len,
                        local->scan_req->ie, local->scan_req->ie_len,
                        local->scan_req->rates[band], false,
-                       tx_flags, local->hw.conf.channel, true);
+                       tx_flags, local->hw.conf.chandef.chan, true);
 
        /*
         * After sending probe requests, wait for probe responses
@@ -467,7 +466,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
        if (local->ops->hw_scan) {
                __set_bit(SCAN_HW_SCANNING, &local->scanning);
        } else if ((req->n_channels == 1) &&
-                  (req->channels[0] == local->_oper_channel)) {
+                  (req->channels[0] == local->_oper_chandef.chan)) {
                /*
                 * If we are scanning only on the operating channel
                 * then we do not need to stop normal activities
index c5899797a8d4b0f01da791da6e2b1be8a685627f..8286dcef228b492fd4491b7ea416701d243459ae 100644 (file)
 #define VIF_PR_FMT     " vif:%s(%d%s)"
 #define VIF_PR_ARG     __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
 
-#define CHANDEF_ENTRY  __field(u32, control_freq)                              \
-                       __field(u32, chan_width)                                \
-                       __field(u32, center_freq1)                              \
+#define CHANDEF_ENTRY  __field(u32, control_freq)                                      \
+                       __field(u32, chan_width)                                        \
+                       __field(u32, center_freq1)                                      \
                        __field(u32, center_freq2)
-#define CHANDEF_ASSIGN(c)                                                      \
-                       __entry->control_freq = (c)->chan->center_freq;         \
-                       __entry->chan_width = (c)->width;                       \
-                       __entry->center_freq1 = (c)->center_freq1;              \
+#define CHANDEF_ASSIGN(c)                                                              \
+                       __entry->control_freq = (c)->chan ? (c)->chan->center_freq : 0; \
+                       __entry->chan_width = (c)->width;                               \
+                       __entry->center_freq1 = (c)->center_freq1;                      \
                        __entry->center_freq2 = (c)->center_freq2;
 #define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz"
-#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width,             \
+#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width,                     \
                        __entry->center_freq1, __entry->center_freq2
 
-#define CHANCTX_ENTRY  CHANDEF_ENTRY                                           \
-                       __field(u8, rx_chains_static)                           \
+#define CHANCTX_ENTRY  CHANDEF_ENTRY                                                   \
+                       __field(u8, rx_chains_static)                                   \
                        __field(u8, rx_chains_dynamic)
-#define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def)                          \
-                       __entry->rx_chains_static = ctx->conf.rx_chains_static; \
+#define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def)                                  \
+                       __entry->rx_chains_static = ctx->conf.rx_chains_static;         \
                        __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
 #define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d"
-#define CHANCTX_PR_ARG CHANDEF_PR_ARG,                                         \
+#define CHANCTX_PR_ARG CHANDEF_PR_ARG,                                                 \
                        __entry->rx_chains_static, __entry->rx_chains_dynamic
 
 
@@ -286,8 +286,7 @@ TRACE_EVENT(drv_config,
                __field(u16, listen_interval)
                __field(u8, long_frame_max_tx_count)
                __field(u8, short_frame_max_tx_count)
-               __field(int, center_freq)
-               __field(int, channel_type)
+               CHANDEF_ENTRY
                __field(int, smps)
        ),
 
@@ -303,15 +302,13 @@ TRACE_EVENT(drv_config,
                        local->hw.conf.long_frame_max_tx_count;
                __entry->short_frame_max_tx_count =
                        local->hw.conf.short_frame_max_tx_count;
-               __entry->center_freq = local->hw.conf.channel ?
-                                       local->hw.conf.channel->center_freq : 0;
-               __entry->channel_type = local->hw.conf.channel_type;
+               CHANDEF_ASSIGN(&local->hw.conf.chandef)
                __entry->smps = local->hw.conf.smps_mode;
        ),
 
        TP_printk(
-               LOCAL_PR_FMT " ch:%#x freq:%d",
-               LOCAL_PR_ARG, __entry->changed, __entry->center_freq
+               LOCAL_PR_FMT " ch:%#x" CHANDEF_PR_FMT,
+               LOCAL_PR_ARG, __entry->changed, CHANDEF_PR_ARG
        )
 );
 
@@ -359,8 +356,7 @@ TRACE_EVENT(drv_bss_info_changed,
                __dynamic_array(u8, ssid, info->ssid_len);
                __field(bool, hidden_ssid);
                __field(int, txpower)
-               __field(u8, p2p_ctwindow)
-               __field(bool, p2p_oppps)
+               __field(u8, p2p_oppps_ctwindow)
        ),
 
        TP_fast_assign(
@@ -400,8 +396,7 @@ TRACE_EVENT(drv_bss_info_changed,
                memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
                __entry->hidden_ssid = info->hidden_ssid;
                __entry->txpower = info->txpower;
-               __entry->p2p_ctwindow = info->p2p_ctwindow;
-               __entry->p2p_oppps = info->p2p_oppps;
+               __entry->p2p_oppps_ctwindow = info->p2p_noa_attr.oppps_ctwindow;
        ),
 
        TP_printk(
index 2a6ae8030bd9e8997cdc4662aeabbc9644ac19cf..aad0bf5d88122a6cde6e4b9d4765f9f671aba441 100644 (file)
@@ -1709,7 +1709,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
        if (chanctx_conf)
                chan = chanctx_conf->def.chan;
        else if (!local->use_chanctx)
-               chan = local->_oper_channel;
+               chan = local->_oper_chandef.chan;
        else
                goto fail_rcu;
 
@@ -1843,7 +1843,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                 * This is the exception! WDS style interfaces are prohibited
                 * when channel contexts are in used so this must be valid
                 */
-               band = local->hw.conf.channel->band;
+               band = local->hw.conf.chandef.chan->band;
                break;
 #ifdef CONFIG_MAC80211_MESH
        case NL80211_IFTYPE_MESH_POINT:
@@ -2442,14 +2442,17 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
        } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
                struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
                struct ieee80211_hdr *hdr;
-               struct sk_buff *presp = rcu_dereference(ifibss->presp);
+               struct beacon_data *presp = rcu_dereference(ifibss->presp);
 
                if (!presp)
                        goto out;
 
-               skb = skb_copy(presp, GFP_ATOMIC);
+               skb = dev_alloc_skb(local->tx_headroom + presp->head_len);
                if (!skb)
                        goto out;
+               skb_reserve(skb, local->tx_headroom);
+               memcpy(skb_put(skb, presp->head_len), presp->head,
+                      presp->head_len);
 
                hdr = (struct ieee80211_hdr *) skb->data;
                hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
index a7368870c8ee10cf7ee48dc764bc466974eac8ae..447e6651e7fa7d0faa293b1ac1b431b6d14005eb 100644 (file)
@@ -738,17 +738,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        elems->supp_rates = pos;
                        elems->supp_rates_len = elen;
                        break;
-               case WLAN_EID_FH_PARAMS:
-                       elems->fh_params = pos;
-                       elems->fh_params_len = elen;
-                       break;
                case WLAN_EID_DS_PARAMS:
-                       elems->ds_params = pos;
-                       elems->ds_params_len = elen;
-                       break;
-               case WLAN_EID_CF_PARAMS:
-                       elems->cf_params = pos;
-                       elems->cf_params_len = elen;
+                       if (elen >= 1)
+                               elems->ds_params = pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_TIM:
                        if (elen >= sizeof(struct ieee80211_tim_ie)) {
@@ -757,10 +751,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        } else
                                elem_parse_failed = true;
                        break;
-               case WLAN_EID_IBSS_PARAMS:
-                       elems->ibss_params = pos;
-                       elems->ibss_params_len = elen;
-                       break;
                case WLAN_EID_CHALLENGE:
                        elems->challenge = pos;
                        elems->challenge_len = elen;
@@ -790,8 +780,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        elems->rsn_len = elen;
                        break;
                case WLAN_EID_ERP_INFO:
-                       elems->erp_info = pos;
-                       elems->erp_info_len = elen;
+                       if (elen >= 1)
+                               elems->erp_info = pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_EXT_SUPP_RATES:
                        elems->ext_supp_rates = pos;
@@ -870,13 +862,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        }
                        elems->ch_switch_ie = (void *)pos;
                        break;
-               case WLAN_EID_QUIET:
-                       if (!elems->quiet_elem) {
-                               elems->quiet_elem = pos;
-                               elems->quiet_elem_len = elen;
-                       }
-                       elems->num_of_quiet_elem++;
-                       break;
                case WLAN_EID_COUNTRY:
                        elems->country_elem = pos;
                        elems->country_elem_len = elen;
@@ -889,8 +874,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        elems->pwr_constr_elem = pos;
                        break;
                case WLAN_EID_TIMEOUT_INTERVAL:
-                       elems->timeout_int = pos;
-                       elems->timeout_int_len = elen;
+                       if (elen >= sizeof(struct ieee80211_timeout_interval_ie))
+                               elems->timeout_int = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                default:
                        break;
@@ -911,12 +898,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
        return crc;
 }
 
-void ieee802_11_parse_elems(u8 *start, size_t len,
-                           struct ieee802_11_elems *elems)
-{
-       ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
-}
-
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
                               bool bss_notify)
 {
@@ -1474,6 +1455,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        /* add interfaces */
        sdata = rtnl_dereference(local->monitor_sdata);
        if (sdata) {
+               /* in HW restart it exists already */
+               WARN_ON(local->resuming);
                res = drv_add_interface(local, sdata);
                if (WARN_ON(res)) {
                        rcu_assign_pointer(local->monitor_sdata, NULL);
@@ -1663,6 +1646,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        local->in_reconfig = false;
        barrier();
 
+       if (local->monitors == local->open_count && local->monitors > 0)
+               ieee80211_add_virtual_monitor(local);
+
        /*
         * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
         * sessions can be established after a resume.
@@ -2056,7 +2042,7 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif)
                /* non-managed type inferfaces */
                return 0;
        }
-       return ifmgd->ave_beacon_signal;
+       return ifmgd->ave_beacon_signal / 16;
 }
 EXPORT_SYMBOL_GPL(ieee80211_ave_rssi);
 
@@ -2171,8 +2157,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
                /* currently not handled */
                WARN_ON(1);
        else {
-               cfg80211_chandef_create(&chandef, local->hw.conf.channel,
-                                       local->hw.conf.channel_type);
+               chandef = local->hw.conf.chandef;
                cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
        }
 }
This page took 0.102948 seconds and 5 git commands to generate.