Search Linux Wireless

Re: [PATCH v2 5/5] wifi: rtl8xxxu: Add rate control code for RTL8188EU

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

 



On Tue, 2022-12-13 at 19:33 +0200, Bitterblue Smith wrote:
> Copied from the newer vendor driver, v5.2.2.4.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
> v2:
>  - Implement suggestions from Ping-Ke Shih:
>    - Add missing break in two switch statements.
>    - Remove unnecessary initialisation of idx in rtl8188e_set_tx_rpt_timing().
> ---
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  |  39 ++
>  .../realtek/rtl8xxxu/rtl8xxxu_8188e.c         | 601 +++++++++++++++++-
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 131 +++-
>  3 files changed, 741 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index 29f5dbee16b0..be9479f969b7 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> 

[...]

> +
> +static void rtl8188e_power_training_try_state(struct rtl8xxxu_ra_info *ra)
> +{
> +	ra->pt_try_state = 0;
> +	switch (ra->pt_mode_ss) {
> +	case 3:
> +		if (ra->decision_rate >= DESC_RATE_MCS13)
> +			ra->pt_try_state = 1;
> +		break;
> +	case 2:
> +		if (ra->decision_rate >= DESC_RATE_MCS5)
> +			ra->pt_try_state = 1;
> +		break;
> +	case 1:
> +		if (ra->decision_rate >= DESC_RATE_48M)
> +			ra->pt_try_state = 1;
> +		break;
> +	case 0:
> +		if (ra->decision_rate >= DESC_RATE_11M)
> +			ra->pt_try_state = 1;
> +		break;
> +	default:
> +		ra->pt_try_state = 0;

It seems to be 0 already because of first statement of this function. 

> +		break;
> +	}
> +
> +	if (ra->rssi_sta_ra < 48) {
> +		ra->pt_stage = 0;
> +	} else if (ra->pt_try_state == 1) {
> +		if ((ra->pt_stop_count >= 10) ||
> +		    (ra->pt_pre_rssi > ra->rssi_sta_ra + 5) ||
> +		    (ra->pt_pre_rssi < ra->rssi_sta_ra - 5) ||
> +		    (ra->decision_rate != ra->pt_pre_rate)) {
> +			if (ra->pt_stage == 0)
> +				ra->pt_stage = 1;
> +			else if (ra->pt_stage == 1)
> +				ra->pt_stage = 3;
> +			else
> +				ra->pt_stage = 5;
> +
> +			ra->pt_pre_rssi = ra->rssi_sta_ra;
> +			ra->pt_stop_count = 0;
> +		} else {
> +			ra->ra_stage = 0;
> +			ra->pt_stop_count++;
> +		}
> +	} else {
> +		ra->pt_stage = 0;
> +		ra->ra_stage = 0;
> +	}
> +
> +	ra->pt_pre_rate = ra->decision_rate;
> +
> +	/* TODO: implement the "false alarm" statistics for this */
> +	/* Disable power training when noisy environment */
> +	/* if (p_dm_odm->is_disable_power_training) { */
> +	if (1) {
> +		ra->pt_stage = 0;
> +		ra->ra_stage = 0;
> +		ra->pt_stop_count = 0;
> +	}
> +}
> +
> +static void rtl8188e_power_training_decision(struct rtl8xxxu_ra_info *ra)
> +{
> +	u8 temp_stage;
> +	u32 numsc;
> +	u32 num_total;
> +	u8 stage_id;
> +	u8 j;
> +
> +	numsc = 0;
> +	num_total = ra->total * pt_penalty[5];
> +	for (j = 0; j <= 4; j++) {
> +		numsc += ra->retry[j] * pt_penalty[j];
> +
> +		if (numsc > num_total)
> +			break;
> +	}
> +
> +	j = j >> 1;

j >>= 1;

> +	temp_stage = (ra->pt_stage + 1) >> 1;
> +	if (temp_stage > j)
> +		stage_id = temp_stage - j;
> +	else
> +		stage_id = 0;
> +
> +	ra->pt_smooth_factor = (ra->pt_smooth_factor >> 1) +
> +			       (ra->pt_smooth_factor >> 2) +
> +			       stage_id * 16 + 2;
> +	if (ra->pt_smooth_factor > 192)
> +		ra->pt_smooth_factor = 192;
> +	stage_id = ra->pt_smooth_factor >> 6;
> +	temp_stage = stage_id * 2;
> +	if (temp_stage != 0)
> +		temp_stage--;
> +	if (ra->drop > 3)
> +		temp_stage = 0;
> +	ra->pt_stage = temp_stage;
> +}
> +
> +void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
> +{
> +	u32 *_rx_desc = (u32 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16));
> +	struct rtl8xxxu_rxdesc16 *rx_desc = (struct rtl8xxxu_rxdesc16 *)_rx_desc;
> +	struct device *dev = &priv->udev->dev;
> +	struct rtl8xxxu_ra_info *ra = &priv->ra_info;
> +

no blank line in declaration part.

> +	u32 tx_rpt_len = rx_desc->pktlen & 0x3ff;
> +	u32 items = tx_rpt_len / TX_RPT2_ITEM_SIZE;
> +	u64 macid_valid = ((u64)_rx_desc[5] << 32) | _rx_desc[4];
> +	u32 macid;
> +	u8 *rpt = skb->data;
> +	bool valid;
> +	u16 min_rpt_time = 0x927c;
> +
> +	dev_dbg(dev, "%s: len: %d items: %d\n", __func__, tx_rpt_len, items);
> +
> +	for (macid = 0; macid < items; macid++) {
> +		valid = false;
> +
> +		if (macid < 64)
> +			valid = macid_valid & BIT(macid);
> +
> +		if (valid) {
> +			ra->retry[0] = le16_to_cpu(*(__le16 *)rpt);
> +			ra->retry[1] = rpt[2];
> +			ra->retry[2] = rpt[3];
> +			ra->retry[3] = rpt[4];
> +			ra->retry[4] = rpt[5];
> +			ra->drop = rpt[6];
> +			ra->total = ra->retry[0] + ra->retry[1] + ra->retry[2] +
> +				    ra->retry[3] + ra->retry[4] + ra->drop;
> +
> +			if (ra->total > 0) {
> +				if (ra->ra_stage < 5)
> +					rtl8188e_rate_decision(ra);
> +				else if (ra->ra_stage == 5)
> +					rtl8188e_power_training_try_state(ra);
> +				else /* ra->ra_stage == 6 */
> +					rtl8188e_power_training_decision(ra);
> +
> +				if (ra->ra_stage <= 5)
> +					ra->ra_stage++;
> +				else
> +					ra->ra_stage = 0;
> +			}
> +		} else if (macid == 0) {
> +			dev_warn(dev, "%s: TX report item 0 not valid\n", __func__);
> +		}
> +
> +		dev_dbg(dev, "%s:  valid: %d retry: %d %d %d %d %d drop: %d\n",
> +			__func__, valid,
> +			ra->retry[0], ra->retry[1], ra->retry[2],
> +			ra->retry[3], ra->retry[4], ra->drop);
> +
> +		if (min_rpt_time > ra->rpt_time)
> +			min_rpt_time = ra->rpt_time;
> +
> +		rpt += TX_RPT2_ITEM_SIZE;
> +
> +		/*
> +		 * We only use macid 0, so only the first item is relevant.
> +		 * AP mode will use more of them if it's ever implemented.
> +		 */
> +		break;
> +	}
> +
> +	if (min_rpt_time != ra->pre_min_rpt_time) {
> +		rtl8xxxu_write16(priv, REG_TX_REPORT_TIME, min_rpt_time);
> +		ra->pre_min_rpt_time = min_rpt_time;
> +	}
> +}
> +

[...]

> +
>  int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
>  {
>  	struct ieee80211_hw *hw = priv->hw;
> @@ -5823,38 +5884,46 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff
> *skb)
>  
>  		skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16));
>  
> -		phy_stats = (struct rtl8723au_phy_stats *)skb->data;
> +		if (rx_desc->rpt_sel) {
> +			skb_queue_tail(&priv->c2hcmd_queue, skb);
> +			schedule_work(&priv->c2hcmd_work);
> +		} else {
> +			phy_stats = (struct rtl8723au_phy_stats *)skb->data;
>  
> -		skb_pull(skb, drvinfo_sz + desc_shift);
> +			skb_pull(skb, drvinfo_sz + desc_shift);
>  
> -		skb_trim(skb, pkt_len);
> +			skb_trim(skb, pkt_len);
>  
> -		if (rx_desc->phy_stats)
> -			rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
> -						   rx_desc->rxmcs, (struct ieee80211_hdr *)skb-
> >data,
> -						   rx_desc->crc32 || rx_desc->icverr);
> +			if (rx_desc->phy_stats)
> +				rtl8xxxu_rx_parse_phystats(
> +					priv, rx_status, phy_stats,
> +					rx_desc->rxmcs,
> +					(struct ieee80211_hdr *)skb->data,
> +					rx_desc->crc32 || rx_desc->icverr
> +				);

squash this parenthesis to previous line.

>  
> -		rx_status->mactime = rx_desc->tsfl;
> -		rx_status->flag |= RX_FLAG_MACTIME_START;
> +			rx_status->mactime = rx_desc->tsfl;
> +			rx_status->flag |= RX_FLAG_MACTIME_START;
>  
> -		if (!rx_desc->swdec)
> -			rx_status->flag |= RX_FLAG_DECRYPTED;
> -		if (rx_desc->crc32)
> -			rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
> -		if (rx_desc->bw)
> -			rx_status->bw = RATE_INFO_BW_40;
> +			if (!rx_desc->swdec)
> +				rx_status->flag |= RX_FLAG_DECRYPTED;
> +			if (rx_desc->crc32)
> +				rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
> +			if (rx_desc->bw)
> +				rx_status->bw = RATE_INFO_BW_40;
>  
> -		if (rx_desc->rxht) {
> -			rx_status->encoding = RX_ENC_HT;
> -			rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
> -		} else {
> -			rx_status->rate_idx = rx_desc->rxmcs;
> -		}
> +			if (rx_desc->rxht) {
> +				rx_status->encoding = RX_ENC_HT;
> +				rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
> +			} else {
> +				rx_status->rate_idx = rx_desc->rxmcs;
> +			}
>  
> -		rx_status->freq = hw->conf.chandef.chan->center_freq;
> -		rx_status->band = hw->conf.chandef.chan->band;
> +			rx_status->freq = hw->conf.chandef.chan->center_freq;
> +			rx_status->band = hw->conf.chandef.chan->band;
>  
> -		ieee80211_rx_irqsafe(hw, skb);
> +			ieee80211_rx_irqsafe(hw, skb);
> +		}
>  
>  		skb = next_skb;
>  		if (skb)
> 

[...]

Only some minor comments.

Thank you for the patches.
--
Ping-Ke





[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