struct hw_mode_spec stores channel information that is allocated by the
individual rt2x00 drivers during hardware probing.  The channel info
array has the same lifetime as the hardware mode specification, but it
is currently allocated separately and then freed through a separate
pointer.

Make struct rt2x00_dev hold a pointer to the hardware mode
specification, store the channel info as a flexible array member, and
allocate both pieces together with kzalloc_flex().

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <[email protected]>
---
 .../net/wireless/ralink/rt2x00/rt2400pci.c    | 24 +++---
 .../net/wireless/ralink/rt2x00/rt2500pci.c    | 55 ++++++++------
 .../net/wireless/ralink/rt2x00/rt2500usb.c    | 55 ++++++++------
 .../net/wireless/ralink/rt2x00/rt2800lib.c    | 74 ++++++++++---------
 drivers/net/wireless/ralink/rt2x00/rt2x00.h   |  4 +-
 .../net/wireless/ralink/rt2x00/rt2x00config.c | 12 +--
 .../net/wireless/ralink/rt2x00/rt2x00dev.c    |  4 +-
 drivers/net/wireless/ralink/rt2x00/rt61pci.c  | 42 ++++++-----
 drivers/net/wireless/ralink/rt2x00/rt73usb.c  | 50 +++++++------
 9 files changed, 177 insertions(+), 143 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c 
b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
index cac191304bf5..3fb74dcbee63 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
@@ -1559,7 +1559,7 @@ static const struct rf_channel rf_vals_b[] = {
 
 static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        u8 *tx_power;
        unsigned int i;
@@ -1580,27 +1580,25 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_bands = SUPPORT_BAND_2GHZ;
-       spec->supported_rates = SUPPORT_RATE_CCK;
+       spec = kzalloc_flex(*spec, channels_info, ARRAY_SIZE(rf_vals_b));
+       if (!spec)
+               return -ENOMEM;
 
        spec->num_channels = ARRAY_SIZE(rf_vals_b);
        spec->channels = rf_vals_b;
 
-       /*
-        * Create channel information array
-        */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
-               return -ENOMEM;
-
-       spec->channels_info = info;
+       spec->supported_bands = SUPPORT_BAND_2GHZ;
+       spec->supported_rates = SUPPORT_RATE_CCK;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
        for (i = 0; i < 14; i++) {
-               info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
-               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               info = &spec->channels_info[i];
+               info->max_power = TXPOWER_FROM_DEV(MAX_TXPOWER);
+               info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c 
b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
index fc35b60e422c..4c85f401c091 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
@@ -1854,7 +1854,10 @@ static const struct rf_channel rf_vals_5222[] = {
 
 static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       const struct rf_channel *channels;
+       unsigned int num_channels = 0;
+       unsigned int supported_bands;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        u8 *tx_power;
        unsigned int i;
@@ -1880,52 +1883,58 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_bands = SUPPORT_BAND_2GHZ;
-       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+       supported_bands = SUPPORT_BAND_2GHZ;
 
        if (rt2x00_rf(rt2x00dev, RF2522)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
-               spec->channels = rf_vals_bg_2522;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2522);
+               channels = rf_vals_bg_2522;
        } else if (rt2x00_rf(rt2x00dev, RF2523)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
-               spec->channels = rf_vals_bg_2523;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2523);
+               channels = rf_vals_bg_2523;
        } else if (rt2x00_rf(rt2x00dev, RF2524)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
-               spec->channels = rf_vals_bg_2524;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2524);
+               channels = rf_vals_bg_2524;
        } else if (rt2x00_rf(rt2x00dev, RF2525)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
-               spec->channels = rf_vals_bg_2525;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2525);
+               channels = rf_vals_bg_2525;
        } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
-               spec->channels = rf_vals_bg_2525e;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
+               channels = rf_vals_bg_2525e;
        } else if (rt2x00_rf(rt2x00dev, RF5222)) {
-               spec->supported_bands |= SUPPORT_BAND_5GHZ;
-               spec->num_channels = ARRAY_SIZE(rf_vals_5222);
-               spec->channels = rf_vals_5222;
+               supported_bands |= SUPPORT_BAND_5GHZ;
+               num_channels = ARRAY_SIZE(rf_vals_5222);
+               channels = rf_vals_5222;
        }
 
        /*
         * Create channel information array
         */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
+       spec = kzalloc_flex(*spec, channels_info, num_channels);
+       if (!spec)
                return -ENOMEM;
 
-       spec->channels_info = info;
+       spec->num_channels = num_channels;
+       spec->channels = channels;
+       spec->supported_bands = supported_bands;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
        for (i = 0; i < 14; i++) {
-               info[i].max_power = MAX_TXPOWER;
-               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               info = &spec->channels_info[i];
+               info->max_power = MAX_TXPOWER;
+               info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
        }
 
        if (spec->num_channels > 14) {
                for (i = 14; i < spec->num_channels; i++) {
-                       info[i].max_power = MAX_TXPOWER;
-                       info[i].default_power1 = DEFAULT_TXPOWER;
+                       info = &spec->channels_info[i];
+                       info->max_power = MAX_TXPOWER;
+                       info->default_power1 = DEFAULT_TXPOWER;
                }
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c 
b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
index 58728df6666c..cbc1c1399cc6 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
@@ -1661,7 +1661,10 @@ static const struct rf_channel rf_vals_5222[] = {
 
 static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       const struct rf_channel *channels;
+       unsigned int num_channels = 0;
+       unsigned int supported_bands;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        u8 *tx_power;
        unsigned int i;
@@ -1693,52 +1696,58 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_bands = SUPPORT_BAND_2GHZ;
-       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+       supported_bands = SUPPORT_BAND_2GHZ;
 
        if (rt2x00_rf(rt2x00dev, RF2522)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
-               spec->channels = rf_vals_bg_2522;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2522);
+               channels = rf_vals_bg_2522;
        } else if (rt2x00_rf(rt2x00dev, RF2523)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523);
-               spec->channels = rf_vals_bg_2523;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2523);
+               channels = rf_vals_bg_2523;
        } else if (rt2x00_rf(rt2x00dev, RF2524)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524);
-               spec->channels = rf_vals_bg_2524;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2524);
+               channels = rf_vals_bg_2524;
        } else if (rt2x00_rf(rt2x00dev, RF2525)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525);
-               spec->channels = rf_vals_bg_2525;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2525);
+               channels = rf_vals_bg_2525;
        } else if (rt2x00_rf(rt2x00dev, RF2525E)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
-               spec->channels = rf_vals_bg_2525e;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
+               channels = rf_vals_bg_2525e;
        } else if (rt2x00_rf(rt2x00dev, RF5222)) {
-               spec->supported_bands |= SUPPORT_BAND_5GHZ;
-               spec->num_channels = ARRAY_SIZE(rf_vals_5222);
-               spec->channels = rf_vals_5222;
+               supported_bands |= SUPPORT_BAND_5GHZ;
+               num_channels = ARRAY_SIZE(rf_vals_5222);
+               channels = rf_vals_5222;
        }
 
        /*
         * Create channel information array
         */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
+       spec = kzalloc_flex(*spec, channels_info, num_channels);
+       if (!spec)
                return -ENOMEM;
 
-       spec->channels_info = info;
+       spec->num_channels = num_channels;
+       spec->channels = channels;
+       spec->supported_bands = supported_bands;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
        for (i = 0; i < 14; i++) {
-               info[i].max_power = MAX_TXPOWER;
-               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               info = &spec->channels_info[i];
+               info->max_power = MAX_TXPOWER;
+               info->default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
        }
 
        if (spec->num_channels > 14) {
                for (i = 14; i < spec->num_channels; i++) {
-                       info[i].max_power = MAX_TXPOWER;
-                       info[i].default_power1 = DEFAULT_TXPOWER;
+                       info = &spec->channels_info[i];
+                       info->max_power = MAX_TXPOWER;
+                       info->default_power1 = DEFAULT_TXPOWER;
                }
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 97290899674e..7b7f6dcc9247 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -11778,7 +11778,9 @@ static const struct rf_channel rf_vals_7620[] = {
 
 static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       const struct rf_channel *channels;
+       unsigned int num_channels = 0;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        s8 *default_power1;
        s8 *default_power2;
@@ -11840,19 +11842,17 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
-
        switch (rt2x00dev->chip.rf) {
        case RF2720:
        case RF2820:
-               spec->num_channels = 14;
-               spec->channels = rf_vals;
+               num_channels = 14;
+               channels = rf_vals;
                break;
 
        case RF2750:
        case RF2850:
-               spec->num_channels = ARRAY_SIZE(rf_vals);
-               spec->channels = rf_vals;
+               num_channels = ARRAY_SIZE(rf_vals);
+               channels = rf_vals;
                break;
 
        case RF2020:
@@ -11870,44 +11870,52 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        case RF5372:
        case RF5390:
        case RF5392:
-               spec->num_channels = 14;
+               num_channels = 14;
                if (rt2800_clk_is_20mhz(rt2x00dev))
-                       spec->channels = rf_vals_3x_xtal20;
+                       channels = rf_vals_3x_xtal20;
                else
-                       spec->channels = rf_vals_3x;
+                       channels = rf_vals_3x;
                break;
 
        case RF7620:
-               spec->num_channels = ARRAY_SIZE(rf_vals_7620);
-               spec->channels = rf_vals_7620;
+               num_channels = ARRAY_SIZE(rf_vals_7620);
+               channels = rf_vals_7620;
                break;
 
        case RF3052:
        case RF3053:
-               spec->num_channels = ARRAY_SIZE(rf_vals_3x);
-               spec->channels = rf_vals_3x;
+               num_channels = ARRAY_SIZE(rf_vals_3x);
+               channels = rf_vals_3x;
                break;
 
        case RF3853:
-               spec->num_channels = ARRAY_SIZE(rf_vals_3853);
-               spec->channels = rf_vals_3853;
+               num_channels = ARRAY_SIZE(rf_vals_3853);
+               channels = rf_vals_3853;
                break;
 
        case RF5592:
                reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX);
                if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
-                       spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40);
-                       spec->channels = rf_vals_5592_xtal40;
+                       num_channels = ARRAY_SIZE(rf_vals_5592_xtal40);
+                       channels = rf_vals_5592_xtal40;
                } else {
-                       spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20);
-                       spec->channels = rf_vals_5592_xtal20;
+                       num_channels = ARRAY_SIZE(rf_vals_5592_xtal20);
+                       channels = rf_vals_5592_xtal20;
                }
                break;
        }
 
-       if (WARN_ON_ONCE(!spec->channels))
+       if (WARN_ON_ONCE(!channels))
                return -ENODEV;
 
+       spec = kzalloc_flex(*spec, channels_info, num_channels);
+       if (!spec)
+               return -ENOMEM;
+
+       spec->num_channels = num_channels;
+       spec->channels = channels;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
        spec->supported_bands = SUPPORT_BAND_2GHZ;
        if (spec->num_channels > 14)
                spec->supported_bands |= SUPPORT_BAND_5GHZ;
@@ -11959,19 +11967,13 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Create channel information and survey arrays
         */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
-               return -ENOMEM;
-
        rt2x00dev->chan_survey =
                kzalloc_objs(struct rt2x00_chan_survey, spec->num_channels);
        if (!rt2x00dev->chan_survey) {
-               kfree(info);
+               kfree(spec);
                return -ENOMEM;
        }
 
-       spec->channels_info = info;
-
        default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
        default_power2 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
 
@@ -11982,10 +11984,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
                default_power3 = NULL;
 
        for (i = 0; i < 14; i++) {
-               info[i].default_power1 = default_power1[i];
-               info[i].default_power2 = default_power2[i];
+               info = &spec->channels_info[i];
+               info->default_power1 = default_power1[i];
+               info->default_power2 = default_power2[i];
                if (default_power3)
-                       info[i].default_power3 = default_power3[i];
+                       info->default_power3 = default_power3[i];
        }
 
        if (spec->num_channels > 14) {
@@ -12002,10 +12005,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
                        default_power3 = NULL;
 
                for (i = 14; i < spec->num_channels; i++) {
-                       info[i].default_power1 = default_power1[i - 14];
-                       info[i].default_power2 = default_power2[i - 14];
+                       info = &spec->channels_info[i];
+                       info->default_power1 = default_power1[i - 14];
+                       info->default_power2 = default_power2[i - 14];
                        if (default_power3)
-                               info[i].default_power3 = default_power3[i - 14];
+                               info->default_power3 = default_power3[i - 14];
                }
        }
 
@@ -12033,6 +12037,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
                break;
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h 
b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index 7d313e86d3f2..babc04210a65 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -404,9 +404,9 @@ struct hw_mode_spec {
 
        unsigned int num_channels;
        const struct rf_channel *channels;
-       const struct channel_info *channels_info;
 
        struct ieee80211_sta_ht_cap ht;
+       struct channel_info channels_info[] __counted_by(num_channels);
 };
 
 /*
@@ -802,7 +802,7 @@ struct rt2x00_dev {
        /*
         * hw capability specifications.
         */
-       struct hw_mode_spec spec;
+       struct hw_mode_spec *spec;
 
        /*
         * This is the default TX/RX antenna setup as indicated
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c 
b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
index f895f560a185..b97cb67c4361 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
@@ -165,7 +165,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
                                   struct ieee80211_conf *conf)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       struct hw_mode_spec *spec = rt2x00dev->spec;
        int center_channel;
        u16 i;
 
@@ -194,6 +194,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                      struct ieee80211_conf *conf,
                      unsigned int ieee80211_flags)
 {
+       struct hw_mode_spec *spec = rt2x00dev->spec;
        struct rt2x00lib_conf libconf;
        u16 hw_value;
        u16 autowake_timeout;
@@ -218,13 +219,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                        hw_value = conf->chandef.chan->hw_value;
                }
 
-               memcpy(&libconf.rf,
-                      &rt2x00dev->spec.channels[hw_value],
-                      sizeof(libconf.rf));
-
-               memcpy(&libconf.channel,
-                      &rt2x00dev->spec.channels_info[hw_value],
-                      sizeof(libconf.channel));
+               memcpy(&libconf.rf, &spec->channels[hw_value], 
sizeof(libconf.rf));
+               memcpy(&libconf.channel, &spec->channels_info[hw_value], 
sizeof(libconf.channel));
 
                /* Used for VCO periodic calibration */
                rt2x00dev->rf_channel = libconf.rf.channel;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c 
b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index edc1f8eac747..3ffbc8aabbae 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1097,7 +1097,7 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev 
*rt2x00dev)
                rt2x00dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
        }
 
-       kfree(rt2x00dev->spec.channels_info);
+       kfree(rt2x00dev->spec);
        kfree(rt2x00dev->chan_survey);
 }
 
@@ -1116,7 +1116,7 @@ static const struct ieee80211_tpt_blink 
rt2x00_tpt_blink[] = {
 
 static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       struct hw_mode_spec *spec = rt2x00dev->spec;
        int status;
 
        if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c 
b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
index 79e1fd0a1fbd..479825f8bba9 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
@@ -2654,7 +2654,10 @@ static const struct rf_channel rf_vals_seq[] = {
 
 static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       const struct rf_channel *channels;
+       unsigned int num_channels = 0;
+       unsigned int supported_bands;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        u8 *tx_power;
        unsigned int i;
@@ -2693,46 +2696,51 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_bands = SUPPORT_BAND_2GHZ;
-       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+       supported_bands = SUPPORT_BAND_2GHZ;
 
        if (!rt2x00_has_cap_rf_sequence(rt2x00dev)) {
-               spec->num_channels = 14;
-               spec->channels = rf_vals_noseq;
+               num_channels = 14;
+               channels = rf_vals_noseq;
        } else {
-               spec->num_channels = 14;
-               spec->channels = rf_vals_seq;
+               num_channels = 14;
+               channels = rf_vals_seq;
        }
 
        if (rt2x00_rf(rt2x00dev, RF5225) || rt2x00_rf(rt2x00dev, RF5325)) {
-               spec->supported_bands |= SUPPORT_BAND_5GHZ;
-               spec->num_channels = ARRAY_SIZE(rf_vals_seq);
+               supported_bands |= SUPPORT_BAND_5GHZ;
+               num_channels = ARRAY_SIZE(rf_vals_seq);
        }
 
        /*
         * Create channel information array
         */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
+       spec = kzalloc_flex(*spec, channels_info, num_channels);
+       if (!spec)
                return -ENOMEM;
 
-       spec->channels_info = info;
+       spec->num_channels = num_channels;
+       spec->channels = channels;
+       spec->supported_bands = supported_bands;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
        for (i = 0; i < 14; i++) {
-               info[i].max_power = MAX_TXPOWER;
-               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               info = &spec->channels_info[i];
+               info->max_power = MAX_TXPOWER;
+               info->default_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].max_power = MAX_TXPOWER;
-                       info[i].default_power1 =
-                                       TXPOWER_FROM_DEV(tx_power[i - 14]);
+                       info = &spec->channels_info[i];
+                       info->max_power = MAX_TXPOWER;
+                       info->default_power1 = TXPOWER_FROM_DEV(tx_power[i - 
14]);
                }
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c 
b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
index d6b7174d087a..17338378329b 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
@@ -2088,7 +2088,10 @@ static const struct rf_channel rf_vals_5225_2527[] = {
 
 static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
-       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       const struct rf_channel *channels;
+       unsigned int num_channels = 0;
+       unsigned int supported_bands;
+       struct hw_mode_spec *spec;
        struct channel_info *info;
        u8 *tx_power;
        unsigned int i;
@@ -2114,49 +2117,54 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev 
*rt2x00dev)
        /*
         * Initialize hw_mode information.
         */
-       spec->supported_bands = SUPPORT_BAND_2GHZ;
-       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+       supported_bands = SUPPORT_BAND_2GHZ;
 
        if (rt2x00_rf(rt2x00dev, RF2528)) {
-               spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
-               spec->channels = rf_vals_bg_2528;
+               num_channels = ARRAY_SIZE(rf_vals_bg_2528);
+               channels = rf_vals_bg_2528;
        } else if (rt2x00_rf(rt2x00dev, RF5226)) {
-               spec->supported_bands |= SUPPORT_BAND_5GHZ;
-               spec->num_channels = ARRAY_SIZE(rf_vals_5226);
-               spec->channels = rf_vals_5226;
+               supported_bands |= SUPPORT_BAND_5GHZ;
+               num_channels = ARRAY_SIZE(rf_vals_5226);
+               channels = rf_vals_5226;
        } else if (rt2x00_rf(rt2x00dev, RF2527)) {
-               spec->num_channels = 14;
-               spec->channels = rf_vals_5225_2527;
+               num_channels = 14;
+               channels = rf_vals_5225_2527;
        } else if (rt2x00_rf(rt2x00dev, RF5225)) {
-               spec->supported_bands |= SUPPORT_BAND_5GHZ;
-               spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
-               spec->channels = rf_vals_5225_2527;
+               supported_bands |= SUPPORT_BAND_5GHZ;
+               num_channels = ARRAY_SIZE(rf_vals_5225_2527);
+               channels = rf_vals_5225_2527;
        }
 
        /*
         * Create channel information array
         */
-       info = kzalloc_objs(*info, spec->num_channels);
-       if (!info)
+       spec = kzalloc_flex(*spec, channels_info, num_channels);
+       if (!spec)
                return -ENOMEM;
 
-       spec->channels_info = info;
+       spec->num_channels = num_channels;
+       spec->channels = channels;
+       spec->supported_bands = supported_bands;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
        tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
        for (i = 0; i < 14; i++) {
-               info[i].max_power = MAX_TXPOWER;
-               info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+               info = &spec->channels_info[i];
+               info->max_power = MAX_TXPOWER;
+               info->default_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].max_power = MAX_TXPOWER;
-                       info[i].default_power1 =
-                                       TXPOWER_FROM_DEV(tx_power[i - 14]);
+                       info = &spec->channels_info[i];
+                       info->max_power = MAX_TXPOWER;
+                       info->default_power1 = TXPOWER_FROM_DEV(tx_power[i - 
14]);
                }
        }
 
+       rt2x00dev->spec = spec;
+
        return 0;
 }
 
-- 
2.54.0


Reply via email to