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