mac80211: make retry limits part of hw config
Johannes Berg [Tue, 14 Oct 2008 17:17:54 +0000 (19:17 +0200)]
Instead of having a separate callback, use the HW config callback
with a new flag to change retry limits.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

15 files changed:
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
include/net/mac80211.h
net/mac80211/debugfs.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/tx.c
net/mac80211/wext.c

index f499107..41cd114 100644 (file)
@@ -1659,7 +1659,6 @@ static struct ieee80211_ops ath9k_ops = {
        .get_tkip_seq       = NULL,
        .set_rts_threshold  = NULL,
        .set_frag_threshold = NULL,
-       .set_retry_limit    = NULL,
        .get_tsf            = ath9k_get_tsf,
        .reset_tsf          = ath9k_reset_tsf,
        .tx_last_beacon     = NULL,
index 2e81af1..9aeeb65 100644 (file)
@@ -3320,6 +3320,22 @@ init_failure:
        return err;
 }
 
+/* Write the short and long frame retry limit values. */
+static void b43_set_retry_limits(struct b43_wldev *dev,
+                                unsigned int short_retry,
+                                unsigned int long_retry)
+{
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
+                       short_retry);
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
+                       long_retry);
+}
+
 static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
@@ -3340,6 +3356,13 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
+                                         conf->long_frame_max_tx_count);
+       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+       if (!changed)
+               goto out_unlock_mutex;
+
        /* Disable IRQs while reconfiguring the device.
         * This makes it possible to drop the spinlock throughout
         * the reconfiguration process. */
@@ -3859,22 +3882,6 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
-/* Write the short and long frame retry limit values. */
-static void b43_set_retry_limits(struct b43_wldev *dev,
-                                unsigned int short_retry,
-                                unsigned int long_retry)
-{
-       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter. */
-       short_retry = min(short_retry, (unsigned int)0xF);
-       long_retry = min(long_retry, (unsigned int)0xF);
-
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
-                       short_retry);
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
-                       long_retry);
-}
-
 static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
 {
        u16 pu_delay;
@@ -4195,26 +4202,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
        cancel_work_sync(&(wl->txpower_adjust_work));
 }
 
-static int b43_op_set_retry_limit(struct ieee80211_hw *hw,
-                                 u32 short_retry_limit, u32 long_retry_limit)
-{
-       struct b43_wl *wl = hw_to_b43_wl(hw);
-       struct b43_wldev *dev;
-       int err = 0;
-
-       mutex_lock(&wl->mutex);
-       dev = wl->current_dev;
-       if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) {
-               err = -ENODEV;
-               goto out_unlock;
-       }
-       b43_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
 static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
                                 struct ieee80211_sta *sta, bool set)
 {
@@ -4251,7 +4238,6 @@ static const struct ieee80211_ops b43_hw_ops = {
        .get_tx_stats           = b43_op_get_tx_stats,
        .start                  = b43_op_start,
        .stop                   = b43_op_stop,
-       .set_retry_limit        = b43_op_set_retry_limit,
        .set_tim                = b43_op_beacon_set_tim,
        .sta_notify             = b43_op_sta_notify,
 };
index 793cc39..78e4636 100644 (file)
@@ -2556,6 +2556,20 @@ init_failure:
        return err;
 }
 
+/* Write the short and long frame retry limit values. */
+static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
+                                      unsigned int short_retry,
+                                      unsigned int long_retry)
+{
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
+}
+
 static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
                                   u32 changed)
 {
@@ -2577,6 +2591,14 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               b43legacy_set_retry_limits(dev,
+                                          conf->short_frame_max_tx_count,
+                                          conf->long_frame_max_tx_count);
+       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+       if (!changed)
+               goto out_unlock_mutex;
+
        /* Switch the PHY mode (if necessary). */
        switch (conf->channel->band) {
        case IEEE80211_BAND_2GHZ:
@@ -2989,20 +3011,6 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
-/* Write the short and long frame retry limit values. */
-static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
-                                      unsigned int short_retry,
-                                      unsigned int long_retry)
-{
-       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter. */
-       short_retry = min(short_retry, (unsigned int)0xF);
-       long_retry = min(long_retry, (unsigned int)0xF);
-
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
-}
-
 static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
                                          bool idle) {
        u16 pu_delay = 1050;
@@ -3367,28 +3375,6 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)
        mutex_unlock(&wl->mutex);
 }
 
-static int b43legacy_op_set_retry_limit(struct ieee80211_hw *hw,
-                                       u32 short_retry_limit,
-                                       u32 long_retry_limit)
-{
-       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-       struct b43legacy_wldev *dev;
-       int err = 0;
-
-       mutex_lock(&wl->mutex);
-       dev = wl->current_dev;
-       if (unlikely(!dev ||
-                    (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) {
-               err = -ENODEV;
-               goto out_unlock;
-       }
-       b43legacy_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
 static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
                                       struct ieee80211_sta *sta, bool set)
 {
@@ -3414,7 +3400,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
        .get_tx_stats           = b43legacy_op_get_tx_stats,
        .start                  = b43legacy_op_start,
        .stop                   = b43legacy_op_stop,
-       .set_retry_limit        = b43legacy_op_set_retry_limit,
        .set_tim                = b43legacy_op_beacon_set_tim,
 };
 
index 96eaf5f..1adca7a 100644 (file)
@@ -1574,7 +1574,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
        .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt2400pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2400pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -1603,6 +1602,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
        .config_intf            = rt2400pci_config_intf,
        .config_erp             = rt2400pci_config_erp,
        .config                 = rt2400pci_config,
+       .set_retry_limit        = rt2400pci_set_retry_limit,
 };
 
 static const struct data_queue_desc rt2400pci_queue_rx = {
index 8b772ab..85b0387 100644 (file)
@@ -1874,7 +1874,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
        .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt2500pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -1903,6 +1902,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
        .config_intf            = rt2500pci_config_intf,
        .config_erp             = rt2500pci_config_erp,
        .config                 = rt2500pci_config,
+       .set_retry_limit        = rt2500pci_set_retry_limit,
 };
 
 static const struct data_queue_desc rt2500pci_queue_rx = {
index 8ec8f7e..0887e89 100644 (file)
@@ -599,6 +599,9 @@ struct rt2x00lib_ops {
 #define CONFIG_UPDATE_SLOT_TIME        ( 1 << 5 )
 #define CONFIG_UPDATE_BEACON_INT       ( 1 << 6 )
 #define CONFIG_UPDATE_ALL              0xffff
+
+       int (*set_retry_limit) (struct ieee80211_hw *hw,
+                               u32 short_limit, u32 long_limit);
 };
 
 /*
index da7b49a..9311833 100644 (file)
@@ -349,6 +349,15 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
        if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
                return 0;
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+               rt2x00dev->ops->lib->set_retry_limit(hw,
+                       conf->short_frame_max_tx_count,
+                       conf->long_frame_max_tx_count);
+       }
+       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+       if (!changed)
+               return 0;
+
        /*
         * Only change device state when the radio is enabled. It does not
         * matter what parameters we have configured when the radio is disabled
index 45f69f8..08eb896 100644 (file)
@@ -2724,7 +2724,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt61pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt61pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -2757,6 +2756,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .config_intf            = rt61pci_config_intf,
        .config_erp             = rt61pci_config_erp,
        .config                 = rt61pci_config,
+       .set_retry_limit        = rt61pci_set_retry_limit,
 };
 
 static const struct data_queue_desc rt61pci_queue_rx = {
index 336fecb..7f89782 100644 (file)
@@ -2315,7 +2315,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt73usb_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt73usb_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -2347,6 +2346,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .config_intf            = rt73usb_config_intf,
        .config_erp             = rt73usb_config_erp,
        .config                 = rt73usb_config,
+       .set_retry_limit        = rt73usb_set_retry_limit,
 };
 
 static const struct data_queue_desc rt73usb_queue_rx = {
index 34e8569..fd52300 100644 (file)
@@ -473,6 +473,7 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
  * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
  * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
  * @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed
+ * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
  */
 enum ieee80211_conf_changed {
        IEEE80211_CONF_CHANGE_RADIO_ENABLED     = BIT(0),
@@ -482,6 +483,7 @@ enum ieee80211_conf_changed {
        IEEE80211_CONF_CHANGE_PS                = BIT(4),
        IEEE80211_CONF_CHANGE_POWER             = BIT(5),
        IEEE80211_CONF_CHANGE_CHANNEL           = BIT(6),
+       IEEE80211_CONF_CHANGE_RETRY_LIMITS      = BIT(7),
 };
 
 /**
@@ -497,6 +499,12 @@ enum ieee80211_conf_changed {
  * @ht_cap: describes current self configuration of 802.11n HT capabilities
  * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
  * @channel: the channel to tune to
+ * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
+ *    (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
+ *    but actually means the number of transmissions not the number of retries
+ * @short_frame_max_tx_count: Maximum number of transmissions for a "short"
+ *    frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
+ *    number of transmissions not the number of retries
  */
 struct ieee80211_conf {
        int beacon_int;
@@ -506,6 +514,8 @@ struct ieee80211_conf {
        u16 listen_interval;
        bool radio_enabled;
 
+       u8 long_frame_max_tx_count, short_frame_max_tx_count;
+
        struct ieee80211_channel *channel;
 
        struct ieee80211_sta_ht_cap ht_cap;
@@ -1190,8 +1200,6 @@ enum ieee80211_ampdu_mlme_action {
  *     the device does fragmentation by itself; if this method is assigned then
  *     the stack will not do fragmentation.
  *
- * @set_retry_limit: Configuration of retry limits (if device needs it)
- *
  * @sta_notify: Notifies low level driver about addition or removal
  *     of assocaited station or AP.
  *
@@ -1261,8 +1269,6 @@ struct ieee80211_ops {
                             u32 *iv32, u16 *iv16);
        int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
-       int (*set_retry_limit)(struct ieee80211_hw *hw,
-                              u32 short_retry, u32 long_retr);
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, struct ieee80211_sta *sta);
        int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
index 767dbca..2697a2f 100644 (file)
@@ -52,9 +52,9 @@ DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
 DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
                      local->fragmentation_threshold);
 DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
-                     local->short_retry_limit);
+                     local->hw.conf.short_frame_max_tx_count);
 DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
-                     local->long_retry_limit);
+                     local->hw.conf.long_frame_max_tx_count);
 DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
                      local->total_ps_buffered);
 DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x",
index 8198447..f1ef522 100644 (file)
@@ -635,8 +635,6 @@ struct ieee80211_local {
 
        int rts_threshold;
        int fragmentation_threshold;
-       int short_retry_limit; /* dot11ShortRetryLimit */
-       int long_retry_limit; /* dot11LongRetryLimit */
 
        struct crypto_blkcipher *wep_tx_tfm;
        struct crypto_blkcipher *wep_rx_tfm;
index c936017..59be9e7 100644 (file)
@@ -673,8 +673,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
        local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       local->short_retry_limit = 7;
-       local->long_retry_limit = 4;
+       local->hw.conf.long_frame_max_tx_count = 4;
+       local->hw.conf.short_frame_max_tx_count = 7;
        local->hw.conf.radio_enabled = true;
 
        INIT_LIST_HEAD(&local->interfaces);
index 8bcabef..dd440a0 100644 (file)
@@ -505,10 +505,10 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
                                info->flags |=
                                        IEEE80211_TX_CTL_LONG_RETRY_LIMIT;
                                info->control.retry_limit =
-                                       tx->local->long_retry_limit;
+                                       tx->local->hw.conf.long_frame_max_tx_count - 1;
                        } else {
                                info->control.retry_limit =
-                                       tx->local->short_retry_limit;
+                                       tx->local->hw.conf.short_frame_max_tx_count - 1;
                        }
                } else {
                        info->control.retry_limit = 1;
index 94c4b35..f7e442f 100644 (file)
@@ -802,21 +802,16 @@ static int ieee80211_ioctl_siwretry(struct net_device *dev,
            (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
                return -EINVAL;
 
-       if (retry->flags & IW_RETRY_MAX)
-               local->long_retry_limit = retry->value;
-       else if (retry->flags & IW_RETRY_MIN)
-               local->short_retry_limit = retry->value;
-       else {
-               local->long_retry_limit = retry->value;
-               local->short_retry_limit = retry->value;
+       if (retry->flags & IW_RETRY_MAX) {
+               local->hw.conf.long_frame_max_tx_count = retry->value;
+       } else if (retry->flags & IW_RETRY_MIN) {
+               local->hw.conf.short_frame_max_tx_count = retry->value;
+       } else {
+               local->hw.conf.long_frame_max_tx_count = retry->value;
+               local->hw.conf.short_frame_max_tx_count = retry->value;
        }
 
-       if (local->ops->set_retry_limit) {
-               return local->ops->set_retry_limit(
-                       local_to_hw(local),
-                       local->short_retry_limit,
-                       local->long_retry_limit);
-       }
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
 
        return 0;
 }
@@ -833,14 +828,15 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
                /* first return min value, iwconfig will ask max value
                 * later if needed */
                retry->flags |= IW_RETRY_LIMIT;
-               retry->value = local->short_retry_limit;
-               if (local->long_retry_limit != local->short_retry_limit)
+               retry->value = local->hw.conf.short_frame_max_tx_count;
+               if (local->hw.conf.long_frame_max_tx_count !=
+                   local->hw.conf.short_frame_max_tx_count)
                        retry->flags |= IW_RETRY_MIN;
                return 0;
        }
        if (retry->flags & IW_RETRY_MAX) {
                retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
-               retry->value = local->long_retry_limit;
+               retry->value = local->hw.conf.long_frame_max_tx_count;
        }
 
        return 0;