The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Stanislaw Gruszka <stf_xl@wp.pl>
To: Rosen Penev <rosenp@gmail.com>
Cc: linux-wireless@vger.kernel.org, Kees Cook <kees@kernel.org>,
	"Gustavo A. R. Silva" <gustavoars@kernel.org>,
	open list <linux-kernel@vger.kernel.org>,
	"open list:KERNEL HARDENING (not covered by other
	areas):Keyword:b__counted_by(_le|_be|_ptr)?b"
	<linux-hardening@vger.kernel.org>
Subject: Re: [PATCH wireless-next] wifi: rt2x00: Use flexible array for hw_mode_spec channels
Date: Thu, 23 Jul 2026 09:53:04 +0200	[thread overview]
Message-ID: <20260723075304.GA4577@wp.pl> (raw)
In-Reply-To: <20260629033156.2363850-1-rosenp@gmail.com>

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 <rosenp@gmail.com>
> ---
>  .../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	other threads:[~2026-07-23  7:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-29  3:31 [PATCH wireless-next] wifi: rt2x00: Use flexible array for hw_mode_spec channels Rosen Penev
2026-07-23  7:53 ` Stanislaw Gruszka [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260723075304.GA4577@wp.pl \
    --to=stf_xl@wp.pl \
    --cc=gustavoars@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=rosenp@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox