]> err.no Git - linux-2.6/blobdiff - drivers/net/wireless/rt2x00/rt2x00mac.c
rt2x00: Always call ieee80211_stop_queue() when return NETDEV_TX_BUSY
[linux-2.6] / drivers / net / wireless / rt2x00 / rt2x00mac.c
index 4a6a0bd01ff192ead09ab3b929f33f57f7c18882..1ab2fb6c38da5a6a572e7499a045028d3bf73045 100644 (file)
        Abstract: rt2x00 generic mac80211 routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 
@@ -89,7 +84,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
         */
        if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) {
                ieee80211_stop_queues(hw);
-               return 0;
+               return NETDEV_TX_OK;
        }
 
        /*
@@ -115,15 +110,24 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
            (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
                               IEEE80211_TXCTL_USE_CTS_PROTECT))) {
-               if (rt2x00_ring_free(ring) <= 1)
+               if (rt2x00_ring_free(ring) <= 1) {
+                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                        return NETDEV_TX_BUSY;
+               }
 
-               if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control))
+               if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) {
+                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                        return NETDEV_TX_BUSY;
+               }
        }
 
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control))
+       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) {
+               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                return NETDEV_TX_BUSY;
+       }
+
+       if (rt2x00_ring_full(ring))
+               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
 
        if (rt2x00dev->ops->lib->kick_tx_queue)
                rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
@@ -196,6 +200,14 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct interface *intf = &rt2x00dev->interface;
 
+       /* FIXME: Beaconing is broken in rt2x00. */
+       if (conf->type == IEEE80211_IF_TYPE_IBSS ||
+           conf->type == IEEE80211_IF_TYPE_AP) {
+               ERROR(rt2x00dev,
+                     "rt2x00 does not support Adhoc or Master mode");
+               return -EOPNOTSUPP;
+       }
+
        /*
         * Don't allow interfaces to be added while
         * either the device has disappeared or when
@@ -239,7 +251,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
                return;
 
        intf->id = 0;
-       intf->type = INVALID_INTERFACE;
+       intf->type = IEEE80211_IF_TYPE_INVALID;
        memset(&intf->bssid, 0x00, ETH_ALEN);
        memset(&intf->mac, 0x00, ETH_ALEN);