Hi,

On Sun, Jun 28, 2026 at 08:31:56PM -0700, Rosen Penev wrote:
> 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(-)

This result in extra code. I do not see benefit of avoiding 
kzalloc calls at cost of adding more lines of code.

Regards
Stanislaw

> 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