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

cfp.c (14730B)


      1/*
      2 * NXP Wireless LAN device driver: Channel, Frequence and Power
      3 *
      4 * Copyright 2011-2020 NXP
      5 *
      6 * This software file (the "File") is distributed by NXP
      7 * under the terms of the GNU General Public License Version 2, June 1991
      8 * (the "License").  You may use, redistribute and/or modify this File in
      9 * accordance with the terms and conditions of the License, a copy of which
     10 * is available by writing to the Free Software Foundation, Inc.,
     11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
     12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
     13 *
     14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
     15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
     16 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
     17 * this warranty disclaimer.
     18 */
     19
     20#include "decl.h"
     21#include "ioctl.h"
     22#include "util.h"
     23#include "fw.h"
     24#include "main.h"
     25#include "cfg80211.h"
     26
     27/* 100mW */
     28#define MWIFIEX_TX_PWR_DEFAULT     20
     29/* 100mW */
     30#define MWIFIEX_TX_PWR_US_DEFAULT      20
     31/* 50mW */
     32#define MWIFIEX_TX_PWR_JP_DEFAULT      16
     33/* 100mW */
     34#define MWIFIEX_TX_PWR_FR_100MW        20
     35/* 10mW */
     36#define MWIFIEX_TX_PWR_FR_10MW         10
     37/* 100mW */
     38#define MWIFIEX_TX_PWR_EMEA_DEFAULT    20
     39
     40static u8 adhoc_rates_b[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 };
     41
     42static u8 adhoc_rates_g[G_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
     43					       0xb0, 0x48, 0x60, 0x6c, 0 };
     44
     45static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96,
     46						 0x0c, 0x12, 0x18, 0x24,
     47						 0x30, 0x48, 0x60, 0x6c, 0 };
     48
     49static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
     50					       0xb0, 0x48, 0x60, 0x6c, 0 };
     51static u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
     52					0xb0, 0x48, 0x60, 0x6c, 0 };
     53static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
     54					0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18,
     55					0x24, 0x30, 0x48, 0x60, 0x6C, 0x90,
     56					0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68,
     57					0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51,
     58					0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 };
     59
     60static u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
     61
     62static u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
     63					0x30, 0x48, 0x60, 0x6c, 0 };
     64
     65static u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
     66					0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
     67					0x60, 0x6c, 0 };
     68
     69u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x00, 0x10, 0x20, 0x30,
     70						0x31, 0x32, 0x40, 0x41, 0x50 };
     71
     72static u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
     73
     74/* For every mcs_rate line, the first 8 bytes are for stream 1x1,
     75 * and all 16 bytes are for stream 2x2.
     76 */
     77static const u16 mcs_rate[4][16] = {
     78	/* LGI 40M */
     79	{ 0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e,
     80	  0x36, 0x6c, 0xa2, 0xd8, 0x144, 0x1b0, 0x1e6, 0x21c },
     81
     82	/* SGI 40M */
     83	{ 0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c,
     84	  0x3c, 0x78, 0xb4, 0xf0, 0x168, 0x1e0, 0x21c, 0x258 },
     85
     86	/* LGI 20M */
     87	{ 0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82,
     88	  0x1a, 0x34, 0x4e, 0x68, 0x9c, 0xd0, 0xea, 0x104 },
     89
     90	/* SGI 20M */
     91	{ 0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90,
     92	  0x1c, 0x39, 0x56, 0x73, 0xad, 0xe7, 0x104, 0x120 }
     93};
     94
     95/* AC rates */
     96static const u16 ac_mcs_rate_nss1[8][10] = {
     97	/* LG 160M */
     98	{ 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
     99	  0x492, 0x57C, 0x618 },
    100
    101	/* SG 160M */
    102	{ 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
    103	  0x514, 0x618, 0x6C6 },
    104
    105	/* LG 80M */
    106	{ 0x3B, 0x75, 0xB0, 0xEA, 0x15F, 0x1D4, 0x20F,
    107	  0x249, 0x2BE, 0x30C },
    108
    109	/* SG 80M */
    110	{ 0x41, 0x82, 0xC3, 0x104, 0x186, 0x208, 0x249,
    111	  0x28A, 0x30C, 0x363 },
    112
    113	/* LG 40M */
    114	{ 0x1B, 0x36, 0x51, 0x6C, 0xA2, 0xD8, 0xF3,
    115	  0x10E, 0x144, 0x168 },
    116
    117	/* SG 40M */
    118	{ 0x1E, 0x3C, 0x5A, 0x78, 0xB4, 0xF0, 0x10E,
    119	  0x12C, 0x168, 0x190 },
    120
    121	/* LG 20M */
    122	{ 0xD, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75, 0x82, 0x9C, 0x00 },
    123
    124	/* SG 20M */
    125	{ 0xF, 0x1D, 0x2C, 0x3A, 0x57, 0x74, 0x82, 0x91, 0xAE, 0x00 },
    126};
    127
    128/* NSS2 note: the value in the table is 2 multiplier of the actual rate */
    129static const u16 ac_mcs_rate_nss2[8][10] = {
    130	/* LG 160M */
    131	{ 0xEA, 0x1D4, 0x2BE, 0x3A8, 0x57C, 0x750, 0x83A,
    132	  0x924, 0xAF8, 0xC30 },
    133
    134	/* SG 160M */
    135	{ 0x104, 0x208, 0x30C, 0x410, 0x618, 0x820, 0x924,
    136	  0xA28, 0xC30, 0xD8B },
    137
    138	/* LG 80M */
    139	{ 0x75, 0xEA, 0x15F, 0x1D4, 0x2BE, 0x3A8, 0x41D,
    140	  0x492, 0x57C, 0x618 },
    141
    142	/* SG 80M */
    143	{ 0x82, 0x104, 0x186, 0x208, 0x30C, 0x410, 0x492,
    144	  0x514, 0x618, 0x6C6 },
    145
    146	/* LG 40M */
    147	{ 0x36, 0x6C, 0xA2, 0xD8, 0x144, 0x1B0, 0x1E6,
    148	  0x21C, 0x288, 0x2D0 },
    149
    150	/* SG 40M */
    151	{ 0x3C, 0x78, 0xB4, 0xF0, 0x168, 0x1E0, 0x21C,
    152	  0x258, 0x2D0, 0x320 },
    153
    154	/* LG 20M */
    155	{ 0x1A, 0x34, 0x4A, 0x68, 0x9C, 0xD0, 0xEA, 0x104,
    156	  0x138, 0x00 },
    157
    158	/* SG 20M */
    159	{ 0x1D, 0x3A, 0x57, 0x74, 0xAE, 0xE6, 0x104, 0x121,
    160	  0x15B, 0x00 },
    161};
    162
    163struct region_code_mapping {
    164	u8 code;
    165	u8 region[IEEE80211_COUNTRY_STRING_LEN];
    166};
    167
    168static struct region_code_mapping region_code_mapping_t[] = {
    169	{ 0x10, "US " }, /* US FCC */
    170	{ 0x20, "CA " }, /* IC Canada */
    171	{ 0x30, "FR " }, /* France */
    172	{ 0x31, "ES " }, /* Spain */
    173	{ 0x32, "FR " }, /* France */
    174	{ 0x40, "JP " }, /* Japan */
    175	{ 0x41, "JP " }, /* Japan */
    176	{ 0x50, "CN " }, /* China */
    177};
    178
    179/* This function converts integer code to region string */
    180u8 *mwifiex_11d_code_2_region(u8 code)
    181{
    182	u8 i;
    183
    184	/* Look for code in mapping table */
    185	for (i = 0; i < ARRAY_SIZE(region_code_mapping_t); i++)
    186		if (region_code_mapping_t[i].code == code)
    187			return region_code_mapping_t[i].region;
    188
    189	return NULL;
    190}
    191
    192/*
    193 * This function maps an index in supported rates table into
    194 * the corresponding data rate.
    195 */
    196u32 mwifiex_index_to_acs_data_rate(struct mwifiex_private *priv,
    197				   u8 index, u8 ht_info)
    198{
    199	u32 rate = 0;
    200	u8 mcs_index = 0;
    201	u8 bw = 0;
    202	u8 gi = 0;
    203
    204	if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_VHT) {
    205		mcs_index = min(index & 0xF, 9);
    206
    207		/* 20M: bw=0, 40M: bw=1, 80M: bw=2, 160M: bw=3 */
    208		bw = (ht_info & 0xC) >> 2;
    209
    210		/* LGI: gi =0, SGI: gi = 1 */
    211		gi = (ht_info & 0x10) >> 4;
    212
    213		if ((index >> 4) == 1)	/* NSS = 2 */
    214			rate = ac_mcs_rate_nss2[2 * (3 - bw) + gi][mcs_index];
    215		else			/* NSS = 1 */
    216			rate = ac_mcs_rate_nss1[2 * (3 - bw) + gi][mcs_index];
    217	} else if ((ht_info & 0x3) == MWIFIEX_RATE_FORMAT_HT) {
    218		/* 20M: bw=0, 40M: bw=1 */
    219		bw = (ht_info & 0xC) >> 2;
    220
    221		/* LGI: gi =0, SGI: gi = 1 */
    222		gi = (ht_info & 0x10) >> 4;
    223
    224		if (index == MWIFIEX_RATE_BITMAP_MCS0) {
    225			if (gi == 1)
    226				rate = 0x0D;    /* MCS 32 SGI rate */
    227			else
    228				rate = 0x0C;    /* MCS 32 LGI rate */
    229		} else if (index < 16) {
    230			if ((bw == 1) || (bw == 0))
    231				rate = mcs_rate[2 * (1 - bw) + gi][index];
    232			else
    233				rate = mwifiex_data_rates[0];
    234		} else {
    235			rate = mwifiex_data_rates[0];
    236		}
    237	} else {
    238		/* 11n non-HT rates */
    239		if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
    240			index = 0;
    241		rate = mwifiex_data_rates[index];
    242	}
    243
    244	return rate;
    245}
    246
    247/* This function maps an index in supported rates table into
    248 * the corresponding data rate.
    249 */
    250u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv,
    251			       u8 index, u8 ht_info)
    252{
    253	u32 mcs_num_supp =
    254		(priv->adapter->user_dev_mcs_support == HT_STREAM_2X2) ? 16 : 8;
    255	u32 rate;
    256
    257	if (priv->adapter->is_hw_11ac_capable)
    258		return mwifiex_index_to_acs_data_rate(priv, index, ht_info);
    259
    260	if (ht_info & BIT(0)) {
    261		if (index == MWIFIEX_RATE_BITMAP_MCS0) {
    262			if (ht_info & BIT(2))
    263				rate = 0x0D;	/* MCS 32 SGI rate */
    264			else
    265				rate = 0x0C;	/* MCS 32 LGI rate */
    266		} else if (index < mcs_num_supp) {
    267			if (ht_info & BIT(1)) {
    268				if (ht_info & BIT(2))
    269					/* SGI, 40M */
    270					rate = mcs_rate[1][index];
    271				else
    272					/* LGI, 40M */
    273					rate = mcs_rate[0][index];
    274			} else {
    275				if (ht_info & BIT(2))
    276					/* SGI, 20M */
    277					rate = mcs_rate[3][index];
    278				else
    279					/* LGI, 20M */
    280					rate = mcs_rate[2][index];
    281			}
    282		} else
    283			rate = mwifiex_data_rates[0];
    284	} else {
    285		if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
    286			index = 0;
    287		rate = mwifiex_data_rates[index];
    288	}
    289	return rate;
    290}
    291
    292/*
    293 * This function returns the current active data rates.
    294 *
    295 * The result may vary depending upon connection status.
    296 */
    297u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
    298{
    299	if (!priv->media_connected)
    300		return mwifiex_get_supported_rates(priv, rates);
    301	else
    302		return mwifiex_copy_rates(rates, 0,
    303					  priv->curr_bss_params.data_rates,
    304					  priv->curr_bss_params.num_of_rates);
    305}
    306
    307/*
    308 * This function locates the Channel-Frequency-Power triplet based upon
    309 * band and channel/frequency parameters.
    310 */
    311struct mwifiex_chan_freq_power *
    312mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq)
    313{
    314	struct mwifiex_chan_freq_power *cfp = NULL;
    315	struct ieee80211_supported_band *sband;
    316	struct ieee80211_channel *ch = NULL;
    317	int i;
    318
    319	if (!channel && !freq)
    320		return cfp;
    321
    322	if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
    323		sband = priv->wdev.wiphy->bands[NL80211_BAND_2GHZ];
    324	else
    325		sband = priv->wdev.wiphy->bands[NL80211_BAND_5GHZ];
    326
    327	if (!sband) {
    328		mwifiex_dbg(priv->adapter, ERROR,
    329			    "%s: cannot find cfp by band %d\n",
    330			    __func__, band);
    331		return cfp;
    332	}
    333
    334	for (i = 0; i < sband->n_channels; i++) {
    335		ch = &sband->channels[i];
    336
    337		if (ch->flags & IEEE80211_CHAN_DISABLED)
    338			continue;
    339
    340		if (freq) {
    341			if (ch->center_freq == freq)
    342				break;
    343		} else {
    344			/* find by valid channel*/
    345			if (ch->hw_value == channel ||
    346			    channel == FIRST_VALID_CHANNEL)
    347				break;
    348		}
    349	}
    350	if (i == sband->n_channels) {
    351		mwifiex_dbg(priv->adapter, WARN,
    352			    "%s: cannot find cfp by band %d\t"
    353			    "& channel=%d freq=%d\n",
    354			    __func__, band, channel, freq);
    355	} else {
    356		if (!ch)
    357			return cfp;
    358
    359		priv->cfp.channel = ch->hw_value;
    360		priv->cfp.freq = ch->center_freq;
    361		priv->cfp.max_tx_power = ch->max_power;
    362		cfp = &priv->cfp;
    363	}
    364
    365	return cfp;
    366}
    367
    368/*
    369 * This function checks if the data rate is set to auto.
    370 */
    371u8
    372mwifiex_is_rate_auto(struct mwifiex_private *priv)
    373{
    374	u32 i;
    375	int rate_num = 0;
    376
    377	for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates); i++)
    378		if (priv->bitmap_rates[i])
    379			rate_num++;
    380
    381	if (rate_num > 1)
    382		return true;
    383	else
    384		return false;
    385}
    386
    387/* This function gets the supported data rates from bitmask inside
    388 * cfg80211_scan_request.
    389 */
    390u32 mwifiex_get_rates_from_cfg80211(struct mwifiex_private *priv,
    391				    u8 *rates, u8 radio_type)
    392{
    393	struct wiphy *wiphy = priv->adapter->wiphy;
    394	struct cfg80211_scan_request *request = priv->scan_request;
    395	u32 num_rates, rate_mask;
    396	struct ieee80211_supported_band *sband;
    397	int i;
    398
    399	if (radio_type) {
    400		sband = wiphy->bands[NL80211_BAND_5GHZ];
    401		if (WARN_ON_ONCE(!sband))
    402			return 0;
    403		rate_mask = request->rates[NL80211_BAND_5GHZ];
    404	} else {
    405		sband = wiphy->bands[NL80211_BAND_2GHZ];
    406		if (WARN_ON_ONCE(!sband))
    407			return 0;
    408		rate_mask = request->rates[NL80211_BAND_2GHZ];
    409	}
    410
    411	num_rates = 0;
    412	for (i = 0; i < sband->n_bitrates; i++) {
    413		if ((BIT(i) & rate_mask) == 0)
    414			continue; /* skip rate */
    415		rates[num_rates++] = (u8)(sband->bitrates[i].bitrate / 5);
    416	}
    417
    418	return num_rates;
    419}
    420
    421/* This function gets the supported data rates. The function works in
    422 * both Ad-Hoc and infra mode by printing the band and returning the
    423 * data rates.
    424 */
    425u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
    426{
    427	u32 k = 0;
    428	struct mwifiex_adapter *adapter = priv->adapter;
    429
    430	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
    431	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
    432		switch (adapter->config_bands) {
    433		case BAND_B:
    434			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    435				    "supported_rates_b\n",
    436				    adapter->config_bands);
    437			k = mwifiex_copy_rates(rates, k, supported_rates_b,
    438					       sizeof(supported_rates_b));
    439			break;
    440		case BAND_G:
    441		case BAND_G | BAND_GN:
    442			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    443				    "supported_rates_g\n",
    444				    adapter->config_bands);
    445			k = mwifiex_copy_rates(rates, k, supported_rates_g,
    446					       sizeof(supported_rates_g));
    447			break;
    448		case BAND_B | BAND_G:
    449		case BAND_A | BAND_B | BAND_G:
    450		case BAND_A | BAND_B:
    451		case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
    452		case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN | BAND_AAC:
    453		case BAND_B | BAND_G | BAND_GN:
    454			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    455				    "supported_rates_bg\n",
    456				    adapter->config_bands);
    457			k = mwifiex_copy_rates(rates, k, supported_rates_bg,
    458					       sizeof(supported_rates_bg));
    459			break;
    460		case BAND_A:
    461		case BAND_A | BAND_G:
    462			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    463				    "supported_rates_a\n",
    464				    adapter->config_bands);
    465			k = mwifiex_copy_rates(rates, k, supported_rates_a,
    466					       sizeof(supported_rates_a));
    467			break;
    468		case BAND_AN:
    469		case BAND_A | BAND_AN:
    470		case BAND_A | BAND_AN | BAND_AAC:
    471		case BAND_A | BAND_G | BAND_AN | BAND_GN:
    472		case BAND_A | BAND_G | BAND_AN | BAND_GN | BAND_AAC:
    473			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    474				    "supported_rates_a\n",
    475				    adapter->config_bands);
    476			k = mwifiex_copy_rates(rates, k, supported_rates_a,
    477					       sizeof(supported_rates_a));
    478			break;
    479		case BAND_GN:
    480			mwifiex_dbg(adapter, INFO, "info: infra band=%d\t"
    481				    "supported_rates_n\n",
    482				    adapter->config_bands);
    483			k = mwifiex_copy_rates(rates, k, supported_rates_n,
    484					       sizeof(supported_rates_n));
    485			break;
    486		}
    487	} else {
    488		/* Ad-hoc mode */
    489		switch (adapter->adhoc_start_band) {
    490		case BAND_B:
    491			mwifiex_dbg(adapter, INFO, "info: adhoc B\n");
    492			k = mwifiex_copy_rates(rates, k, adhoc_rates_b,
    493					       sizeof(adhoc_rates_b));
    494			break;
    495		case BAND_G:
    496		case BAND_G | BAND_GN:
    497			mwifiex_dbg(adapter, INFO, "info: adhoc G only\n");
    498			k = mwifiex_copy_rates(rates, k, adhoc_rates_g,
    499					       sizeof(adhoc_rates_g));
    500			break;
    501		case BAND_B | BAND_G:
    502		case BAND_B | BAND_G | BAND_GN:
    503			mwifiex_dbg(adapter, INFO, "info: adhoc BG\n");
    504			k = mwifiex_copy_rates(rates, k, adhoc_rates_bg,
    505					       sizeof(adhoc_rates_bg));
    506			break;
    507		case BAND_A:
    508		case BAND_A | BAND_AN:
    509			mwifiex_dbg(adapter, INFO, "info: adhoc A\n");
    510			k = mwifiex_copy_rates(rates, k, adhoc_rates_a,
    511					       sizeof(adhoc_rates_a));
    512			break;
    513		}
    514	}
    515
    516	return k;
    517}
    518
    519u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
    520			    u8 rx_rate, u8 rate_info)
    521{
    522	u8 rate_index = 0;
    523
    524	/* HT40 */
    525	if ((rate_info & BIT(0)) && (rate_info & BIT(1)))
    526		rate_index = MWIFIEX_RATE_INDEX_MCS0 +
    527			     MWIFIEX_BW20_MCS_NUM + rx_rate;
    528	else if (rate_info & BIT(0)) /* HT20 */
    529		rate_index = MWIFIEX_RATE_INDEX_MCS0 + rx_rate;
    530	else
    531		rate_index = (rx_rate > MWIFIEX_RATE_INDEX_OFDM0) ?
    532			      rx_rate - 1 : rx_rate;
    533
    534	if (rate_index >= MWIFIEX_MAX_AC_RX_RATES)
    535		rate_index = MWIFIEX_MAX_AC_RX_RATES - 1;
    536
    537	return rate_index;
    538}