[IPSEC]: Fix transport-mode async resume on intput without netfilter
[linux-2.6] / net / mac80211 / ieee80211.c
index 6378850..9c14e3d 100644 (file)
@@ -34,6 +34,8 @@
 #include "debugfs.h"
 #include "debugfs_netdev.h"
 
+#define SUPP_MCS_SET_LEN 16
+
 /*
  * For seeing transmitted packets on monitor interfaces
  * we have a radiotap header too.
@@ -350,11 +352,14 @@ static int ieee80211_stop(struct net_device *dev)
                synchronize_rcu();
                skb_queue_purge(&sdata->u.sta.skb_queue);
 
-               if (!local->ops->hw_scan &&
-                   local->scan_dev == sdata->dev) {
-                       local->sta_scanning = 0;
-                       cancel_delayed_work(&local->scan_work);
+               if (local->scan_dev == sdata->dev) {
+                       if (!local->ops->hw_scan) {
+                               local->sta_sw_scanning = 0;
+                               cancel_delayed_work(&local->scan_work);
+                       } else
+                               local->sta_hw_scanning = 0;
                }
+
                flush_workqueue(local->hw.workqueue);
 
                sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
@@ -526,7 +531,7 @@ int ieee80211_hw_config(struct ieee80211_local *local)
        struct ieee80211_channel *chan;
        int ret = 0;
 
-       if (local->sta_scanning) {
+       if (local->sta_sw_scanning) {
                chan = local->scan_channel;
                mode = local->scan_hw_mode;
        } else {
@@ -560,6 +565,55 @@ int ieee80211_hw_config(struct ieee80211_local *local)
        return ret;
 }
 
+/**
+ * ieee80211_hw_config_ht should be used only after legacy configuration
+ * has been determined, as ht configuration depends upon the hardware's
+ * HT abilities for a _specific_ band.
+ */
+int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht,
+                          struct ieee80211_ht_info *req_ht_cap,
+                          struct ieee80211_ht_bss_info *req_bss_cap)
+{
+       struct ieee80211_conf *conf = &local->hw.conf;
+       struct ieee80211_hw_mode *mode = conf->mode;
+       int i;
+
+       /* HT is not supported */
+       if (!mode->ht_info.ht_supported) {
+               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
+               return -EOPNOTSUPP;
+       }
+
+       /* disable HT */
+       if (!enable_ht) {
+               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
+       } else {
+               conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
+               conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap;
+               conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS);
+               conf->ht_conf.cap |=
+                       mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS;
+               conf->ht_bss_conf.primary_channel =
+                       req_bss_cap->primary_channel;
+               conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
+               conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
+               for (i = 0; i < SUPP_MCS_SET_LEN; i++)
+                       conf->ht_conf.supp_mcs_set[i] =
+                               mode->ht_info.supp_mcs_set[i] &
+                                 req_ht_cap->supp_mcs_set[i];
+
+               /* In STA mode, this gives us indication
+                * to the AP's mode of operation */
+               conf->ht_conf.ht_supported = 1;
+               conf->ht_conf.ampdu_factor = req_ht_cap->ampdu_factor;
+               conf->ht_conf.ampdu_density = req_ht_cap->ampdu_density;
+       }
+
+       local->ops->conf_ht(local_to_hw(local), &local->hw.conf);
+
+       return 0;
+}
+
 void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
@@ -678,6 +732,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
                pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
        if (control->flags & IEEE80211_TXCTL_REQUEUE)
                pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
+       if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
+               pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
        pkt_data->queue = control->queue;
 
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -805,10 +861,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
                        sta_info_put(sta);
                        return;
                }
-       } else {
-               /* FIXME: STUPID to call this with both local and local->mdev */
-               rate_control_tx_status(local, local->mdev, skb, status);
-       }
+       } else
+               rate_control_tx_status(local->mdev, skb, status);
 
        ieee80211_led_tx(local, 0);
 
@@ -1260,33 +1314,50 @@ static int __init ieee80211_init(void)
 
        BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
 
-#ifdef CONFIG_MAC80211_RCSIMPLE
+#ifdef CONFIG_MAC80211_RC_SIMPLE
        ret = ieee80211_rate_control_register(&mac80211_rcsimple);
        if (ret)
-               return ret;
+               goto fail;
+#endif
+
+#ifdef CONFIG_MAC80211_RC_PID
+       ret = ieee80211_rate_control_register(&mac80211_rcpid);
+       if (ret)
+               goto fail;
 #endif
 
        ret = ieee80211_wme_register();
        if (ret) {
-#ifdef CONFIG_MAC80211_RCSIMPLE
-               ieee80211_rate_control_unregister(&mac80211_rcsimple);
-#endif
                printk(KERN_DEBUG "ieee80211_init: failed to "
                       "initialize WME (err=%d)\n", ret);
-               return ret;
+               goto fail;
        }
 
        ieee80211_debugfs_netdev_init();
        ieee80211_regdomain_init();
 
        return 0;
+
+fail:
+
+#ifdef CONFIG_MAC80211_RC_SIMPLE
+       ieee80211_rate_control_unregister(&mac80211_rcsimple);
+#endif
+#ifdef CONFIG_MAC80211_RC_PID
+       ieee80211_rate_control_unregister(&mac80211_rcpid);
+#endif
+
+       return ret;
 }
 
 static void __exit ieee80211_exit(void)
 {
-#ifdef CONFIG_MAC80211_RCSIMPLE
+#ifdef CONFIG_MAC80211_RC_SIMPLE
        ieee80211_rate_control_unregister(&mac80211_rcsimple);
 #endif
+#ifdef CONFIG_MAC80211_RC_PID
+       ieee80211_rate_control_unregister(&mac80211_rcpid);
+#endif
 
        ieee80211_wme_unregister();
        ieee80211_debugfs_netdev_exit();