zd1211rw: collect driver settings and add function to restore theim
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Mon, 31 Jan 2011 18:49:43 +0000 (20:49 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 4 Feb 2011 21:29:50 +0000 (16:29 -0500)
We need HW hard reset later in patchset to reset device after TX-stall.
Collect all settings that we have set to driver for later reset and
add restore function.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.h

index 84ee1b88691236f77228222dba7fc661d5962771..e82f0075ed9303871aa468b651e0c7af9428b79d 100644 (file)
@@ -141,6 +141,9 @@ static void housekeeping_disable(struct zd_mac *mac);
 static void beacon_init(struct zd_mac *mac);
 static void beacon_enable(struct zd_mac *mac);
 static void beacon_disable(struct zd_mac *mac);
+static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble);
+static int zd_mac_config_beacon(struct ieee80211_hw *hw,
+                               struct sk_buff *beacon);
 
 static int zd_reg2alpha2(u8 regdomain, char *alpha2)
 {
@@ -339,6 +342,68 @@ static void zd_op_stop(struct ieee80211_hw *hw)
                dev_kfree_skb_any(skb);
 }
 
+int zd_restore_settings(struct zd_mac *mac)
+{
+       struct sk_buff *beacon;
+       struct zd_mc_hash multicast_hash;
+       unsigned int short_preamble;
+       int r, beacon_interval, beacon_period;
+       u8 channel;
+
+       dev_dbg_f(zd_mac_dev(mac), "\n");
+
+       spin_lock_irq(&mac->lock);
+       multicast_hash = mac->multicast_hash;
+       short_preamble = mac->short_preamble;
+       beacon_interval = mac->beacon.interval;
+       beacon_period = mac->beacon.period;
+       channel = mac->channel;
+       spin_unlock_irq(&mac->lock);
+
+       r = set_mac_and_bssid(mac);
+       if (r < 0) {
+               dev_dbg_f(zd_mac_dev(mac), "set_mac_and_bssid failed, %d\n", r);
+               return r;
+       }
+
+       r = zd_chip_set_channel(&mac->chip, channel);
+       if (r < 0) {
+               dev_dbg_f(zd_mac_dev(mac), "zd_chip_set_channel failed, %d\n",
+                         r);
+               return r;
+       }
+
+       set_rts_cts(mac, short_preamble);
+
+       r = zd_chip_set_multicast_hash(&mac->chip, &multicast_hash);
+       if (r < 0) {
+               dev_dbg_f(zd_mac_dev(mac),
+                         "zd_chip_set_multicast_hash failed, %d\n", r);
+               return r;
+       }
+
+       if (mac->type == NL80211_IFTYPE_MESH_POINT ||
+           mac->type == NL80211_IFTYPE_ADHOC ||
+           mac->type == NL80211_IFTYPE_AP) {
+               if (mac->vif != NULL) {
+                       beacon = ieee80211_beacon_get(mac->hw, mac->vif);
+                       if (beacon) {
+                               zd_mac_config_beacon(mac->hw, beacon);
+                               kfree_skb(beacon);
+                       }
+               }
+
+               zd_set_beacon_interval(&mac->chip, beacon_interval,
+                                       beacon_period, mac->type);
+
+               spin_lock_irq(&mac->lock);
+               mac->beacon.last_update = jiffies;
+               spin_unlock_irq(&mac->lock);
+       }
+
+       return 0;
+}
+
 /**
  * zd_mac_tx_status - reports tx status of a packet if required
  * @hw - a &struct ieee80211_hw pointer
@@ -988,6 +1053,10 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
        struct zd_mac *mac = zd_hw_mac(hw);
        struct ieee80211_conf *conf = &hw->conf;
 
+       spin_lock_irq(&mac->lock);
+       mac->channel = conf->channel->hw_value;
+       spin_unlock_irq(&mac->lock);
+
        return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
 }
 
index 281b3079311a8989bb4cceee39926e60a9d6b36c..c0f239e40bcdb6895b8317fba4d3d7c33e2eb4fa 100644 (file)
@@ -192,6 +192,7 @@ struct zd_mac {
        u8 intr_buffer[USB_MAX_EP_INT_BUFFER];
        u8 regdomain;
        u8 default_regdomain;
+       u8 channel;
        int type;
        int associated;
        unsigned long flags;
@@ -313,6 +314,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length);
 void zd_mac_tx_failed(struct urb *urb);
 void zd_mac_tx_to_dev(struct sk_buff *skb, int error);
 
+int zd_restore_settings(struct zd_mac *mac);
+
 #ifdef DEBUG
 void zd_dump_rx_status(const struct rx_status *status);
 #else