]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/rt2x00/rt2x00mac.c
rt2x00: Reorganize beacon handling
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / rt2x00 / rt2x00mac.c
index b02dbc8a666e46a7acde175f5c377c27e6a4985e..16b72d9ca1c35a3d337123f2b3931ce9e751c6cb 100644 (file)
@@ -34,7 +34,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
                                struct sk_buff *frag_skb)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
-       struct skb_frame_desc *skbdesc;
        struct ieee80211_tx_info *rts_info;
        struct sk_buff *skb;
        int size;
@@ -65,6 +64,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
        rts_info = IEEE80211_SKB_CB(skb);
        rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+       rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
        rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
        rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
 
@@ -82,14 +82,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
                                  frag_skb->data, size, tx_info,
                                  (struct ieee80211_rts *)(skb->data));
 
-       /*
-        * Initialize skb descriptor
-        */
-       skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
-       skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
-
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
+       if (rt2x00queue_write_tx_frame(queue, skb)) {
                WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
                return NETDEV_TX_BUSY;
        }
@@ -135,18 +128,16 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        }
 
        /*
-        * If CTS/RTS is required. and this frame is not CTS or RTS,
-        * create and queue that frame first. But make sure we have
-        * at least enough entries available to send this CTS/RTS
-        * frame as well as the data frame.
+        * If CTS/RTS is required. create and queue that frame first.
+        * Make sure we have at least enough entries available to send
+        * this CTS/RTS frame as well as the data frame.
         * Note that when the driver has set the set_rts_threshold()
         * callback function it doesn't need software generation of
-        * neither RTS or CTS-to-self frames and handles everything
+        * either RTS or CTS-to-self frame and handles everything
         * inside the hardware.
         */
        frame_control = le16_to_cpu(ieee80211hdr->frame_control);
-       if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
-           (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
+       if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
                               IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
            !rt2x00dev->ops->hw->set_rts_threshold) {
                if (rt2x00queue_available(queue) <= 1) {
@@ -160,17 +151,14 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                }
        }
 
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
+       if (rt2x00queue_write_tx_frame(queue, skb)) {
                ieee80211_stop_queue(rt2x00dev->hw, qid);
                return NETDEV_TX_BUSY;
        }
 
-       if (rt2x00queue_full(queue))
+       if (rt2x00queue_threshold(queue))
                ieee80211_stop_queue(rt2x00dev->hw, qid);
 
-       if (rt2x00dev->ops->lib->kick_tx_queue)
-               rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
-
        return NETDEV_TX_OK;
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_tx);
@@ -360,7 +348,8 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct rt2x00_intf *intf = vif_to_intf(vif);
-       int status;
+       int update_bssid = 0;
+       int status = 0;
 
        /*
         * Mac80211 might be calling this function while we are trying
@@ -372,12 +361,13 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
        spin_lock(&intf->lock);
 
        /*
-        * If the interface does not work in master mode,
-        * then the bssid value in the interface structure
-        * should now be set.
+        * conf->bssid can be NULL if coming from the internal
+        * beacon update routine.
         */
-       if (conf->type != IEEE80211_IF_TYPE_AP)
+       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
+               update_bssid = 1;
                memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
+       }
 
        spin_unlock(&intf->lock);
 
@@ -387,17 +377,14 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
         * values as arguments we make keep access to rt2x00_intf thread safe
         * even without the lock.
         */
-       rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid);
+       rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+                             update_bssid ? conf->bssid : NULL);
 
        /*
-        * We only need to initialize the beacon when master mode is enabled.
+        * Update the beacon.
         */
-       if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon)
-               return 0;
-
-       status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, conf->beacon);
-       if (status)
-               dev_kfree_skb(conf->beacon);
+       if (conf->changed & IEEE80211_IFCC_BEACON)
+               status = rt2x00queue_update_beacon(rt2x00dev, vif);
 
        return status;
 }
@@ -513,7 +500,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
         * When the erp information has changed, we should perform
         * additional configuration steps. For all other changes we are done.
         */
-       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+       if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_CTS_PROT)) {
                if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
                        rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
                else
@@ -524,7 +511,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
        if (delayed) {
                intf->delayed_flags |= delayed;
-               queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+               schedule_work(&rt2x00dev->intf_work);
        }
        spin_unlock(&intf->lock);
 }