Search Linux Wireless

Re: [PATCH 1/3] d80211: Split antenna selection into TX and RX antenna

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

 



On Wed, 2007-02-21 at 17:02 +0100, Ivo van Doorn wrote:
> Currently d80211 only uses a single variable for antenna selection,
> some devices (rt2x00) can configure the TX and RX antenna
> seperately from eachother.
> Assuming that antenna_sel is only for tx, and rx is "the other antenna"
> is flawed and does hinder possible switching of RX antenna based
> on RSSI results. And configuring the wrong antenna also impacts
> transfer rates and link quality.
> 
> This patch will remove the usage of the IOCTL call:
> PRISM2_PARAM_ANTENNA_SEL but will restore the usage of
> (the already excisting) IOCTL calls PRISM2_PARAM_ANTSEL_TX and
> PRISM2_PARAM_ANTSEL_RX.

We should make sure that antenna selection is something that cfg80211
can do easily as well, so that we can deprecate the PRISM2_IOCTL calls.

Dan


> Signed-off-by: Ivo van Doorn <IvDoorn@xxxxxxxxx>
> 
> ---
> 
> diff --git a/include/net/d80211.h b/include/net/d80211.h
> index 551fe46..68c8c8a 100644
> --- a/include/net/d80211.h
> +++ b/include/net/d80211.h
> @@ -196,7 +196,8 @@ struct ieee80211_tx_control {
>  						* above */
>  	u8 retry_limit;		/* 1 = only first attempt, 2 = one retry, .. */
>  	u8 power_level;		/* per-packet transmit power level, in dBm */
> -	u8 antenna_sel; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
> +	u8 antenna_sel_tx; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
> +	u8 antenna_sel_rx; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
>  	s8 key_idx;		/* -1 = do not encrypt, >= 0 keyidx from
>  				 * hw->set_key() */
>  	u8 icv_len;		/* length of the ICV/MIC field in octets */
> @@ -285,10 +286,9 @@ struct ieee80211_conf {
>          u8 antenna_max;			/* maximum antenna gain */
>  	short tx_power_reduction; /* in 0.1 dBm */
>  
> -	int antenna_sel;		/* default antenna conf:
> -					 *	0 = default/diversity,
> -			  		 *	1 = Ant0,
> -					 *	2 = Ant1 */
> +	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
> +	u8 antenna_sel_tx;
> +	u8 antenna_sel_rx;
>  
>          int antenna_def;
>          int antenna_mode;
> diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
> index 273cba1..53c47db 100644
> --- a/net/d80211/ieee80211.c
> +++ b/net/d80211/ieee80211.c
> @@ -1075,9 +1075,12 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
>  		control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
>  		tx->sta->clear_dst_mask = 0;
>  	}
> -	control->antenna_sel = local->hw.conf.antenna_sel;
> -	if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
> -		control->antenna_sel = tx->sta->antenna_sel;
> +	control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
> +	control->antenna_sel_rx = local->hw.conf.antenna_sel_rx;
> +	if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta) {
> +		control->antenna_sel_tx = tx->sta->antenna_sel_tx;
> +		control->antenna_sel_rx = tx->sta->antenna_sel_rx;
> +	}
>  	hdrlen = ieee80211_get_hdrlen(tx->fc);
>  	if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
>  		u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
> @@ -1788,7 +1791,8 @@ struct sk_buff * ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
>  		control->tx_rate = (local->short_preamble &&
>  				    (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
>  			rate->val2 : rate->val;
> -		control->antenna_sel = local->hw.conf.antenna_sel;
> +		control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
> +		control->antenna_sel_rx = local->hw.conf.antenna_sel_rx;
>  		control->power_level = local->hw.conf.power_level;
>  		control->flags |= IEEE80211_TXCTL_NO_ACK;
>  		control->retry_limit = 1;
> diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
> index cad4d54..20a200a 100644
> --- a/net/d80211/ieee80211_ioctl.c
> +++ b/net/d80211/ieee80211_ioctl.c
> @@ -2480,6 +2480,18 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
>  			       "for low-level driver\n", dev->name, value);
>  		break;
>  
> +	case PRISM2_PARAM_ANTSEL_TX:
> +		local->hw.conf.antenna_sel_tx = value;
> +		if (ieee80211_hw_config(local))
> +			ret = -EINVAL;
> +		break;
> +
> +	case PRISM2_PARAM_ANTSEL_RX:
> +		local->hw.conf.antenna_sel_rx = value;
> +		if (ieee80211_hw_config(local))
> +			ret = -EINVAL;
> +		break;
> +
>  	case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
>  		local->cts_protect_erp_frames = value;
>  		break;
> @@ -2532,12 +2544,6 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
>  		ret = ieee80211_ioctl_set_radio_enabled(dev, value);
>  		break;
>  
> -	case PRISM2_PARAM_ANTENNA_SEL:
> -		local->hw.conf.antenna_sel = value;
> -		if (ieee80211_hw_config(local))
> -			ret = -EINVAL;
> -		break;
> -
>  	case PRISM2_PARAM_ANTENNA_MODE:
>  		local->hw.conf.antenna_mode = value;
>  		if (ieee80211_hw_config(local))
> @@ -2712,6 +2718,14 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
>  		*param = sdata->ieee802_1x;
>  		break;
>  
> +	case PRISM2_PARAM_ANTSEL_TX:
> +		*param = local->hw.conf.antenna_sel_tx;
> +		break;
> +
> +	case PRISM2_PARAM_ANTSEL_RX:
> +		*param = local->hw.conf.antenna_sel_rx;
> +		break;
> +
>  	case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:
>  		*param = local->cts_protect_erp_frames;
>  		break;
> @@ -2735,10 +2749,6 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
>  		*param = local->next_mode;
>  		break;
>  
> -	case PRISM2_PARAM_ANTENNA_SEL:
> -		*param = local->hw.conf.antenna_sel;
> -		break;
> -
>  	case PRISM2_PARAM_ANTENNA_MODE:
>  		*param = local->hw.conf.antenna_mode;
>  		break;
> diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
> index f5dd80f..1442afb 100644
> --- a/net/d80211/ieee80211_sta.c
> +++ b/net/d80211/ieee80211_sta.c
> @@ -2220,7 +2220,8 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
>  		control.tx_rate = (local->short_preamble &&
>  				   (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
>  			rate->val2 : rate->val;
> -		control.antenna_sel = local->hw.conf.antenna_sel;
> +		control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
> +		control.antenna_sel_rx = local->hw.conf.antenna_sel_rx;
>  		control.power_level = local->hw.conf.power_level;
>  		control.flags |= IEEE80211_TXCTL_NO_ACK;
>  		control.retry_limit = 1;
> diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
> index b9d0973..4c44c73 100644
> --- a/net/d80211/ieee80211_sysfs.c
> +++ b/net/d80211/ieee80211_sysfs.c
> @@ -153,7 +153,8 @@ static ssize_t ieee80211_local_show_##name(struct class_device *cd,	\
>  IEEE80211_LOCAL_SHOW(channel, hw.conf.channel, "%d");
>  IEEE80211_LOCAL_SHOW(frequency, hw.conf.freq, "%d");
>  IEEE80211_LOCAL_SHOW(radar_detect, hw.conf.radar_detect, "%d");
> -IEEE80211_LOCAL_SHOW(antenna_sel, hw.conf.antenna_sel, "%d");
> +IEEE80211_LOCAL_SHOW(antenna_sel_tx, hw.conf.antenna_sel_tx, "%d");
> +IEEE80211_LOCAL_SHOW(antenna_sel_rx, hw.conf.antenna_sel_rx, "%d");
>  IEEE80211_LOCAL_SHOW(bridge_packets, bridge_packets, "%d");
>  IEEE80211_LOCAL_SHOW(key_tx_rx_threshold, key_tx_rx_threshold, "%d");
>  IEEE80211_LOCAL_SHOW(rts_threshold, rts_threshold, "%d");
> @@ -216,7 +217,8 @@ static struct class_device_attribute ieee80211_class_dev_attrs[] = {
>  	__ATTR(channel, S_IRUGO, ieee80211_local_show_channel, NULL),
>  	__ATTR(frequency, S_IRUGO, ieee80211_local_show_frequency, NULL),
>  	__ATTR(radar_detect, S_IRUGO, ieee80211_local_show_radar_detect, NULL),
> -	__ATTR(antenna_sel, S_IRUGO, ieee80211_local_show_antenna_sel, NULL),
> +	__ATTR(antenna_sel_tx, S_IRUGO, ieee80211_local_show_antenna_sel_tx, NULL),
> +	__ATTR(antenna_sel_rx, S_IRUGO, ieee80211_local_show_antenna_sel_rx, NULL),
>  	__ATTR(bridge_packets, S_IRUGO, ieee80211_local_show_bridge_packets, NULL),
>  	__ATTR(key_tx_rx_threshold, S_IRUGO, ieee80211_local_show_key_tx_rx_threshold, NULL),
>  	__ATTR(rts_threshold, S_IRUGO, ieee80211_local_show_rts_threshold, NULL),
> diff --git a/net/d80211/rc80211_simple.c b/net/d80211/rc80211_simple.c
> index 3634d00..91468b2 100644
> --- a/net/d80211/rc80211_simple.c
> +++ b/net/d80211/rc80211_simple.c
> @@ -137,13 +137,14 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
>  	srctrl = sta->rate_ctrl_priv;
>  	srctrl->tx_num_xmit++;
>  	if (status->excessive_retries) {
> -		sta->antenna_sel = sta->antenna_sel == 1 ? 2 : 1;
> +		sta->antenna_sel_tx = sta->antenna_sel_tx == 1 ? 2 : 1;
> +		sta->antenna_sel_rx = sta->antenna_sel_rx == 1 ? 2 : 1;
>  		if (local->sta_antenna_sel == STA_ANTENNA_SEL_SW_CTRL_DEBUG) {
>  			printk(KERN_DEBUG "%s: " MAC_FMT " TX antenna --> %d "
> -			       "(@%lu)\n",
> +			       "RX antenna --> %d (@%lu)\n",
>  			       dev->name, MAC_ARG(hdr->addr1),
> -			       sta->antenna_sel, jiffies);
> -		}
> +			       sta->antenna_sel_tx, sta->antenna_sel_rx, jiffies);
> + 		}
>  		srctrl->tx_num_failures++;
>  		sta->tx_retry_failed++;
>  		sta->tx_num_consecutive_failures++;
> diff --git a/net/d80211/sta_info.h b/net/d80211/sta_info.h
> index ad000a2..4622902 100644
> --- a/net/d80211/sta_info.h
> +++ b/net/d80211/sta_info.h
> @@ -89,7 +89,8 @@ struct sta_info {
>          int channel_use;
>          int channel_use_raw;
>  
> -	int antenna_sel;
> +	int antenna_sel_tx;
> +	int antenna_sel_rx;
>  
> 
>  	int key_idx_compression; /* key table index for compression and TX
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux