cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rc.c (8227B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2012  Realtek Corporation.*/
      3
      4#include "wifi.h"
      5#include "base.h"
      6#include "rc.h"
      7
      8/*
      9 *Finds the highest rate index we can use
     10 *if skb is special data like DHCP/EAPOL, we set should
     11 *it to lowest rate CCK_1M, otherwise we set rate to
     12 *highest rate based on wireless mode used for iwconfig
     13 *show Tx rate.
     14 */
     15static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
     16				  struct ieee80211_sta *sta,
     17				  struct sk_buff *skb, bool not_data)
     18{
     19	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
     20	struct rtl_phy *rtlphy = &(rtlpriv->phy);
     21	struct rtl_sta_info *sta_entry = NULL;
     22	u16 wireless_mode = 0;
     23	u8 nss;
     24	struct ieee80211_tx_rate rate;
     25
     26	switch (get_rf_type(rtlphy)) {
     27	case RF_4T4R:
     28		nss = 4;
     29		break;
     30	case RF_3T3R:
     31		nss = 3;
     32		break;
     33	case RF_2T2R:
     34		nss = 2;
     35		break;
     36	default:
     37		nss = 1;
     38		break;
     39	}
     40
     41	/*
     42	 *this rate is no use for true rate, firmware
     43	 *will control rate at all it just used for
     44	 *1.show in iwconfig in B/G mode
     45	 *2.in rtl_get_tcb_desc when we check rate is
     46	 *      1M we will not use FW rate but user rate.
     47	 */
     48
     49	if (sta) {
     50		sta_entry = (struct rtl_sta_info *)sta->drv_priv;
     51		wireless_mode = sta_entry->wireless_mode;
     52	}
     53
     54	if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) ||
     55	    not_data) {
     56		return 0;
     57	} else {
     58		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
     59			if (wireless_mode == WIRELESS_MODE_B) {
     60				return B_MODE_MAX_RIX;
     61			} else if (wireless_mode == WIRELESS_MODE_G) {
     62				return G_MODE_MAX_RIX;
     63			} else if (wireless_mode == WIRELESS_MODE_N_24G) {
     64				if (nss == 1)
     65					return N_MODE_MCS7_RIX;
     66				else
     67					return N_MODE_MCS15_RIX;
     68			} else if (wireless_mode == WIRELESS_MODE_AC_24G) {
     69				if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) {
     70					ieee80211_rate_set_vht(&rate,
     71							       AC_MODE_MCS8_RIX,
     72							       nss);
     73					goto out;
     74				} else {
     75					ieee80211_rate_set_vht(&rate,
     76							       AC_MODE_MCS9_RIX,
     77							       nss);
     78					goto out;
     79				}
     80			}
     81			return 0;
     82		} else {
     83			if (wireless_mode == WIRELESS_MODE_A) {
     84				return A_MODE_MAX_RIX;
     85			} else if (wireless_mode == WIRELESS_MODE_N_5G) {
     86				if (nss == 1)
     87					return N_MODE_MCS7_RIX;
     88				else
     89					return N_MODE_MCS15_RIX;
     90			} else if (wireless_mode == WIRELESS_MODE_AC_5G) {
     91				if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20) {
     92					ieee80211_rate_set_vht(&rate,
     93							       AC_MODE_MCS8_RIX,
     94							       nss);
     95					goto out;
     96				} else {
     97					ieee80211_rate_set_vht(&rate,
     98							       AC_MODE_MCS9_RIX,
     99							       nss);
    100					goto out;
    101				}
    102			}
    103			return 0;
    104		}
    105	}
    106
    107out:
    108	return rate.idx;
    109}
    110
    111static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
    112				    struct ieee80211_sta *sta,
    113				    struct ieee80211_tx_rate *rate,
    114				    struct ieee80211_tx_rate_control *txrc,
    115				    u8 tries, s8 rix, int rtsctsenable,
    116				    bool not_data)
    117{
    118	struct rtl_mac *mac = rtl_mac(rtlpriv);
    119	struct rtl_sta_info *sta_entry = NULL;
    120	u16 wireless_mode = 0;
    121	u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0;
    122
    123	if (sta) {
    124		sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
    125		sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
    126		sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80;
    127		sta_entry = (struct rtl_sta_info *)sta->drv_priv;
    128		wireless_mode = sta_entry->wireless_mode;
    129	}
    130	rate->count = tries;
    131	rate->idx = rix >= 0x00 ? rix : 0x00;
    132
    133	if (!not_data) {
    134		if (txrc->short_preamble)
    135			rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
    136		if (mac->opmode == NL80211_IFTYPE_AP ||
    137			mac->opmode == NL80211_IFTYPE_ADHOC) {
    138			if (sta && (sta->deflink.ht_cap.cap &
    139				    IEEE80211_HT_CAP_SUP_WIDTH_20_40))
    140				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
    141			if (sta && sta->deflink.vht_cap.vht_supported)
    142				rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
    143		} else {
    144			if (mac->bw_80)
    145				rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
    146			else if (mac->bw_40)
    147				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
    148		}
    149
    150		if (sgi_20 || sgi_40 || sgi_80)
    151			rate->flags |= IEEE80211_TX_RC_SHORT_GI;
    152		if (sta && sta->deflink.ht_cap.ht_supported &&
    153		    (wireless_mode == WIRELESS_MODE_N_5G ||
    154		     wireless_mode == WIRELESS_MODE_N_24G))
    155			rate->flags |= IEEE80211_TX_RC_MCS;
    156		if (sta && sta->deflink.vht_cap.vht_supported &&
    157		    (wireless_mode == WIRELESS_MODE_AC_5G ||
    158		     wireless_mode == WIRELESS_MODE_AC_24G ||
    159		     wireless_mode == WIRELESS_MODE_AC_ONLY))
    160			rate->flags |= IEEE80211_TX_RC_VHT_MCS;
    161	}
    162}
    163
    164static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
    165			 void *priv_sta,
    166			 struct ieee80211_tx_rate_control *txrc)
    167{
    168	struct rtl_priv *rtlpriv = ppriv;
    169	struct sk_buff *skb = txrc->skb;
    170	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
    171	struct ieee80211_tx_rate *rates = tx_info->control.rates;
    172	__le16 fc = rtl_get_fc(skb);
    173	u8 try_per_rate, i, rix;
    174	bool not_data = !ieee80211_is_data(fc);
    175
    176	rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
    177	try_per_rate = 1;
    178	_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
    179				try_per_rate, rix, 1, not_data);
    180
    181	if (!not_data) {
    182		for (i = 1; i < 4; i++)
    183			_rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
    184						txrc, i, (rix - i), 1,
    185						not_data);
    186	}
    187}
    188
    189static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
    190			       struct rtl_sta_info *sta_entry, u16 tid)
    191{
    192	struct rtl_mac *mac = rtl_mac(rtlpriv);
    193
    194	if (mac->act_scanning)
    195		return false;
    196
    197	if (mac->opmode == NL80211_IFTYPE_STATION &&
    198	    mac->cnt_after_linked < 3)
    199		return false;
    200
    201	if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
    202		return true;
    203
    204	return false;
    205}
    206
    207/*mac80211 Rate Control callbacks*/
    208static void rtl_tx_status(void *ppriv,
    209			  struct ieee80211_supported_band *sband,
    210			  struct ieee80211_sta *sta, void *priv_sta,
    211			  struct sk_buff *skb)
    212{
    213	struct rtl_priv *rtlpriv = ppriv;
    214	struct rtl_mac *mac = rtl_mac(rtlpriv);
    215	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
    216	__le16 fc = rtl_get_fc(skb);
    217	struct rtl_sta_info *sta_entry;
    218
    219	if (!priv_sta || !ieee80211_is_data(fc))
    220		return;
    221
    222	if (rtl_is_special_data(mac->hw, skb, true, true))
    223		return;
    224
    225	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
    226	    is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
    227		return;
    228
    229	if (sta) {
    230		/* Check if aggregation has to be enabled for this tid */
    231		sta_entry = (struct rtl_sta_info *)sta->drv_priv;
    232		if (sta->deflink.ht_cap.ht_supported &&
    233		    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
    234			if (ieee80211_is_data_qos(fc)) {
    235				u8 tid = rtl_get_tid(skb);
    236
    237				if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
    238						       tid)) {
    239					sta_entry->tids[tid].agg.agg_state =
    240						RTL_AGG_PROGRESS;
    241					ieee80211_start_tx_ba_session(sta, tid,
    242								      5000);
    243				}
    244			}
    245		}
    246	}
    247}
    248
    249static void rtl_rate_init(void *ppriv,
    250			  struct ieee80211_supported_band *sband,
    251			  struct cfg80211_chan_def *chandef,
    252			  struct ieee80211_sta *sta, void *priv_sta)
    253{
    254}
    255
    256static void rtl_rate_update(void *ppriv,
    257			    struct ieee80211_supported_band *sband,
    258			    struct cfg80211_chan_def *chandef,
    259			    struct ieee80211_sta *sta, void *priv_sta,
    260			    u32 changed)
    261{
    262}
    263
    264static void *rtl_rate_alloc(struct ieee80211_hw *hw)
    265{
    266	struct rtl_priv *rtlpriv = rtl_priv(hw);
    267	return rtlpriv;
    268}
    269
    270static void rtl_rate_free(void *rtlpriv)
    271{
    272	return;
    273}
    274
    275static void *rtl_rate_alloc_sta(void *ppriv,
    276				struct ieee80211_sta *sta, gfp_t gfp)
    277{
    278	struct rtl_priv *rtlpriv = ppriv;
    279	struct rtl_rate_priv *rate_priv;
    280
    281	rate_priv = kzalloc(sizeof(*rate_priv), gfp);
    282	if (!rate_priv)
    283		return NULL;
    284
    285	rtlpriv->rate_priv = rate_priv;
    286
    287	return rate_priv;
    288}
    289
    290static void rtl_rate_free_sta(void *rtlpriv,
    291			      struct ieee80211_sta *sta, void *priv_sta)
    292{
    293	struct rtl_rate_priv *rate_priv = priv_sta;
    294
    295	kfree(rate_priv);
    296}
    297
    298static const struct rate_control_ops rtl_rate_ops = {
    299	.name = "rtl_rc",
    300	.alloc = rtl_rate_alloc,
    301	.free = rtl_rate_free,
    302	.alloc_sta = rtl_rate_alloc_sta,
    303	.free_sta = rtl_rate_free_sta,
    304	.rate_init = rtl_rate_init,
    305	.rate_update = rtl_rate_update,
    306	.tx_status = rtl_tx_status,
    307	.get_rate = rtl_get_rate,
    308};
    309
    310int rtl_rate_control_register(void)
    311{
    312	return ieee80211_rate_control_register(&rtl_rate_ops);
    313}
    314
    315void rtl_rate_control_unregister(void)
    316{
    317	ieee80211_rate_control_unregister(&rtl_rate_ops);
    318}