include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / net / wireless / p54 / fwio.c
index dc4f3f5..c43a5d4 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 
@@ -320,7 +321,7 @@ int p54_setup_mac(struct p54_common *priv)
                return -ENOMEM;
 
        setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup));
-       if (priv->hw->conf.radio_enabled) {
+       if (!(priv->hw->conf.flags & IEEE80211_CONF_IDLE)) {
                switch (priv->mode) {
                case NL80211_IFTYPE_STATION:
                        mode = P54_FILTER_TYPE_STATION;
@@ -348,8 +349,9 @@ int p54_setup_mac(struct p54_common *priv)
                     (priv->filter_flags & FIF_OTHER_BSS)) &&
                    (mode != P54_FILTER_TYPE_PROMISCUOUS))
                        mode |= P54_FILTER_TYPE_TRANSPARENT;
-       } else
+       } else {
                mode = P54_FILTER_TYPE_HIBERNATE;
+       }
 
        setup->mac_mode = cpu_to_le16(mode);
        memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
@@ -585,7 +587,8 @@ int p54_set_ps(struct p54_common *priv)
        unsigned int i;
        u16 mode;
 
-       if (priv->hw->conf.flags & IEEE80211_CONF_PS)
+       if (priv->hw->conf.flags & IEEE80211_CONF_PS &&
+           !priv->powersave_override)
                mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
                       P54_PSM_CHECKSUM | P54_PSM_MCBC;
        else
@@ -607,8 +610,8 @@ int p54_set_ps(struct p54_common *priv)
 
        psm->beacon_rssi_skip_max = 200;
        psm->rssi_delta_threshold = 0;
-       psm->nr = 10;
-       psm->exclude[0] = 0;
+       psm->nr = 1;
+       psm->exclude[0] = WLAN_EID_TIM;
 
        p54_tx(priv, skb);
        return 0;
@@ -685,6 +688,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
 
 int p54_fetch_statistics(struct p54_common *priv)
 {
+       struct ieee80211_tx_info *txinfo;
+       struct p54_tx_info *p54info;
        struct sk_buff *skb;
 
        skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL,
@@ -693,6 +698,20 @@ int p54_fetch_statistics(struct p54_common *priv)
        if (!skb)
                return -ENOMEM;
 
+       /*
+        * The statistic feedback causes some extra headaches here, if it
+        * is not to crash/corrupt the firmware data structures.
+        *
+        * Unlike all other Control Get OIDs we can not use helpers like
+        * skb_put to reserve the space for the data we're requesting.
+        * Instead the extra frame length -which will hold the results later-
+        * will only be told to the p54_assign_address, so that following
+        * frames won't be placed into the  allegedly empty area.
+        */
+       txinfo = IEEE80211_SKB_CB(skb);
+       p54info = (void *) txinfo->rate_driver_data;
+       p54info->extra_len = sizeof(struct p54_statistics);
+
        p54_tx(priv, skb);
        return 0;
 }