rt2x00: Gather channel information in structure
authorIvo van Doorn <ivdoorn@gmail.com>
Mon, 4 Aug 2008 14:38:47 +0000 (16:38 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 22 Aug 2008 20:29:58 +0000 (16:29 -0400)
Channel information which is read from EEPROM should
be read into an array containing per-channel information.
This removes the requirement of multiple arrays and makes
the channel handling a bit cleaner and easier to expand.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
13 files changed:
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500pci.h
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2500usb.h
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.h

index 4c0538d6099bb2503646d091e4a9e9a1d3417095..0107cec18b262306ad1c9026c9267a440ce60050 100644 (file)
@@ -1404,7 +1404,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
  * RF value list for RF2420 & RF2421
  * Supports: 2.4 GHz
  */
-static const struct rf_channel rf_vals_bg[] = {
+static const struct rf_channel rf_vals_b[] = {
        { 1,  0x00022058, 0x000c1fda, 0x00000101, 0 },
        { 2,  0x00022058, 0x000c1fee, 0x00000101, 0 },
        { 3,  0x00022058, 0x000c2002, 0x00000101, 0 },
@@ -1421,10 +1421,11 @@ static const struct rf_channel rf_vals_bg[] = {
        { 14, 0x00022058, 0x000c20fa, 0x00000101, 0 },
 };
 
-static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-       u8 *txpower;
+       struct channel_info *info;
+       char *tx_power;
        unsigned int i;
 
        /*
@@ -1439,24 +1440,29 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                                rt2x00_eeprom_addr(rt2x00dev,
                                                   EEPROM_MAC_ADDR_0));
 
-       /*
-        * Convert tx_power array in eeprom.
-        */
-       txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
-       for (i = 0; i < 14; i++)
-               txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
-
        /*
         * Initialize hw_mode information.
         */
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK;
-       spec->tx_power_a = NULL;
-       spec->tx_power_bg = txpower;
-       spec->tx_power_default = DEFAULT_TXPOWER;
 
-       spec->num_channels = ARRAY_SIZE(rf_vals_bg);
-       spec->channels = rf_vals_bg;
+       spec->num_channels = ARRAY_SIZE(rf_vals_b);
+       spec->channels = rf_vals_b;
+
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       spec->channels_info = info;
+
+       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
+       for (i = 0; i < 14; i++)
+               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+
+       return 0;
 }
 
 static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1477,7 +1483,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize hw specifications.
         */
-       rt2400pci_probe_hw_mode(rt2x00dev);
+       retval = rt2400pci_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
 
        /*
         * This device requires the atim queue and DMA-mapped skbs.
index bc5564258228be1ef0218fe3863c91c3f3b731f5..bbff381ce3963d11e28b9b261c5c44ab88d3da5b 100644 (file)
 #define MAX_TXPOWER    62
 #define DEFAULT_TXPOWER        39
 
-#define TXPOWER_FROM_DEV(__txpower)                                    \
-({                                                                     \
-       ((__txpower) > MAX_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER :   \
-       ((__txpower) < MIN_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER :   \
-       (((__txpower) - MAX_TXPOWER) + MIN_TXPOWER);                    \
-})
-
-#define TXPOWER_TO_DEV(__txpower)                      \
-({                                                     \
-       (__txpower) += MIN_TXPOWER;                     \
-       ((__txpower) <= MIN_TXPOWER) ? MAX_TXPOWER :    \
-       (((__txpower) >= MAX_TXPOWER) ? MIN_TXPOWER :   \
-       (MAX_TXPOWER - ((__txpower) - MIN_TXPOWER)));   \
-})
+#define __CLAMP_TX(__txpower) \
+       clamp_t(char, (__txpower), MIN_TXPOWER, MAX_TXPOWER)
+
+#define TXPOWER_FROM_DEV(__txpower) \
+       ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER)
+
+#define TXPOWER_TO_DEV(__txpower) \
+       MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)
 
 #endif /* RT2400PCI_H */
index 181a146b4768e229f43d70df03878777c8698b73..e0ff76ff490dd5920cbf4d4d47093f96ac9f568f 100644 (file)
@@ -1721,10 +1721,11 @@ static const struct rf_channel rf_vals_5222[] = {
        { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
 };
 
-static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-       u8 *txpower;
+       struct channel_info *info;
+       char *tx_power;
        unsigned int i;
 
        /*
@@ -1740,21 +1741,11 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                                rt2x00_eeprom_addr(rt2x00dev,
                                                   EEPROM_MAC_ADDR_0));
 
-       /*
-        * Convert tx_power array in eeprom.
-        */
-       txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
-       for (i = 0; i < 14; i++)
-               txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
-
        /*
         * Initialize hw_mode information.
         */
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-       spec->tx_power_a = NULL;
-       spec->tx_power_bg = txpower;
-       spec->tx_power_default = DEFAULT_TXPOWER;
 
        if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
                spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
@@ -1776,6 +1767,26 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                spec->num_channels = ARRAY_SIZE(rf_vals_5222);
                spec->channels = rf_vals_5222;
        }
+
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       spec->channels_info = info;
+
+       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
+       for (i = 0; i < 14; i++)
+               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+
+       if (spec->num_channels > 14) {
+               for (i = 14; i < spec->num_channels; i++)
+                       info[i].tx_power1 = DEFAULT_TXPOWER;
+       }
+
+       return 0;
 }
 
 static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1796,7 +1807,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize hw specifications.
         */
-       rt2500pci_probe_hw_mode(rt2x00dev);
+       retval = rt2500pci_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
 
        /*
         * This device requires the atim queue and DMA-mapped skbs.
index 42f376929ea9287d7471d94f254b94f089277239..8c26bef6cf49cc23d0eecafe635e20f93b89f052 100644 (file)
 #define MAX_TXPOWER    31
 #define DEFAULT_TXPOWER        24
 
-#define TXPOWER_FROM_DEV(__txpower)            \
-({                                             \
-       ((__txpower) > MAX_TXPOWER) ?           \
-               DEFAULT_TXPOWER : (__txpower);  \
-})
-
-#define TXPOWER_TO_DEV(__txpower)                      \
-({                                                     \
-       ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER :    \
-       (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER :   \
-       (__txpower));                                   \
-})
+#define TXPOWER_FROM_DEV(__txpower) \
+       (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
 
 #endif /* RT2500PCI_H */
index cd5af656932dda7c0a49f88d7d3b244180e56af0..3b90ed62214872e64e75e59a82d620149ca205e3 100644 (file)
@@ -1665,10 +1665,11 @@ static const struct rf_channel rf_vals_5222[] = {
        { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
 };
 
-static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-       u8 *txpower;
+       struct channel_info *info;
+       char *tx_power;
        unsigned int i;
 
        /*
@@ -1686,21 +1687,11 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                                rt2x00_eeprom_addr(rt2x00dev,
                                                   EEPROM_MAC_ADDR_0));
 
-       /*
-        * Convert tx_power array in eeprom.
-        */
-       txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
-       for (i = 0; i < 14; i++)
-               txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
-
        /*
         * Initialize hw_mode information.
         */
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-       spec->tx_power_a = NULL;
-       spec->tx_power_bg = txpower;
-       spec->tx_power_default = DEFAULT_TXPOWER;
 
        if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
                spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
@@ -1722,6 +1713,26 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                spec->num_channels = ARRAY_SIZE(rf_vals_5222);
                spec->channels = rf_vals_5222;
        }
+
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       spec->channels_info = info;
+
+       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
+       for (i = 0; i < 14; i++)
+               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+
+       if (spec->num_channels > 14) {
+               for (i = 14; i < spec->num_channels; i++)
+                       info[i].tx_power1 = DEFAULT_TXPOWER;
+       }
+
+       return 0;
 }
 
 static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1742,7 +1753,9 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize hw specifications.
         */
-       rt2500usb_probe_hw_mode(rt2x00dev);
+       retval = rt2500usb_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
 
        /*
         * This device requires the atim queue
index 4769ffeb4cc6ac3a577b2d62905c13ef52d3b3f2..89e5ed24e4f7906a95ae0feaacc992e022840e34 100644 (file)
 #define MAX_TXPOWER    31
 #define DEFAULT_TXPOWER        24
 
-#define TXPOWER_FROM_DEV(__txpower)            \
-({                                             \
-       ((__txpower) > MAX_TXPOWER) ?           \
-               DEFAULT_TXPOWER : (__txpower);  \
-})
-
-#define TXPOWER_TO_DEV(__txpower)                      \
-({                                                     \
-       ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER :    \
-       (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER :   \
-       (__txpower));                                   \
-})
+#define TXPOWER_FROM_DEV(__txpower) \
+       (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
 
 #endif /* RT2500USB_H */
index 0ffd972bb856df48c04c67a7bfa707d53cb6fceb..323bd54eb801a5c1c1c77b6115afff4b27ff7b56 100644 (file)
@@ -143,6 +143,17 @@ struct rf_channel {
        u32 rf4;
 };
 
+/*
+ * Channel information structure
+ */
+struct channel_info {
+       unsigned int flags;
+#define GEOGRAPHY_ALLOWED      0x00000001
+
+       short tx_power1;
+       short tx_power2;
+};
+
 /*
  * Antenna setup values.
  */
@@ -394,10 +405,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
  * @num_channels: Number of supported channels. This is used as array size
  *     for @tx_power_a, @tx_power_bg and @channels.
  * @channels: Device/chipset specific channel values (See &struct rf_channel).
- * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL).
- * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL).
- * @tx_power_default: Default TX power value to use when either
- *     @tx_power_a or @tx_power_bg is missing.
+ * @channels_info: Additional information for channels (See &struct channel_info).
  */
 struct hw_mode_spec {
        unsigned int supported_bands;
@@ -410,10 +418,7 @@ struct hw_mode_spec {
 
        unsigned int num_channels;
        const struct rf_channel *channels;
-
-       const u8 *tx_power_a;
-       const u8 *tx_power_bg;
-       u8 tx_power_default;
+       const struct channel_info *channels_info;
 };
 
 /*
@@ -425,7 +430,9 @@ struct hw_mode_spec {
  */
 struct rt2x00lib_conf {
        struct ieee80211_conf *conf;
+
        struct rf_channel rf;
+       struct channel_info channel;
 
        struct antenna_setup ant;
 
index d134c3be539a7af207ea5543b1e90e1f085ff945..ea37c79620430e0488cf7d5f24a0dbe58765a279 100644 (file)
@@ -245,6 +245,10 @@ config:
                memcpy(&libconf.rf,
                       &rt2x00dev->spec.channels[conf->channel->hw_value],
                       sizeof(libconf.rf));
+
+               memcpy(&libconf.channel,
+                      &rt2x00dev->spec.channels_info[conf->channel->hw_value],
+                      sizeof(libconf.channel));
        }
 
        if (flags & CONFIG_UPDATE_ANTENNA) {
index 182952249a197b232fad096b4ebb83228306eef0..328ff8bc4c16b31e324df229d1464f96ba7d308a 100644 (file)
@@ -818,7 +818,6 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
        struct ieee80211_rate *rates;
        unsigned int num_rates;
        unsigned int i;
-       unsigned char tx_power;
 
        num_rates = 0;
        if (spec->supported_rates & SUPPORT_RATE_CCK)
@@ -844,20 +843,9 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
         * Initialize Channel list.
         */
        for (i = 0; i < spec->num_channels; i++) {
-               if (spec->channels[i].channel <= 14) {
-                       if (spec->tx_power_bg)
-                               tx_power = spec->tx_power_bg[i];
-                       else
-                               tx_power = spec->tx_power_default;
-               } else {
-                       if (spec->tx_power_a)
-                               tx_power = spec->tx_power_a[i];
-                       else
-                               tx_power = spec->tx_power_default;
-               }
-
                rt2x00lib_channel(&channels[i],
-                                 spec->channels[i].channel, tx_power, i);
+                                 spec->channels[i].channel,
+                                 spec->channels_info[i].tx_power1, i);
        }
 
        /*
@@ -909,6 +897,8 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
                rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
                rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
        }
+
+       kfree(rt2x00dev->spec.channels_info);
 }
 
 static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
index 86e7a50374b95c8643f792ad7340bf6c1b5f1b76..87012f88461fdc2686220f0aeb6c23abdbe7cf18 100644 (file)
@@ -2514,10 +2514,11 @@ static const struct rf_channel rf_vals_seq[] = {
        { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 },
 };
 
-static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-       u8 *txpower;
+       struct channel_info *info;
+       char *tx_power;
        unsigned int i;
 
        /*
@@ -2533,21 +2534,11 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                                rt2x00_eeprom_addr(rt2x00dev,
                                                   EEPROM_MAC_ADDR_0));
 
-       /*
-        * Convert tx_power array in eeprom.
-        */
-       txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
-       for (i = 0; i < 14; i++)
-               txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
-
        /*
         * Initialize hw_mode information.
         */
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-       spec->tx_power_a = NULL;
-       spec->tx_power_bg = txpower;
-       spec->tx_power_default = DEFAULT_TXPOWER;
 
        if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) {
                spec->num_channels = 14;
@@ -2561,13 +2552,28 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
            rt2x00_rf(&rt2x00dev->chip, RF5325)) {
                spec->supported_bands |= SUPPORT_BAND_5GHZ;
                spec->num_channels = ARRAY_SIZE(rf_vals_seq);
+       }
+
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       spec->channels_info = info;
 
-               txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
-               for (i = 0; i < 14; i++)
-                       txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
+       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
+       for (i = 0; i < 14; i++)
+               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
 
-               spec->tx_power_a = txpower;
+       if (spec->num_channels > 14) {
+               tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
+               for (i = 14; i < spec->num_channels; i++)
+                       info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
        }
+
+       return 0;
 }
 
 static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -2588,7 +2594,9 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize hw specifications.
         */
-       rt61pci_probe_hw_mode(rt2x00dev);
+       retval = rt61pci_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
 
        /*
         * This device requires firmware and DMA mapped skbs.
index 6d591cef3e5de6cbf7efeebd0253c1a6724364ea..8ec1451308ccea2700ce05e03f0be2229a3c2779 100644 (file)
@@ -1482,17 +1482,10 @@ struct hw_pairwise_ta_entry {
 #define MAX_TXPOWER    31
 #define DEFAULT_TXPOWER        24
 
-#define TXPOWER_FROM_DEV(__txpower)            \
-({                                             \
-       ((__txpower) > MAX_TXPOWER) ?           \
-               DEFAULT_TXPOWER : (__txpower);  \
-})
-
-#define TXPOWER_TO_DEV(__txpower)                      \
-({                                                     \
-       ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER :    \
-       (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER :   \
-       (__txpower));                                   \
-})
+#define TXPOWER_FROM_DEV(__txpower) \
+       (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
 
 #endif /* RT61PCI_H */
index ddba747fed9850eb14728959427229e1e12a01bb..1bd6b3ffca09e9bf29f9232fc7d90b985b0e0a73 100644 (file)
@@ -2107,10 +2107,11 @@ static const struct rf_channel rf_vals_5225_2527[] = {
 };
 
 
-static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
        struct hw_mode_spec *spec = &rt2x00dev->spec;
-       u8 *txpower;
+       struct channel_info *info;
+       char *tx_power;
        unsigned int i;
 
        /*
@@ -2126,21 +2127,11 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                                rt2x00_eeprom_addr(rt2x00dev,
                                                   EEPROM_MAC_ADDR_0));
 
-       /*
-        * Convert tx_power array in eeprom.
-        */
-       txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
-       for (i = 0; i < 14; i++)
-               txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
-
        /*
         * Initialize hw_mode information.
         */
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-       spec->tx_power_a = NULL;
-       spec->tx_power_bg = txpower;
-       spec->tx_power_default = DEFAULT_TXPOWER;
 
        if (rt2x00_rf(&rt2x00dev->chip, RF2528)) {
                spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
@@ -2158,14 +2149,26 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                spec->channels = rf_vals_5225_2527;
        }
 
-       if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-           rt2x00_rf(&rt2x00dev->chip, RF5226)) {
-               txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
-               for (i = 0; i < 14; i++)
-                       txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
 
-               spec->tx_power_a = txpower;
+       spec->channels_info = info;
+
+       tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
+       for (i = 0; i < 14; i++)
+               info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+
+       if (spec->num_channels > 14) {
+               tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
+               for (i = 14; i < spec->num_channels; i++)
+                       info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
        }
+
+       return 0;
 }
 
 static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -2186,7 +2189,9 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize hw specifications.
         */
-       rt73usb_probe_hw_mode(rt2x00dev);
+       retval = rt73usb_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
 
        /*
         * This device requires firmware.
index 91e04d319d76fa195d036a5692f303a59495fb35..868386c457f65c39c4e15d11ef92cefbebb534a4 100644 (file)
@@ -1050,17 +1050,10 @@ struct hw_pairwise_ta_entry {
 #define MAX_TXPOWER    31
 #define DEFAULT_TXPOWER        24
 
-#define TXPOWER_FROM_DEV(__txpower)            \
-({                                             \
-       ((__txpower) > MAX_TXPOWER) ?           \
-               DEFAULT_TXPOWER : (__txpower);  \
-})
-
-#define TXPOWER_TO_DEV(__txpower)                      \
-({                                                     \
-       ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER :    \
-       (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER :   \
-       (__txpower));                                   \
-})
+#define TXPOWER_FROM_DEV(__txpower) \
+       (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
 
 #endif /* RT73USB_H */