Search Linux Wireless

Re: [PATCH wireless-next v11 1/3] wifi: cfg80211: Add Support to Set RTS Threshold for each Radio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 5/21/2025 10:33 PM, Roopni Devanathan wrote:
...
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index fd5f79266471..4e8507649d15 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -854,6 +854,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
>  	[NL80211_ATTR_MLO_RECONF_REM_LINKS] = { .type = NLA_U16 },
>  	[NL80211_ATTR_EPCS] = { .type = NLA_FLAG },
>  	[NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS] = { .type = NLA_U16 },
> +	[NL80211_ATTR_WIPHY_RADIO_INDEX] = { .type = NLA_U8 },
>  };
>  
>  /* policy for the key attributes */
> @@ -3608,6 +3609,33 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
>  	return __nl80211_set_channel(rdev, netdev, info, link_id);
>  }
>  
> +static int nl80211_set_wiphy_radio(struct genl_info *info,
> +				   struct cfg80211_registered_device *rdev,
> +				   int radio_id)

refer to prior comment about s/radio_id/radio_idx/g

> +{
> +	u32 rts_threshold = 0, old_rts, changed = 0;
> +	int result;
> +
> +	if (!rdev->ops->set_wiphy_params)
> +		return -EOPNOTSUPP;
> +
> +	if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
> +		rts_threshold = nla_get_u32(
> +				info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
> +		changed |= WIPHY_PARAM_RTS_THRESHOLD;
> +	}
> +
> +	old_rts = rdev->wiphy.radio_cfg[radio_id].rts_threshold;
> +
> +	rdev->wiphy.radio_cfg[radio_id].rts_threshold = rts_threshold;
> +
> +	result = rdev_set_wiphy_params(rdev, radio_id, changed);
> +	if (result)
> +		rdev->wiphy.radio_cfg[radio_id].rts_threshold = old_rts;
> +
> +	return 0;
> +}
> +
>  static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  {
>  	struct cfg80211_registered_device *rdev = NULL;
> @@ -3617,6 +3645,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  	struct nlattr *nl_txq_params;
>  	u32 changed;
>  	u8 retry_short = 0, retry_long = 0;
> +	int radio_id = -1;
>  	u32 frag_threshold = 0, rts_threshold = 0;
>  	u8 coverage_class = 0;
>  	u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
> @@ -3670,6 +3699,19 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  	if (result)
>  		return result;
>  
> +	if (info->attrs[NL80211_ATTR_WIPHY_RADIO_INDEX]) {
> +		/* Radio idx is not expected for non-multi radio wiphy */
> +		if (rdev->wiphy.n_radio <= 0)
> +			return -EINVAL;
> +
> +		radio_id = nla_get_u8(
> +				info->attrs[NL80211_ATTR_WIPHY_RADIO_INDEX]);
> +		if (radio_id >= rdev->wiphy.n_radio)
> +			return -EINVAL;
> +		else
> +			return nl80211_set_wiphy_radio(info, rdev, radio_id);

nit: no need for else after return, so the above two lines should be just:

		return nl80211_set_wiphy_radio(info, rdev, radio_id);

> +	}
> +
>  	if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
>  		struct ieee80211_txq_params txq_params;
>  		struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
> @@ -3879,16 +3921,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  	if (changed) {
>  		u8 old_retry_short, old_retry_long;
>  		u32 old_frag_threshold, old_rts_threshold;
> -		u8 old_coverage_class;
> +		u8 old_coverage_class, i;
>  		u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
> +		u32 *old_radio_rts_threshold;
>  
>  		if (!rdev->ops->set_wiphy_params)
>  			return -EOPNOTSUPP;
>  
> +		old_radio_rts_threshold = kcalloc(rdev->wiphy.n_radio,
> +						  sizeof(u32),
> +						  GFP_KERNEL);

can't n_radio be 0 for legacy drivers, and hence this will attempt to allocate
a zero-sized block of memory?

seems the allocation and references need to be guarded by:
		if (rdev->wiphy.n_radio)

> +		if (!old_radio_rts_threshold)
> +			return -ENOMEM;
> +
>  		old_retry_short = rdev->wiphy.retry_short;
>  		old_retry_long = rdev->wiphy.retry_long;
>  		old_frag_threshold = rdev->wiphy.frag_threshold;
>  		old_rts_threshold = rdev->wiphy.rts_threshold;
> +		for (i = 0 ; i < rdev->wiphy.n_radio; i++)
> +			old_radio_rts_threshold[i] =
> +				rdev->wiphy.radio_cfg[i].rts_threshold;
>  		old_coverage_class = rdev->wiphy.coverage_class;
>  		old_txq_limit = rdev->wiphy.txq_limit;
>  		old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
> @@ -3900,8 +3952,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  			rdev->wiphy.retry_long = retry_long;
>  		if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
>  			rdev->wiphy.frag_threshold = frag_threshold;
> -		if (changed & WIPHY_PARAM_RTS_THRESHOLD)
> +		if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
>  			rdev->wiphy.rts_threshold = rts_threshold;
> +			for (i = 0 ; i < rdev->wiphy.n_radio; i++)
> +				rdev->wiphy.radio_cfg[i].rts_threshold =
> +					rdev->wiphy.rts_threshold;
> +		}
>  		if (changed & WIPHY_PARAM_COVERAGE_CLASS)
>  			rdev->wiphy.coverage_class = coverage_class;
>  		if (changed & WIPHY_PARAM_TXQ_LIMIT)
> @@ -3911,18 +3967,23 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>  		if (changed & WIPHY_PARAM_TXQ_QUANTUM)
>  			rdev->wiphy.txq_quantum = txq_quantum;
>  
> -		result = rdev_set_wiphy_params(rdev, changed);
> +		result = rdev_set_wiphy_params(rdev, radio_id, changed);
>  		if (result) {
>  			rdev->wiphy.retry_short = old_retry_short;
>  			rdev->wiphy.retry_long = old_retry_long;
>  			rdev->wiphy.frag_threshold = old_frag_threshold;
>  			rdev->wiphy.rts_threshold = old_rts_threshold;
> +			for (i = 0 ; i < rdev->wiphy.n_radio; i++)
> +				rdev->wiphy.radio_cfg[i].rts_threshold =
> +					old_radio_rts_threshold[i];
>  			rdev->wiphy.coverage_class = old_coverage_class;
>  			rdev->wiphy.txq_limit = old_txq_limit;
>  			rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
>  			rdev->wiphy.txq_quantum = old_txq_quantum;
> -			return result;
>  		}
> +
> +		kfree(old_radio_rts_threshold);
> +		return result;
>  	}
>  
>  	return 0;




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux