]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/mac80211/main.c
migrate_mode.h is not exported to user mode
[karo-tx-linux.git] / net / mac80211 / main.c
index cae443563ec9d98a8230de9fae394b960fa66621..0a0d94ad9b08374fe90e0f653da4d4b352e8f6c9 100644 (file)
@@ -47,7 +47,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
        if (atomic_read(&local->iff_allmultis))
                new_flags |= FIF_ALLMULTI;
 
-       if (local->monitors || local->scanning)
+       if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning))
                new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
        if (local->fif_probe_req || local->probe_req_reg)
@@ -92,50 +92,9 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
        ieee80211_configure_filter(local);
 }
 
-/*
- * Returns true if we are logically configured to be on
- * the operating channel AND the hardware-conf is currently
- * configured on the operating channel.  Compares channel-type
- * as well.
- */
-bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
-{
-       struct ieee80211_channel *chan, *scan_chan;
-       enum nl80211_channel_type channel_type;
-
-       /* This logic needs to match logic in ieee80211_hw_config */
-       if (local->scan_channel) {
-               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;
-       } else if (local->tmp_channel) {
-               chan = scan_chan = local->tmp_channel;
-               channel_type = local->tmp_channel_type;
-       } else {
-               chan = local->oper_channel;
-               channel_type = local->_oper_channel_type;
-       }
-
-       if (chan != local->oper_channel ||
-           channel_type != local->_oper_channel_type)
-               return false;
-
-       /* Check current hardware-config against oper_channel. */
-       if ((local->oper_channel != local->hw.conf.channel) ||
-           (local->_oper_channel_type != local->hw.conf.channel_type))
-               return false;
-
-       return true;
-}
-
 int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 {
-       struct ieee80211_channel *chan, *scan_chan;
+       struct ieee80211_channel *chan;
        int ret = 0;
        int power;
        enum nl80211_channel_type channel_type;
@@ -143,14 +102,12 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 
        might_sleep();
 
-       scan_chan = local->scan_channel;
-
        /* If this off-channel logic ever changes,  ieee80211_on_oper_channel
         * may need to change as well.
         */
        offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
-       if (scan_chan) {
-               chan = scan_chan;
+       if (local->scan_channel) {
+               chan = local->scan_channel;
                /* If scanning on oper channel, use whatever channel-type
                 * is currently in use.
                 */
@@ -159,7 +116,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
                else
                        channel_type = NL80211_CHAN_NO_HT;
        } else if (local->tmp_channel) {
-               chan = scan_chan = local->tmp_channel;
+               chan = local->tmp_channel;
                channel_type = local->tmp_channel_type;
        } else {
                chan = local->oper_channel;
@@ -193,8 +150,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
                changed |= IEEE80211_CONF_CHANGE_SMPS;
        }
 
-       if ((local->scanning & SCAN_SW_SCANNING) ||
-           (local->scanning & SCAN_HW_SCANNING))
+       if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+           test_bit(SCAN_HW_SCANNING, &local->scanning))
                power = chan->max_power;
        else
                power = local->power_constr_level ?
@@ -436,9 +393,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
        sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
        bss_conf = &sdata->vif.bss_conf;
 
-       if (!ieee80211_sdata_running(sdata))
-               return NOTIFY_DONE;
-
        /* ARP filtering is only supported in managed mode */
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                return NOTIFY_DONE;
@@ -467,7 +421,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
        }
        bss_conf->arp_addr_cnt = c;
 
-       /* Configure driver only if associated */
+       /* Configure driver only if associated (which also implies it is up) */
        if (ifmgd->associated) {
                bss_conf->arp_filter_enabled = sdata->arp_filter_state;
                ieee80211_bss_info_change_notify(sdata,
@@ -560,6 +514,19 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
        },
 };
 
+static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
+       .ampdu_params_info = IEEE80211_HT_AMPDU_PARM_FACTOR |
+                            IEEE80211_HT_AMPDU_PARM_DENSITY,
+
+       .cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                               IEEE80211_HT_CAP_MAX_AMSDU |
+                               IEEE80211_HT_CAP_SGI_40),
+       .mcs = {
+               .rx_mask = { 0xff, 0xff, 0xff, 0xff, 0xff,
+                            0xff, 0xff, 0xff, 0xff, 0xff, },
+       },
+};
+
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                                        const struct ieee80211_ops *ops)
 {
@@ -595,7 +562,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        wiphy->flags |= WIPHY_FLAG_NETNS_OK |
                        WIPHY_FLAG_4ADDR_AP |
-                       WIPHY_FLAG_4ADDR_STATION;
+                       WIPHY_FLAG_4ADDR_STATION |
+                       WIPHY_FLAG_REPORTS_OBSS |
+                       WIPHY_FLAG_OFFCHAN_TX |
+                       WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+
+       wiphy->features = NL80211_FEATURE_SK_TX_STATUS |
+                         NL80211_FEATURE_HT_IBSS;
 
        if (!ops->set_key)
                wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -608,7 +581,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
 
-       BUG_ON(!ops->tx);
+       BUG_ON(!ops->tx && !ops->tx_frags);
        BUG_ON(!ops->start);
        BUG_ON(!ops->stop);
        BUG_ON(!ops->config);
@@ -628,6 +601,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        local->user_power_level = -1;
        local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
        local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
+       wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
 
        INIT_LIST_HEAD(&local->interfaces);
 
@@ -670,6 +644,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        INIT_WORK(&local->sched_scan_stopped_work,
                  ieee80211_sched_scan_stopped_work);
 
+       spin_lock_init(&local->ack_status_lock);
+       idr_init(&local->ack_status_frames);
+       /* preallocate at least one entry */
+       idr_pre_get(&local->ack_status_frames, GFP_KERNEL);
+
        sta_info_init(local);
 
        for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -1051,6 +1030,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 }
 EXPORT_SYMBOL(ieee80211_unregister_hw);
 
+static int ieee80211_free_ack_frame(int id, void *p, void *data)
+{
+       WARN_ONCE(1, "Have pending ack frames!\n");
+       kfree_skb(p);
+       return 0;
+}
+
 void ieee80211_free_hw(struct ieee80211_hw *hw)
 {
        struct ieee80211_local *local = hw_to_local(hw);
@@ -1061,6 +1047,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
        if (local->wiphy_ciphers_allocated)
                kfree(local->hw.wiphy->cipher_suites);
 
+       idr_for_each(&local->ack_status_frames,
+                    ieee80211_free_ack_frame, NULL);
+       idr_destroy(&local->ack_status_frames);
+
        wiphy_free(local->hw.wiphy);
 }
 EXPORT_SYMBOL(ieee80211_free_hw);