2733 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2012 Realtek Corporation.*/3 4#include "wifi.h"5#include "rc.h"6#include "base.h"7#include "efuse.h"8#include "cam.h"9#include "ps.h"10#include "regd.h"11#include "pci.h"12#include <linux/ip.h>13#include <linux/module.h>14#include <linux/udp.h>15 16/*17 *NOTICE!!!: This file will be very big, we should18 *keep it clear under following roles:19 *20 *This file include following parts, so, if you add new21 *functions into this file, please check which part it22 *should includes. or check if you should add new part23 *for this file:24 *25 *1) mac80211 init functions26 *2) tx information functions27 *3) functions called by core.c28 *4) wq & timer callback functions29 *5) frame process functions30 *6) IOT functions31 *7) sysfs functions32 *8) vif functions33 *9) ...34 */35 36/*********************************************************37 *38 * mac80211 init functions39 *40 *********************************************************/41static struct ieee80211_channel rtl_channeltable_2g[] = {42 {.center_freq = 2412, .hw_value = 1,},43 {.center_freq = 2417, .hw_value = 2,},44 {.center_freq = 2422, .hw_value = 3,},45 {.center_freq = 2427, .hw_value = 4,},46 {.center_freq = 2432, .hw_value = 5,},47 {.center_freq = 2437, .hw_value = 6,},48 {.center_freq = 2442, .hw_value = 7,},49 {.center_freq = 2447, .hw_value = 8,},50 {.center_freq = 2452, .hw_value = 9,},51 {.center_freq = 2457, .hw_value = 10,},52 {.center_freq = 2462, .hw_value = 11,},53 {.center_freq = 2467, .hw_value = 12,},54 {.center_freq = 2472, .hw_value = 13,},55 {.center_freq = 2484, .hw_value = 14,},56};57 58static struct ieee80211_channel rtl_channeltable_5g[] = {59 {.center_freq = 5180, .hw_value = 36,},60 {.center_freq = 5200, .hw_value = 40,},61 {.center_freq = 5220, .hw_value = 44,},62 {.center_freq = 5240, .hw_value = 48,},63 {.center_freq = 5260, .hw_value = 52,},64 {.center_freq = 5280, .hw_value = 56,},65 {.center_freq = 5300, .hw_value = 60,},66 {.center_freq = 5320, .hw_value = 64,},67 {.center_freq = 5500, .hw_value = 100,},68 {.center_freq = 5520, .hw_value = 104,},69 {.center_freq = 5540, .hw_value = 108,},70 {.center_freq = 5560, .hw_value = 112,},71 {.center_freq = 5580, .hw_value = 116,},72 {.center_freq = 5600, .hw_value = 120,},73 {.center_freq = 5620, .hw_value = 124,},74 {.center_freq = 5640, .hw_value = 128,},75 {.center_freq = 5660, .hw_value = 132,},76 {.center_freq = 5680, .hw_value = 136,},77 {.center_freq = 5700, .hw_value = 140,},78 {.center_freq = 5745, .hw_value = 149,},79 {.center_freq = 5765, .hw_value = 153,},80 {.center_freq = 5785, .hw_value = 157,},81 {.center_freq = 5805, .hw_value = 161,},82 {.center_freq = 5825, .hw_value = 165,},83};84 85static struct ieee80211_rate rtl_ratetable_2g[] = {86 {.bitrate = 10, .hw_value = 0x00,},87 {.bitrate = 20, .hw_value = 0x01,},88 {.bitrate = 55, .hw_value = 0x02,},89 {.bitrate = 110, .hw_value = 0x03,},90 {.bitrate = 60, .hw_value = 0x04,},91 {.bitrate = 90, .hw_value = 0x05,},92 {.bitrate = 120, .hw_value = 0x06,},93 {.bitrate = 180, .hw_value = 0x07,},94 {.bitrate = 240, .hw_value = 0x08,},95 {.bitrate = 360, .hw_value = 0x09,},96 {.bitrate = 480, .hw_value = 0x0a,},97 {.bitrate = 540, .hw_value = 0x0b,},98};99 100static struct ieee80211_rate rtl_ratetable_5g[] = {101 {.bitrate = 60, .hw_value = 0x04,},102 {.bitrate = 90, .hw_value = 0x05,},103 {.bitrate = 120, .hw_value = 0x06,},104 {.bitrate = 180, .hw_value = 0x07,},105 {.bitrate = 240, .hw_value = 0x08,},106 {.bitrate = 360, .hw_value = 0x09,},107 {.bitrate = 480, .hw_value = 0x0a,},108 {.bitrate = 540, .hw_value = 0x0b,},109};110 111static const struct ieee80211_supported_band rtl_band_2ghz = {112 .band = NL80211_BAND_2GHZ,113 114 .channels = rtl_channeltable_2g,115 .n_channels = ARRAY_SIZE(rtl_channeltable_2g),116 117 .bitrates = rtl_ratetable_2g,118 .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),119 120 .ht_cap = {0},121};122 123static struct ieee80211_supported_band rtl_band_5ghz = {124 .band = NL80211_BAND_5GHZ,125 126 .channels = rtl_channeltable_5g,127 .n_channels = ARRAY_SIZE(rtl_channeltable_5g),128 129 .bitrates = rtl_ratetable_5g,130 .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),131 132 .ht_cap = {0},133};134 135static const u8 tid_to_ac[] = {136 2, /* IEEE80211_AC_BE */137 3, /* IEEE80211_AC_BK */138 3, /* IEEE80211_AC_BK */139 2, /* IEEE80211_AC_BE */140 1, /* IEEE80211_AC_VI */141 1, /* IEEE80211_AC_VI */142 0, /* IEEE80211_AC_VO */143 0, /* IEEE80211_AC_VO */144};145 146u8 rtl_tid_to_ac(u8 tid)147{148 return tid_to_ac[tid];149}150EXPORT_SYMBOL_GPL(rtl_tid_to_ac);151 152static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,153 struct ieee80211_sta_ht_cap *ht_cap)154{155 struct rtl_priv *rtlpriv = rtl_priv(hw);156 struct rtl_phy *rtlphy = &(rtlpriv->phy);157 158 ht_cap->ht_supported = true;159 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |160 IEEE80211_HT_CAP_SGI_40 |161 IEEE80211_HT_CAP_SGI_20 |162 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;163 164 if (rtlpriv->rtlhal.disable_amsdu_8k)165 ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;166 167 /*168 *Maximum length of AMPDU that the STA can receive.169 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)170 */171 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;172 173 /*Minimum MPDU start spacing , */174 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;175 176 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;177 178 /*hw->wiphy->bands[NL80211_BAND_2GHZ]179 *base on ant_num180 *rx_mask: RX mask181 *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7182 *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15183 *if rx_ant >= 3 rx_mask[2]= 0xff;184 *if BW_40 rx_mask[4]= 0x01;185 *highest supported RX rate186 */187 if (rtlpriv->dm.supp_phymode_switch) {188 pr_info("Support phy mode switch\n");189 190 ht_cap->mcs.rx_mask[0] = 0xFF;191 ht_cap->mcs.rx_mask[1] = 0xFF;192 ht_cap->mcs.rx_mask[4] = 0x01;193 194 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);195 } else {196 if (get_rf_type(rtlphy) == RF_1T2R ||197 get_rf_type(rtlphy) == RF_2T2R) {198 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,199 "1T2R or 2T2R\n");200 ht_cap->mcs.rx_mask[0] = 0xFF;201 ht_cap->mcs.rx_mask[1] = 0xFF;202 ht_cap->mcs.rx_mask[4] = 0x01;203 204 ht_cap->mcs.rx_highest =205 cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);206 } else if (get_rf_type(rtlphy) == RF_1T1R) {207 rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n");208 209 ht_cap->mcs.rx_mask[0] = 0xFF;210 ht_cap->mcs.rx_mask[1] = 0x00;211 ht_cap->mcs.rx_mask[4] = 0x01;212 213 ht_cap->mcs.rx_highest =214 cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);215 }216 }217}218 219static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,220 struct ieee80211_sta_vht_cap *vht_cap)221{222 struct rtl_priv *rtlpriv = rtl_priv(hw);223 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);224 225 if (!(rtlpriv->cfg->spec_ver & RTL_SPEC_SUPPORT_VHT))226 return;227 228 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE ||229 rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) {230 u16 mcs_map;231 232 vht_cap->vht_supported = true;233 vht_cap->cap =234 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |235 IEEE80211_VHT_CAP_SHORT_GI_80 |236 IEEE80211_VHT_CAP_TXSTBC |237 IEEE80211_VHT_CAP_RXSTBC_1 |238 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |239 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |240 IEEE80211_VHT_CAP_HTC_VHT |241 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |242 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |243 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |244 0;245 246 mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |247 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |248 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |249 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |250 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |251 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |252 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |253 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;254 255 vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);256 vht_cap->vht_mcs.rx_highest =257 cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9);258 vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);259 vht_cap->vht_mcs.tx_highest =260 cpu_to_le16(MAX_BIT_RATE_SHORT_GI_2NSS_80MHZ_MCS9);261 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {262 u16 mcs_map;263 264 vht_cap->vht_supported = true;265 vht_cap->cap =266 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |267 IEEE80211_VHT_CAP_SHORT_GI_80 |268 IEEE80211_VHT_CAP_TXSTBC |269 IEEE80211_VHT_CAP_RXSTBC_1 |270 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |271 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |272 IEEE80211_VHT_CAP_HTC_VHT |273 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |274 IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |275 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN |276 0;277 278 mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |279 IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 |280 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |281 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |282 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |283 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |284 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |285 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;286 287 vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);288 vht_cap->vht_mcs.rx_highest =289 cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9);290 vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);291 vht_cap->vht_mcs.tx_highest =292 cpu_to_le16(MAX_BIT_RATE_SHORT_GI_1NSS_80MHZ_MCS9);293 }294}295 296static void _rtl_init_mac80211(struct ieee80211_hw *hw)297{298 struct rtl_priv *rtlpriv = rtl_priv(hw);299 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);300 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));301 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));302 struct ieee80211_supported_band *sband;303 304 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&305 rtlhal->bandset == BAND_ON_BOTH) {306 /* 1: 2.4 G bands */307 /* <1> use mac->bands as mem for hw->wiphy->bands */308 sband = &(rtlmac->bands[NL80211_BAND_2GHZ]);309 310 /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ]311 * to default value(1T1R) */312 memcpy(&(rtlmac->bands[NL80211_BAND_2GHZ]), &rtl_band_2ghz,313 sizeof(struct ieee80211_supported_band));314 315 /* <3> init ht cap base on ant_num */316 _rtl_init_hw_ht_capab(hw, &sband->ht_cap);317 318 /* <4> set mac->sband to wiphy->sband */319 hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;320 321 /* 2: 5 G bands */322 /* <1> use mac->bands as mem for hw->wiphy->bands */323 sband = &(rtlmac->bands[NL80211_BAND_5GHZ]);324 325 /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ]326 * to default value(1T1R) */327 memcpy(&(rtlmac->bands[NL80211_BAND_5GHZ]), &rtl_band_5ghz,328 sizeof(struct ieee80211_supported_band));329 330 /* <3> init ht cap base on ant_num */331 _rtl_init_hw_ht_capab(hw, &sband->ht_cap);332 333 _rtl_init_hw_vht_capab(hw, &sband->vht_cap);334 /* <4> set mac->sband to wiphy->sband */335 hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;336 } else {337 if (rtlhal->current_bandtype == BAND_ON_2_4G) {338 /* <1> use mac->bands as mem for hw->wiphy->bands */339 sband = &(rtlmac->bands[NL80211_BAND_2GHZ]);340 341 /* <2> set hw->wiphy->bands[NL80211_BAND_2GHZ]342 * to default value(1T1R) */343 memcpy(&(rtlmac->bands[NL80211_BAND_2GHZ]),344 &rtl_band_2ghz,345 sizeof(struct ieee80211_supported_band));346 347 /* <3> init ht cap base on ant_num */348 _rtl_init_hw_ht_capab(hw, &sband->ht_cap);349 350 /* <4> set mac->sband to wiphy->sband */351 hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;352 } else if (rtlhal->current_bandtype == BAND_ON_5G) {353 /* <1> use mac->bands as mem for hw->wiphy->bands */354 sband = &(rtlmac->bands[NL80211_BAND_5GHZ]);355 356 /* <2> set hw->wiphy->bands[NL80211_BAND_5GHZ]357 * to default value(1T1R) */358 memcpy(&(rtlmac->bands[NL80211_BAND_5GHZ]),359 &rtl_band_5ghz,360 sizeof(struct ieee80211_supported_band));361 362 /* <3> init ht cap base on ant_num */363 _rtl_init_hw_ht_capab(hw, &sband->ht_cap);364 365 _rtl_init_hw_vht_capab(hw, &sband->vht_cap);366 /* <4> set mac->sband to wiphy->sband */367 hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;368 } else {369 pr_err("Err BAND %d\n",370 rtlhal->current_bandtype);371 }372 }373 /* <5> set hw caps */374 ieee80211_hw_set(hw, SIGNAL_DBM);375 ieee80211_hw_set(hw, RX_INCLUDES_FCS);376 ieee80211_hw_set(hw, AMPDU_AGGREGATION);377 ieee80211_hw_set(hw, MFP_CAPABLE);378 ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);379 ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);380 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);381 382 /* swlps or hwlps has been set in diff chip in init_sw_vars */383 if (rtlpriv->psc.swctrl_lps) {384 ieee80211_hw_set(hw, SUPPORTS_PS);385 ieee80211_hw_set(hw, PS_NULLFUNC_STACK);386 }387 if (rtlpriv->psc.fwctrl_lps) {388 ieee80211_hw_set(hw, SUPPORTS_PS);389 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);390 }391 hw->wiphy->interface_modes =392 BIT(NL80211_IFTYPE_AP) |393 BIT(NL80211_IFTYPE_STATION) |394 BIT(NL80211_IFTYPE_ADHOC) |395 BIT(NL80211_IFTYPE_MESH_POINT) |396 BIT(NL80211_IFTYPE_P2P_CLIENT) |397 BIT(NL80211_IFTYPE_P2P_GO);398 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;399 400 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;401 402 hw->wiphy->rts_threshold = 2347;403 404 hw->queues = AC_MAX;405 hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;406 407 /* TODO: Correct this value for our hw */408 hw->max_listen_interval = MAX_LISTEN_INTERVAL;409 hw->max_rate_tries = MAX_RATE_TRIES;410 /* hw->max_rates = 1; */411 hw->sta_data_size = sizeof(struct rtl_sta_info);412 413/* wowlan is not supported by kernel if CONFIG_PM is not defined */414#ifdef CONFIG_PM415 if (rtlpriv->psc.wo_wlan_mode) {416 if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_MAGIC_PACKET)417 rtlpriv->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;418 if (rtlpriv->psc.wo_wlan_mode & WAKE_ON_PATTERN_MATCH) {419 rtlpriv->wowlan.n_patterns =420 MAX_SUPPORT_WOL_PATTERN_NUM;421 rtlpriv->wowlan.pattern_min_len = MIN_WOL_PATTERN_SIZE;422 rtlpriv->wowlan.pattern_max_len = MAX_WOL_PATTERN_SIZE;423 }424 hw->wiphy->wowlan = &rtlpriv->wowlan;425 }426#endif427 428 /* <6> mac address */429 if (is_valid_ether_addr(rtlefuse->dev_addr)) {430 SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);431 } else {432 u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };433 434 get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);435 SET_IEEE80211_PERM_ADDR(hw, rtlmac1);436 }437}438 439static void rtl_watchdog_wq_callback(struct work_struct *work);440static void rtl_fwevt_wq_callback(struct work_struct *work);441static void rtl_c2hcmd_wq_callback(struct work_struct *work);442 443static int _rtl_init_deferred_work(struct ieee80211_hw *hw)444{445 struct rtl_priv *rtlpriv = rtl_priv(hw);446 struct workqueue_struct *wq;447 448 wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);449 if (!wq)450 return -ENOMEM;451 452 /* <1> timer */453 timer_setup(&rtlpriv->works.watchdog_timer,454 rtl_watch_dog_timer_callback, 0);455 456 /* <2> work queue */457 rtlpriv->works.hw = hw;458 rtlpriv->works.rtl_wq = wq;459 460 INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,461 rtl_watchdog_wq_callback);462 INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,463 rtl_ips_nic_off_wq_callback);464 INIT_DELAYED_WORK(&rtlpriv->works.ps_work, rtl_swlps_wq_callback);465 INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,466 rtl_swlps_rfon_wq_callback);467 INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq, rtl_fwevt_wq_callback);468 INIT_DELAYED_WORK(&rtlpriv->works.c2hcmd_wq, rtl_c2hcmd_wq_callback);469 return 0;470}471 472void rtl_deinit_deferred_work(struct ieee80211_hw *hw, bool ips_wq)473{474 struct rtl_priv *rtlpriv = rtl_priv(hw);475 476 del_timer_sync(&rtlpriv->works.watchdog_timer);477 478 cancel_delayed_work_sync(&rtlpriv->works.watchdog_wq);479 if (ips_wq)480 cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);481 else482 cancel_delayed_work_sync(&rtlpriv->works.ips_nic_off_wq);483 cancel_delayed_work_sync(&rtlpriv->works.ps_work);484 cancel_delayed_work_sync(&rtlpriv->works.ps_rfon_wq);485 cancel_delayed_work_sync(&rtlpriv->works.fwevt_wq);486 cancel_delayed_work_sync(&rtlpriv->works.c2hcmd_wq);487}488EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work);489 490void rtl_init_rfkill(struct ieee80211_hw *hw)491{492 struct rtl_priv *rtlpriv = rtl_priv(hw);493 494 bool radio_state;495 bool blocked;496 u8 valid = 0;497 498 /*set init state to on */499 rtlpriv->rfkill.rfkill_state = true;500 wiphy_rfkill_set_hw_state(hw->wiphy, 0);501 502 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);503 504 if (valid) {505 pr_info("rtlwifi: wireless switch is %s\n",506 rtlpriv->rfkill.rfkill_state ? "on" : "off");507 508 rtlpriv->rfkill.rfkill_state = radio_state;509 510 blocked = rtlpriv->rfkill.rfkill_state != 1;511 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);512 }513 514 wiphy_rfkill_start_polling(hw->wiphy);515}516EXPORT_SYMBOL(rtl_init_rfkill);517 518void rtl_deinit_rfkill(struct ieee80211_hw *hw)519{520 wiphy_rfkill_stop_polling(hw->wiphy);521}522EXPORT_SYMBOL_GPL(rtl_deinit_rfkill);523 524int rtl_init_core(struct ieee80211_hw *hw)525{526 struct rtl_priv *rtlpriv = rtl_priv(hw);527 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));528 529 /* <1> init mac80211 */530 _rtl_init_mac80211(hw);531 rtlmac->hw = hw;532 533 /* <2> rate control register */534 hw->rate_control_algorithm = "rtl_rc";535 536 /*537 * <3> init CRDA must come after init538 * mac80211 hw in _rtl_init_mac80211.539 */540 if (rtl_regd_init(hw, rtl_reg_notifier)) {541 pr_err("REGD init failed\n");542 return 1;543 }544 545 /* <4> locks */546 mutex_init(&rtlpriv->locks.conf_mutex);547 mutex_init(&rtlpriv->locks.ips_mutex);548 mutex_init(&rtlpriv->locks.lps_mutex);549 spin_lock_init(&rtlpriv->locks.irq_th_lock);550 spin_lock_init(&rtlpriv->locks.h2c_lock);551 spin_lock_init(&rtlpriv->locks.rf_ps_lock);552 spin_lock_init(&rtlpriv->locks.rf_lock);553 spin_lock_init(&rtlpriv->locks.waitq_lock);554 spin_lock_init(&rtlpriv->locks.entry_list_lock);555 spin_lock_init(&rtlpriv->locks.scan_list_lock);556 spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);557 spin_lock_init(&rtlpriv->locks.fw_ps_lock);558 spin_lock_init(&rtlpriv->locks.iqk_lock);559 /* <5> init list */560 INIT_LIST_HEAD(&rtlpriv->entry_list);561 INIT_LIST_HEAD(&rtlpriv->scan_list.list);562 skb_queue_head_init(&rtlpriv->tx_report.queue);563 skb_queue_head_init(&rtlpriv->c2hcmd_queue);564 565 rtlmac->link_state = MAC80211_NOLINK;566 567 /* <6> init deferred work */568 return _rtl_init_deferred_work(hw);569}570EXPORT_SYMBOL_GPL(rtl_init_core);571 572static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw);573static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,574 bool timeout);575 576void rtl_deinit_core(struct ieee80211_hw *hw)577{578 rtl_c2hcmd_launcher(hw, 0);579 rtl_free_entries_from_scan_list(hw);580 rtl_free_entries_from_ack_queue(hw, false);581}582EXPORT_SYMBOL_GPL(rtl_deinit_core);583 584void rtl_init_rx_config(struct ieee80211_hw *hw)585{586 struct rtl_priv *rtlpriv = rtl_priv(hw);587 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));588 589 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));590}591EXPORT_SYMBOL_GPL(rtl_init_rx_config);592 593/*********************************************************594 *595 * tx information functions596 *597 *********************************************************/598static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,599 struct rtl_tcb_desc *tcb_desc,600 struct ieee80211_tx_info *info)601{602 struct rtl_priv *rtlpriv = rtl_priv(hw);603 u8 rate_flag = info->control.rates[0].flags;604 605 tcb_desc->use_shortpreamble = false;606 607 /* 1M can only use Long Preamble. 11B spec */608 if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])609 return;610 else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)611 tcb_desc->use_shortpreamble = true;612 613 return;614}615 616static void _rtl_query_shortgi(struct ieee80211_hw *hw,617 struct ieee80211_sta *sta,618 struct rtl_tcb_desc *tcb_desc,619 struct ieee80211_tx_info *info)620{621 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));622 u8 rate_flag = info->control.rates[0].flags;623 u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;624 u8 sgi_80 = 0, bw_80 = 0;625 626 tcb_desc->use_shortgi = false;627 628 if (sta == NULL)629 return;630 631 sgi_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40;632 sgi_20 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20;633 sgi_80 = sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80;634 635 if (!sta->deflink.ht_cap.ht_supported &&636 !sta->deflink.vht_cap.vht_supported)637 return;638 639 if (!sgi_40 && !sgi_20)640 return;641 642 if (mac->opmode == NL80211_IFTYPE_STATION) {643 bw_40 = mac->bw_40;644 bw_80 = mac->bw_80;645 } else if (mac->opmode == NL80211_IFTYPE_AP ||646 mac->opmode == NL80211_IFTYPE_ADHOC ||647 mac->opmode == NL80211_IFTYPE_MESH_POINT) {648 bw_40 = sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;649 bw_80 = sta->deflink.vht_cap.vht_supported;650 }651 652 if (bw_80) {653 if (sgi_80)654 tcb_desc->use_shortgi = true;655 else656 tcb_desc->use_shortgi = false;657 } else {658 if (bw_40 && sgi_40)659 tcb_desc->use_shortgi = true;660 else if (!bw_40 && sgi_20)661 tcb_desc->use_shortgi = true;662 }663 664 if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))665 tcb_desc->use_shortgi = false;666}667 668static void _rtl_query_protection_mode(struct ieee80211_hw *hw,669 struct rtl_tcb_desc *tcb_desc,670 struct ieee80211_tx_info *info)671{672 struct rtl_priv *rtlpriv = rtl_priv(hw);673 u8 rate_flag = info->control.rates[0].flags;674 675 /* Common Settings */676 tcb_desc->rts_stbc = false;677 tcb_desc->cts_enable = false;678 tcb_desc->rts_sc = 0;679 tcb_desc->rts_bw = false;680 tcb_desc->rts_use_shortpreamble = false;681 tcb_desc->rts_use_shortgi = false;682 683 if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {684 /* Use CTS-to-SELF in protection mode. */685 tcb_desc->rts_enable = true;686 tcb_desc->cts_enable = true;687 tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];688 } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {689 /* Use RTS-CTS in protection mode. */690 tcb_desc->rts_enable = true;691 tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];692 }693}694 695u8 rtl_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index,696 enum wireless_mode wirelessmode)697{698 struct rtl_priv *rtlpriv = rtl_priv(hw);699 struct rtl_phy *rtlphy = &rtlpriv->phy;700 u8 ret = 0;701 702 switch (rate_index) {703 case RATR_INX_WIRELESS_NGB:704 if (rtlphy->rf_type == RF_1T1R)705 ret = RATEID_IDX_BGN_40M_1SS;706 else707 ret = RATEID_IDX_BGN_40M_2SS;708 ; break;709 case RATR_INX_WIRELESS_N:710 case RATR_INX_WIRELESS_NG:711 if (rtlphy->rf_type == RF_1T1R)712 ret = RATEID_IDX_GN_N1SS;713 else714 ret = RATEID_IDX_GN_N2SS;715 ; break;716 case RATR_INX_WIRELESS_NB:717 if (rtlphy->rf_type == RF_1T1R)718 ret = RATEID_IDX_BGN_20M_1SS_BN;719 else720 ret = RATEID_IDX_BGN_20M_2SS_BN;721 ; break;722 case RATR_INX_WIRELESS_GB:723 ret = RATEID_IDX_BG;724 break;725 case RATR_INX_WIRELESS_G:726 ret = RATEID_IDX_G;727 break;728 case RATR_INX_WIRELESS_B:729 ret = RATEID_IDX_B;730 break;731 case RATR_INX_WIRELESS_MC:732 if (wirelessmode == WIRELESS_MODE_B ||733 wirelessmode == WIRELESS_MODE_G ||734 wirelessmode == WIRELESS_MODE_N_24G ||735 wirelessmode == WIRELESS_MODE_AC_24G)736 ret = RATEID_IDX_BG;737 else738 ret = RATEID_IDX_G;739 break;740 case RATR_INX_WIRELESS_AC_5N:741 if (rtlphy->rf_type == RF_1T1R)742 ret = RATEID_IDX_VHT_1SS;743 else744 ret = RATEID_IDX_VHT_2SS;745 break;746 case RATR_INX_WIRELESS_AC_24N:747 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {748 if (rtlphy->rf_type == RF_1T1R)749 ret = RATEID_IDX_VHT_1SS;750 else751 ret = RATEID_IDX_VHT_2SS;752 } else {753 if (rtlphy->rf_type == RF_1T1R)754 ret = RATEID_IDX_MIX1;755 else756 ret = RATEID_IDX_MIX2;757 }758 break;759 default:760 ret = RATEID_IDX_BGN_40M_2SS;761 break;762 }763 return ret;764}765EXPORT_SYMBOL(rtl_mrate_idx_to_arfr_id);766 767static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,768 struct ieee80211_sta *sta,769 struct rtl_tcb_desc *tcb_desc)770{771#define SET_RATE_ID(rate_id) \772 ({typeof(rate_id) _id = rate_id; \773 ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \774 rtl_mrate_idx_to_arfr_id(hw, _id, \775 (sta_entry ? sta_entry->wireless_mode : \776 WIRELESS_MODE_G)) : \777 _id); })778 779 struct rtl_priv *rtlpriv = rtl_priv(hw);780 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));781 struct rtl_sta_info *sta_entry = NULL;782 u8 ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC);783 784 if (sta) {785 sta_entry = (struct rtl_sta_info *) sta->drv_priv;786 ratr_index = sta_entry->ratr_index;787 }788 if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {789 if (mac->opmode == NL80211_IFTYPE_STATION) {790 tcb_desc->ratr_index = 0;791 } else if (mac->opmode == NL80211_IFTYPE_ADHOC ||792 mac->opmode == NL80211_IFTYPE_MESH_POINT) {793 if (tcb_desc->multicast || tcb_desc->broadcast) {794 tcb_desc->hw_rate =795 rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];796 tcb_desc->use_driver_rate = 1;797 tcb_desc->ratr_index =798 SET_RATE_ID(RATR_INX_WIRELESS_MC);799 } else {800 tcb_desc->ratr_index = ratr_index;801 }802 } else if (mac->opmode == NL80211_IFTYPE_AP) {803 tcb_desc->ratr_index = ratr_index;804 }805 }806 807 if (rtlpriv->dm.useramask) {808 tcb_desc->ratr_index = ratr_index;809 /* TODO we will differentiate adhoc and station future */810 if (mac->opmode == NL80211_IFTYPE_STATION ||811 mac->opmode == NL80211_IFTYPE_MESH_POINT) {812 tcb_desc->mac_id = 0;813 814 if (sta &&815 (rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID))816 ; /* use sta_entry->ratr_index */817 else if (mac->mode == WIRELESS_MODE_AC_5G)818 tcb_desc->ratr_index =819 SET_RATE_ID(RATR_INX_WIRELESS_AC_5N);820 else if (mac->mode == WIRELESS_MODE_AC_24G)821 tcb_desc->ratr_index =822 SET_RATE_ID(RATR_INX_WIRELESS_AC_24N);823 else if (mac->mode == WIRELESS_MODE_N_24G)824 tcb_desc->ratr_index =825 SET_RATE_ID(RATR_INX_WIRELESS_NGB);826 else if (mac->mode == WIRELESS_MODE_N_5G)827 tcb_desc->ratr_index =828 SET_RATE_ID(RATR_INX_WIRELESS_NG);829 else if (mac->mode & WIRELESS_MODE_G)830 tcb_desc->ratr_index =831 SET_RATE_ID(RATR_INX_WIRELESS_GB);832 else if (mac->mode & WIRELESS_MODE_B)833 tcb_desc->ratr_index =834 SET_RATE_ID(RATR_INX_WIRELESS_B);835 else if (mac->mode & WIRELESS_MODE_A)836 tcb_desc->ratr_index =837 SET_RATE_ID(RATR_INX_WIRELESS_G);838 839 } else if (mac->opmode == NL80211_IFTYPE_AP ||840 mac->opmode == NL80211_IFTYPE_ADHOC) {841 if (NULL != sta) {842 if (sta->aid > 0)843 tcb_desc->mac_id = sta->aid + 1;844 else845 tcb_desc->mac_id = 1;846 } else {847 tcb_desc->mac_id = 0;848 }849 }850 }851#undef SET_RATE_ID852}853 854static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,855 struct ieee80211_sta *sta,856 struct rtl_tcb_desc *tcb_desc)857{858 struct rtl_priv *rtlpriv = rtl_priv(hw);859 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));860 861 tcb_desc->packet_bw = false;862 if (!sta)863 return;864 if (mac->opmode == NL80211_IFTYPE_AP ||865 mac->opmode == NL80211_IFTYPE_ADHOC ||866 mac->opmode == NL80211_IFTYPE_MESH_POINT) {867 if (!(sta->deflink.ht_cap.ht_supported) ||868 !(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))869 return;870 } else if (mac->opmode == NL80211_IFTYPE_STATION) {871 if (!mac->bw_40 || !(sta->deflink.ht_cap.ht_supported))872 return;873 }874 if (tcb_desc->multicast || tcb_desc->broadcast)875 return;876 877 /*use legency rate, shall use 20MHz */878 if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])879 return;880 881 tcb_desc->packet_bw = HT_CHANNEL_WIDTH_20_40;882 883 if (rtlpriv->cfg->spec_ver & RTL_SPEC_SUPPORT_VHT) {884 if (mac->opmode == NL80211_IFTYPE_AP ||885 mac->opmode == NL80211_IFTYPE_ADHOC ||886 mac->opmode == NL80211_IFTYPE_MESH_POINT) {887 if (!(sta->deflink.vht_cap.vht_supported))888 return;889 } else if (mac->opmode == NL80211_IFTYPE_STATION) {890 if (!mac->bw_80 ||891 !(sta->deflink.vht_cap.vht_supported))892 return;893 }894 if (tcb_desc->hw_rate <=895 rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15])896 return;897 tcb_desc->packet_bw = HT_CHANNEL_WIDTH_80;898 }899}900 901static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw,902 struct ieee80211_sta *sta)903{904 struct rtl_priv *rtlpriv = rtl_priv(hw);905 struct rtl_phy *rtlphy = &(rtlpriv->phy);906 u8 hw_rate;907 u16 tx_mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.tx_mcs_map);908 909 if ((get_rf_type(rtlphy) == RF_2T2R) &&910 (tx_mcs_map & 0x000c) != 0x000c) {911 if ((tx_mcs_map & 0x000c) >> 2 ==912 IEEE80211_VHT_MCS_SUPPORT_0_7)913 hw_rate =914 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS7];915 else if ((tx_mcs_map & 0x000c) >> 2 ==916 IEEE80211_VHT_MCS_SUPPORT_0_8)917 hw_rate =918 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS8];919 else920 hw_rate =921 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];922 } else {923 if ((tx_mcs_map & 0x0003) ==924 IEEE80211_VHT_MCS_SUPPORT_0_7)925 hw_rate =926 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS7];927 else if ((tx_mcs_map & 0x0003) ==928 IEEE80211_VHT_MCS_SUPPORT_0_8)929 hw_rate =930 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS8];931 else932 hw_rate =933 rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];934 }935 936 return hw_rate;937}938 939static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw,940 struct ieee80211_sta *sta)941{942 struct rtl_priv *rtlpriv = rtl_priv(hw);943 struct rtl_phy *rtlphy = &rtlpriv->phy;944 u8 hw_rate;945 946 if (get_rf_type(rtlphy) == RF_2T2R &&947 sta->deflink.ht_cap.mcs.rx_mask[1] != 0)948 hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];949 else950 hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];951 952 return hw_rate;953}954 955/* mac80211's rate_idx is like this:956 *957 * 2.4G band:rx_status->band == NL80211_BAND_2GHZ958 *959 * B/G rate:960 * (rx_status->flag & RX_FLAG_HT) = 0,961 * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11,962 *963 * N rate:964 * (rx_status->flag & RX_FLAG_HT) = 1,965 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15966 *967 * 5G band:rx_status->band == NL80211_BAND_5GHZ968 * A rate:969 * (rx_status->flag & RX_FLAG_HT) = 0,970 * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7,971 *972 * N rate:973 * (rx_status->flag & RX_FLAG_HT) = 1,974 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15975 *976 * VHT rates:977 * DESC_RATEVHT1SS_MCS0-->DESC_RATEVHT1SS_MCS9 ==> idx is 0-->9978 * DESC_RATEVHT2SS_MCS0-->DESC_RATEVHT2SS_MCS9 ==> idx is 0-->9979 */980int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht,981 u8 desc_rate)982{983 int rate_idx;984 985 if (isvht) {986 switch (desc_rate) {987 case DESC_RATEVHT1SS_MCS0:988 rate_idx = 0;989 break;990 case DESC_RATEVHT1SS_MCS1:991 rate_idx = 1;992 break;993 case DESC_RATEVHT1SS_MCS2:994 rate_idx = 2;995 break;996 case DESC_RATEVHT1SS_MCS3:997 rate_idx = 3;998 break;999 case DESC_RATEVHT1SS_MCS4:1000 rate_idx = 4;1001 break;1002 case DESC_RATEVHT1SS_MCS5:1003 rate_idx = 5;1004 break;1005 case DESC_RATEVHT1SS_MCS6:1006 rate_idx = 6;1007 break;1008 case DESC_RATEVHT1SS_MCS7:1009 rate_idx = 7;1010 break;1011 case DESC_RATEVHT1SS_MCS8:1012 rate_idx = 8;1013 break;1014 case DESC_RATEVHT1SS_MCS9:1015 rate_idx = 9;1016 break;1017 case DESC_RATEVHT2SS_MCS0:1018 rate_idx = 0;1019 break;1020 case DESC_RATEVHT2SS_MCS1:1021 rate_idx = 1;1022 break;1023 case DESC_RATEVHT2SS_MCS2:1024 rate_idx = 2;1025 break;1026 case DESC_RATEVHT2SS_MCS3:1027 rate_idx = 3;1028 break;1029 case DESC_RATEVHT2SS_MCS4:1030 rate_idx = 4;1031 break;1032 case DESC_RATEVHT2SS_MCS5:1033 rate_idx = 5;1034 break;1035 case DESC_RATEVHT2SS_MCS6:1036 rate_idx = 6;1037 break;1038 case DESC_RATEVHT2SS_MCS7:1039 rate_idx = 7;1040 break;1041 case DESC_RATEVHT2SS_MCS8:1042 rate_idx = 8;1043 break;1044 case DESC_RATEVHT2SS_MCS9:1045 rate_idx = 9;1046 break;1047 default:1048 rate_idx = 0;1049 break;1050 }1051 return rate_idx;1052 }1053 if (false == isht) {1054 if (NL80211_BAND_2GHZ == hw->conf.chandef.chan->band) {1055 switch (desc_rate) {1056 case DESC_RATE1M:1057 rate_idx = 0;1058 break;1059 case DESC_RATE2M:1060 rate_idx = 1;1061 break;1062 case DESC_RATE5_5M:1063 rate_idx = 2;1064 break;1065 case DESC_RATE11M:1066 rate_idx = 3;1067 break;1068 case DESC_RATE6M:1069 rate_idx = 4;1070 break;1071 case DESC_RATE9M:1072 rate_idx = 5;1073 break;1074 case DESC_RATE12M:1075 rate_idx = 6;1076 break;1077 case DESC_RATE18M:1078 rate_idx = 7;1079 break;1080 case DESC_RATE24M:1081 rate_idx = 8;1082 break;1083 case DESC_RATE36M:1084 rate_idx = 9;1085 break;1086 case DESC_RATE48M:1087 rate_idx = 10;1088 break;1089 case DESC_RATE54M:1090 rate_idx = 11;1091 break;1092 default:1093 rate_idx = 0;1094 break;1095 }1096 } else {1097 switch (desc_rate) {1098 case DESC_RATE6M:1099 rate_idx = 0;1100 break;1101 case DESC_RATE9M:1102 rate_idx = 1;1103 break;1104 case DESC_RATE12M:1105 rate_idx = 2;1106 break;1107 case DESC_RATE18M:1108 rate_idx = 3;1109 break;1110 case DESC_RATE24M:1111 rate_idx = 4;1112 break;1113 case DESC_RATE36M:1114 rate_idx = 5;1115 break;1116 case DESC_RATE48M:1117 rate_idx = 6;1118 break;1119 case DESC_RATE54M:1120 rate_idx = 7;1121 break;1122 default:1123 rate_idx = 0;1124 break;1125 }1126 }1127 } else {1128 switch (desc_rate) {1129 case DESC_RATEMCS0:1130 rate_idx = 0;1131 break;1132 case DESC_RATEMCS1:1133 rate_idx = 1;1134 break;1135 case DESC_RATEMCS2:1136 rate_idx = 2;1137 break;1138 case DESC_RATEMCS3:1139 rate_idx = 3;1140 break;1141 case DESC_RATEMCS4:1142 rate_idx = 4;1143 break;1144 case DESC_RATEMCS5:1145 rate_idx = 5;1146 break;1147 case DESC_RATEMCS6:1148 rate_idx = 6;1149 break;1150 case DESC_RATEMCS7:1151 rate_idx = 7;1152 break;1153 case DESC_RATEMCS8:1154 rate_idx = 8;1155 break;1156 case DESC_RATEMCS9:1157 rate_idx = 9;1158 break;1159 case DESC_RATEMCS10:1160 rate_idx = 10;1161 break;1162 case DESC_RATEMCS11:1163 rate_idx = 11;1164 break;1165 case DESC_RATEMCS12:1166 rate_idx = 12;1167 break;1168 case DESC_RATEMCS13:1169 rate_idx = 13;1170 break;1171 case DESC_RATEMCS14:1172 rate_idx = 14;1173 break;1174 case DESC_RATEMCS15:1175 rate_idx = 15;1176 break;1177 default:1178 rate_idx = 0;1179 break;1180 }1181 }1182 return rate_idx;1183}1184EXPORT_SYMBOL(rtlwifi_rate_mapping);1185 1186static u8 _rtl_get_tx_hw_rate(struct ieee80211_hw *hw,1187 struct ieee80211_tx_info *info)1188{1189 struct rtl_priv *rtlpriv = rtl_priv(hw);1190 struct ieee80211_tx_rate *r = &info->status.rates[0];1191 struct ieee80211_rate *txrate;1192 u8 hw_value = 0x0;1193 1194 if (r->flags & IEEE80211_TX_RC_MCS) {1195 /* HT MCS0-15 */1196 hw_value = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15] - 15 +1197 r->idx;1198 } else if (r->flags & IEEE80211_TX_RC_VHT_MCS) {1199 /* VHT MCS0-9, NSS */1200 if (ieee80211_rate_get_vht_nss(r) == 2)1201 hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];1202 else1203 hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];1204 1205 hw_value = hw_value - 9 + ieee80211_rate_get_vht_mcs(r);1206 } else {1207 /* legacy */1208 txrate = ieee80211_get_tx_rate(hw, info);1209 1210 if (txrate)1211 hw_value = txrate->hw_value;1212 }1213 1214 /* check 5G band */1215 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G &&1216 hw_value < rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])1217 hw_value = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M];1218 1219 return hw_value;1220}1221 1222void rtl_get_tcb_desc(struct ieee80211_hw *hw,1223 struct ieee80211_tx_info *info,1224 struct ieee80211_sta *sta,1225 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)1226{1227#define SET_RATE_ID(rate_id) \1228 ({typeof(rate_id) _id = rate_id; \1229 ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \1230 rtl_mrate_idx_to_arfr_id(hw, _id, \1231 (sta_entry ? sta_entry->wireless_mode : \1232 WIRELESS_MODE_G)) : \1233 _id); })1234 1235 struct rtl_priv *rtlpriv = rtl_priv(hw);1236 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));1237 struct ieee80211_hdr *hdr = rtl_get_hdr(skb);1238 struct rtl_sta_info *sta_entry =1239 (sta ? (struct rtl_sta_info *)sta->drv_priv : NULL);1240 1241 __le16 fc = rtl_get_fc(skb);1242 1243 tcb_desc->hw_rate = _rtl_get_tx_hw_rate(hw, info);1244 1245 if (rtl_is_tx_report_skb(hw, skb))1246 tcb_desc->use_spe_rpt = 1;1247 1248 if (ieee80211_is_data(fc)) {1249 /*1250 *we set data rate INX 01251 *in rtl_rc.c if skb is special data or1252 *mgt which need low data rate.1253 */1254 1255 /*1256 *So tcb_desc->hw_rate is just used for1257 *special data and mgt frames1258 */1259 if (info->control.rates[0].idx == 0 ||1260 ieee80211_is_nullfunc(fc)) {1261 tcb_desc->use_driver_rate = true;1262 tcb_desc->ratr_index =1263 SET_RATE_ID(RATR_INX_WIRELESS_MC);1264 1265 tcb_desc->disable_ratefallback = 1;1266 } else {1267 /*1268 *because hw will nerver use hw_rate1269 *when tcb_desc->use_driver_rate = false1270 *so we never set highest N rate here,1271 *and N rate will all be controlled by FW1272 *when tcb_desc->use_driver_rate = false1273 */1274 if (sta && sta->deflink.vht_cap.vht_supported) {1275 tcb_desc->hw_rate =1276 _rtl_get_vht_highest_n_rate(hw, sta);1277 } else {1278 if (sta && sta->deflink.ht_cap.ht_supported) {1279 tcb_desc->hw_rate =1280 _rtl_get_highest_n_rate(hw, sta);1281 } else {1282 if (rtlmac->mode == WIRELESS_MODE_B) {1283 tcb_desc->hw_rate =1284 rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];1285 } else {1286 tcb_desc->hw_rate =1287 rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];1288 }1289 }1290 }1291 }1292 1293 if (is_multicast_ether_addr(hdr->addr1))1294 tcb_desc->multicast = 1;1295 else if (is_broadcast_ether_addr(hdr->addr1))1296 tcb_desc->broadcast = 1;1297 1298 _rtl_txrate_selectmode(hw, sta, tcb_desc);1299 _rtl_query_bandwidth_mode(hw, sta, tcb_desc);1300 _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);1301 _rtl_query_shortgi(hw, sta, tcb_desc, info);1302 _rtl_query_protection_mode(hw, tcb_desc, info);1303 } else {1304 tcb_desc->use_driver_rate = true;1305 tcb_desc->ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC);1306 tcb_desc->disable_ratefallback = 1;1307 tcb_desc->mac_id = 0;1308 tcb_desc->packet_bw = false;1309 }1310#undef SET_RATE_ID1311}1312EXPORT_SYMBOL(rtl_get_tcb_desc);1313 1314bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)1315{1316 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1317 struct rtl_priv *rtlpriv = rtl_priv(hw);1318 __le16 fc = rtl_get_fc(skb);1319 1320 if (ieee80211_is_auth(fc)) {1321 rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");1322 1323 mac->link_state = MAC80211_LINKING;1324 /* Dul mac */1325 rtlpriv->phy.need_iqk = true;1326 1327 }1328 1329 return true;1330}1331EXPORT_SYMBOL_GPL(rtl_tx_mgmt_proc);1332 1333struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, u8 *sa,1334 u8 *bssid, u16 tid);1335 1336static void process_agg_start(struct ieee80211_hw *hw,1337 struct ieee80211_hdr *hdr, u16 tid)1338{1339 struct rtl_priv *rtlpriv = rtl_priv(hw);1340 struct ieee80211_rx_status rx_status = { 0 };1341 struct sk_buff *skb_delba = NULL;1342 1343 skb_delba = rtl_make_del_ba(hw, hdr->addr2, hdr->addr3, tid);1344 if (skb_delba) {1345 rx_status.freq = hw->conf.chandef.chan->center_freq;1346 rx_status.band = hw->conf.chandef.chan->band;1347 rx_status.flag |= RX_FLAG_DECRYPTED;1348 rx_status.flag |= RX_FLAG_MACTIME_START;1349 rx_status.rate_idx = 0;1350 rx_status.signal = 50 + 10;1351 memcpy(IEEE80211_SKB_RXCB(skb_delba),1352 &rx_status, sizeof(rx_status));1353 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG,1354 "fake del\n",1355 skb_delba->data,1356 skb_delba->len);1357 ieee80211_rx_irqsafe(hw, skb_delba);1358 }1359}1360 1361bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)1362{1363 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1364 struct ieee80211_hdr *hdr = rtl_get_hdr(skb);1365 struct rtl_priv *rtlpriv = rtl_priv(hw);1366 __le16 fc = rtl_get_fc(skb);1367 u8 *act = (u8 *)(((u8 *)skb->data + MAC80211_3ADDR_LEN));1368 u8 category;1369 1370 if (!ieee80211_is_action(fc))1371 return true;1372 1373 category = *act;1374 act++;1375 switch (category) {1376 case ACT_CAT_BA:1377 switch (*act) {1378 case ACT_ADDBAREQ:1379 if (mac->act_scanning)1380 return false;1381 1382 rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,1383 "%s ACT_ADDBAREQ From :%pM\n",1384 is_tx ? "Tx" : "Rx", hdr->addr2);1385 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n",1386 skb->data, skb->len);1387 if (!is_tx) {1388 struct ieee80211_sta *sta = NULL;1389 struct rtl_sta_info *sta_entry = NULL;1390 struct rtl_tid_data *tid_data;1391 struct ieee80211_mgmt *mgmt = (void *)skb->data;1392 u16 capab = 0, tid = 0;1393 1394 rcu_read_lock();1395 sta = rtl_find_sta(hw, hdr->addr3);1396 if (sta == NULL) {1397 rtl_dbg(rtlpriv, COMP_SEND | COMP_RECV,1398 DBG_DMESG, "sta is NULL\n");1399 rcu_read_unlock();1400 return true;1401 }1402 1403 sta_entry =1404 (struct rtl_sta_info *)sta->drv_priv;1405 capab =1406 le16_to_cpu(mgmt->u.action.u.addba_req.capab);1407 tid = (capab &1408 IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;1409 if (tid >= MAX_TID_COUNT) {1410 rcu_read_unlock();1411 return true;1412 }1413 tid_data = &sta_entry->tids[tid];1414 if (tid_data->agg.rx_agg_state ==1415 RTL_RX_AGG_START)1416 process_agg_start(hw, hdr, tid);1417 rcu_read_unlock();1418 }1419 break;1420 case ACT_ADDBARSP:1421 rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,1422 "%s ACT_ADDBARSP From :%pM\n",1423 is_tx ? "Tx" : "Rx", hdr->addr2);1424 break;1425 case ACT_DELBA:1426 rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,1427 "ACT_ADDBADEL From :%pM\n", hdr->addr2);1428 break;1429 }1430 break;1431 default:1432 break;1433 }1434 1435 return true;1436}1437EXPORT_SYMBOL_GPL(rtl_action_proc);1438 1439static void setup_special_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc,1440 int type)1441{1442 struct ieee80211_hw *hw = rtlpriv->hw;1443 1444 rtlpriv->ra.is_special_data = true;1445 if (rtlpriv->cfg->ops->get_btc_status())1446 rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(1447 rtlpriv, type);1448 rtl_lps_leave(hw, false);1449 ppsc->last_delaylps_stamp_jiffies = jiffies;1450}1451 1452static const u8 *rtl_skb_ether_type_ptr(struct ieee80211_hw *hw,1453 struct sk_buff *skb, bool is_enc)1454{1455 struct rtl_priv *rtlpriv = rtl_priv(hw);1456 u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);1457 u8 encrypt_header_len = 0;1458 u8 offset;1459 1460 switch (rtlpriv->sec.pairwise_enc_algorithm) {1461 case WEP40_ENCRYPTION:1462 case WEP104_ENCRYPTION:1463 encrypt_header_len = 4;/*WEP_IV_LEN*/1464 break;1465 case TKIP_ENCRYPTION:1466 encrypt_header_len = 8;/*TKIP_IV_LEN*/1467 break;1468 case AESCCMP_ENCRYPTION:1469 encrypt_header_len = 8;/*CCMP_HDR_LEN;*/1470 break;1471 default:1472 break;1473 }1474 1475 offset = mac_hdr_len + SNAP_SIZE;1476 if (is_enc)1477 offset += encrypt_header_len;1478 1479 return skb->data + offset;1480}1481 1482/*should call before software enc*/1483u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,1484 bool is_enc)1485{1486 struct rtl_priv *rtlpriv = rtl_priv(hw);1487 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1488 __le16 fc = rtl_get_fc(skb);1489 u16 ether_type;1490 const u8 *ether_type_ptr;1491 const struct iphdr *ip;1492 1493 if (!ieee80211_is_data(fc))1494 goto end;1495 1496 ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, is_enc);1497 ether_type = be16_to_cpup((__be16 *)ether_type_ptr);1498 1499 if (ETH_P_IP == ether_type) {1500 ip = (struct iphdr *)((u8 *)ether_type_ptr +1501 PROTOC_TYPE_SIZE);1502 if (IPPROTO_UDP == ip->protocol) {1503 struct udphdr *udp = (struct udphdr *)((u8 *)ip +1504 (ip->ihl << 2));1505 if (((((u8 *)udp)[1] == 68) &&1506 (((u8 *)udp)[3] == 67)) ||1507 ((((u8 *)udp)[1] == 67) &&1508 (((u8 *)udp)[3] == 68))) {1509 /* 68 : UDP BOOTP client1510 * 67 : UDP BOOTP server1511 */1512 rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV),1513 DBG_DMESG, "dhcp %s !!\n",1514 (is_tx) ? "Tx" : "Rx");1515 1516 if (is_tx)1517 setup_special_tx(rtlpriv, ppsc,1518 PACKET_DHCP);1519 1520 return true;1521 }1522 }1523 } else if (ETH_P_ARP == ether_type) {1524 if (is_tx)1525 setup_special_tx(rtlpriv, ppsc, PACKET_ARP);1526 1527 return true;1528 } else if (ETH_P_PAE == ether_type) {1529 /* EAPOL is seens as in-4way */1530 rtlpriv->btcoexist.btc_info.in_4way = true;1531 rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies;1532 1533 rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,1534 "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx");1535 1536 if (is_tx) {1537 rtlpriv->ra.is_special_data = true;1538 rtl_lps_leave(hw, false);1539 ppsc->last_delaylps_stamp_jiffies = jiffies;1540 1541 setup_special_tx(rtlpriv, ppsc, PACKET_EAPOL);1542 }1543 1544 return true;1545 } else if (ETH_P_IPV6 == ether_type) {1546 /* TODO: Handle any IPv6 cases that need special handling.1547 * For now, always return false1548 */1549 goto end;1550 }1551 1552end:1553 rtlpriv->ra.is_special_data = false;1554 return false;1555}1556EXPORT_SYMBOL_GPL(rtl_is_special_data);1557 1558void rtl_tx_ackqueue(struct ieee80211_hw *hw, struct sk_buff *skb)1559{1560 struct rtl_priv *rtlpriv = rtl_priv(hw);1561 struct rtl_tx_report *tx_report = &rtlpriv->tx_report;1562 1563 __skb_queue_tail(&tx_report->queue, skb);1564}1565EXPORT_SYMBOL_GPL(rtl_tx_ackqueue);1566 1567static void rtl_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,1568 bool ack)1569{1570 struct rtl_priv *rtlpriv = rtl_priv(hw);1571 struct ieee80211_tx_info *info;1572 1573 info = IEEE80211_SKB_CB(skb);1574 ieee80211_tx_info_clear_status(info);1575 if (ack) {1576 rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD,1577 "tx report: ack\n");1578 info->flags |= IEEE80211_TX_STAT_ACK;1579 } else {1580 rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD,1581 "tx report: not ack\n");1582 info->flags &= ~IEEE80211_TX_STAT_ACK;1583 }1584 ieee80211_tx_status_irqsafe(hw, skb);1585}1586 1587bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb)1588{1589 u16 ether_type;1590 const u8 *ether_type_ptr;1591 __le16 fc = rtl_get_fc(skb);1592 1593 ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, true);1594 ether_type = be16_to_cpup((__be16 *)ether_type_ptr);1595 1596 if (ether_type == ETH_P_PAE || ieee80211_is_nullfunc(fc))1597 return true;1598 1599 return false;1600}1601 1602static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw,1603 struct rtlwifi_tx_info *tx_info)1604{1605 struct rtl_priv *rtlpriv = rtl_priv(hw);1606 struct rtl_tx_report *tx_report = &rtlpriv->tx_report;1607 u16 sn;1608 1609 /* SW_DEFINE[11:8] are reserved (driver fills zeros)1610 * SW_DEFINE[7:2] are used by driver1611 * SW_DEFINE[1:0] are reserved for firmware (driver fills zeros)1612 */1613 sn = (atomic_inc_return(&tx_report->sn) & 0x003F) << 2;1614 1615 tx_report->last_sent_sn = sn;1616 tx_report->last_sent_time = jiffies;1617 tx_info->sn = sn;1618 tx_info->send_time = tx_report->last_sent_time;1619 rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG,1620 "Send TX-Report sn=0x%X\n", sn);1621 1622 return sn;1623}1624 1625void rtl_set_tx_report(struct rtl_tcb_desc *ptcb_desc, u8 *pdesc,1626 struct ieee80211_hw *hw, struct rtlwifi_tx_info *tx_info)1627{1628 if (ptcb_desc->use_spe_rpt) {1629 u16 sn = rtl_get_tx_report_sn(hw, tx_info);1630 1631 SET_TX_DESC_SPE_RPT(pdesc, 1);1632 SET_TX_DESC_SW_DEFINE(pdesc, sn);1633 }1634}1635EXPORT_SYMBOL_GPL(rtl_set_tx_report);1636 1637void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len)1638{1639 struct rtl_priv *rtlpriv = rtl_priv(hw);1640 struct rtl_tx_report *tx_report = &rtlpriv->tx_report;1641 struct rtlwifi_tx_info *tx_info;1642 struct sk_buff_head *queue = &tx_report->queue;1643 struct sk_buff *skb;1644 u16 sn;1645 u8 st, retry;1646 1647 if (rtlpriv->cfg->spec_ver & RTL_SPEC_EXT_C2H) {1648 sn = GET_TX_REPORT_SN_V2(tmp_buf);1649 st = GET_TX_REPORT_ST_V2(tmp_buf);1650 retry = GET_TX_REPORT_RETRY_V2(tmp_buf);1651 } else {1652 sn = GET_TX_REPORT_SN_V1(tmp_buf);1653 st = GET_TX_REPORT_ST_V1(tmp_buf);1654 retry = GET_TX_REPORT_RETRY_V1(tmp_buf);1655 }1656 1657 tx_report->last_recv_sn = sn;1658 1659 skb_queue_walk(queue, skb) {1660 tx_info = rtl_tx_skb_cb_info(skb);1661 if (tx_info->sn == sn) {1662 skb_unlink(skb, queue);1663 rtl_tx_status(hw, skb, st == 0);1664 break;1665 }1666 }1667 rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG,1668 "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n",1669 st, sn, retry);1670}1671EXPORT_SYMBOL_GPL(rtl_tx_report_handler);1672 1673bool rtl_check_tx_report_acked(struct ieee80211_hw *hw)1674{1675 struct rtl_priv *rtlpriv = rtl_priv(hw);1676 struct rtl_tx_report *tx_report = &rtlpriv->tx_report;1677 1678 if (tx_report->last_sent_sn == tx_report->last_recv_sn)1679 return true;1680 1681 if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) {1682 rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_WARNING,1683 "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n",1684 tx_report->last_sent_sn, tx_report->last_recv_sn);1685 return true; /* 3 sec. (timeout) seen as acked */1686 }1687 1688 return false;1689}1690 1691void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms)1692{1693 struct rtl_priv *rtlpriv = rtl_priv(hw);1694 int i;1695 1696 for (i = 0; i < wait_ms; i++) {1697 if (rtl_check_tx_report_acked(hw))1698 break;1699 usleep_range(1000, 2000);1700 rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,1701 "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms);1702 }1703}1704 1705u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw,1706 struct ieee80211_vif *vif,1707 enum wireless_mode wirelessmode,1708 struct ieee80211_tx_queue_params *param)1709{1710 u32 reg = 0;1711 u8 sifstime = 10;1712 u8 slottime = 20;1713 1714 /* AIFS = AIFSN * slot time + SIFS */1715 switch (wirelessmode) {1716 case WIRELESS_MODE_A:1717 case WIRELESS_MODE_N_24G:1718 case WIRELESS_MODE_N_5G:1719 case WIRELESS_MODE_AC_5G:1720 case WIRELESS_MODE_AC_24G:1721 sifstime = 16;1722 slottime = 9;1723 break;1724 case WIRELESS_MODE_G:1725 slottime = (vif->bss_conf.use_short_slot ? 9 : 20);1726 break;1727 default:1728 break;1729 }1730 1731 reg |= (param->txop & 0x7FF) << 16;1732 reg |= (fls(param->cw_max) & 0xF) << 12;1733 reg |= (fls(param->cw_min) & 0xF) << 8;1734 reg |= (param->aifs & 0x0F) * slottime + sifstime;1735 1736 return reg;1737}1738EXPORT_SYMBOL_GPL(rtl_get_hal_edca_param);1739 1740/*********************************************************1741 *1742 * functions called by core.c1743 *1744 *********************************************************/1745int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1746 struct ieee80211_sta *sta, u16 tid, u16 *ssn)1747{1748 struct rtl_priv *rtlpriv = rtl_priv(hw);1749 struct rtl_tid_data *tid_data;1750 struct rtl_sta_info *sta_entry = NULL;1751 1752 if (sta == NULL)1753 return -EINVAL;1754 1755 if (unlikely(tid >= MAX_TID_COUNT))1756 return -EINVAL;1757 1758 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1759 tid_data = &sta_entry->tids[tid];1760 1761 rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG,1762 "on ra = %pM tid = %d seq:%d\n", sta->addr, tid,1763 *ssn);1764 1765 tid_data->agg.agg_state = RTL_AGG_START;1766 1767 return IEEE80211_AMPDU_TX_START_IMMEDIATE;1768}1769 1770int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1771 struct ieee80211_sta *sta, u16 tid)1772{1773 struct rtl_priv *rtlpriv = rtl_priv(hw);1774 struct rtl_sta_info *sta_entry = NULL;1775 1776 if (sta == NULL)1777 return -EINVAL;1778 1779 rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG,1780 "on ra = %pM tid = %d\n", sta->addr, tid);1781 1782 if (unlikely(tid >= MAX_TID_COUNT))1783 return -EINVAL;1784 1785 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1786 sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;1787 1788 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);1789 return 0;1790}1791 1792int rtl_rx_agg_start(struct ieee80211_hw *hw,1793 struct ieee80211_sta *sta, u16 tid)1794{1795 struct rtl_priv *rtlpriv = rtl_priv(hw);1796 struct rtl_tid_data *tid_data;1797 struct rtl_sta_info *sta_entry = NULL;1798 u8 reject_agg;1799 1800 if (sta == NULL)1801 return -EINVAL;1802 1803 if (unlikely(tid >= MAX_TID_COUNT))1804 return -EINVAL;1805 1806 if (rtlpriv->cfg->ops->get_btc_status()) {1807 rtlpriv->btcoexist.btc_ops->btc_get_ampdu_cfg(rtlpriv,1808 &reject_agg,1809 NULL, NULL);1810 if (reject_agg)1811 return -EINVAL;1812 }1813 1814 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1815 tid_data = &sta_entry->tids[tid];1816 1817 rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG,1818 "on ra = %pM tid = %d\n", sta->addr, tid);1819 1820 tid_data->agg.rx_agg_state = RTL_RX_AGG_START;1821 return 0;1822}1823 1824int rtl_rx_agg_stop(struct ieee80211_hw *hw,1825 struct ieee80211_sta *sta, u16 tid)1826{1827 struct rtl_priv *rtlpriv = rtl_priv(hw);1828 struct rtl_sta_info *sta_entry = NULL;1829 1830 if (sta == NULL)1831 return -EINVAL;1832 1833 rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG,1834 "on ra = %pM tid = %d\n", sta->addr, tid);1835 1836 if (unlikely(tid >= MAX_TID_COUNT))1837 return -EINVAL;1838 1839 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1840 sta_entry->tids[tid].agg.rx_agg_state = RTL_RX_AGG_STOP;1841 1842 return 0;1843}1844 1845int rtl_tx_agg_oper(struct ieee80211_hw *hw,1846 struct ieee80211_sta *sta, u16 tid)1847{1848 struct rtl_priv *rtlpriv = rtl_priv(hw);1849 struct rtl_sta_info *sta_entry = NULL;1850 1851 if (sta == NULL)1852 return -EINVAL;1853 1854 rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG,1855 "on ra = %pM tid = %d\n", sta->addr, tid);1856 1857 if (unlikely(tid >= MAX_TID_COUNT))1858 return -EINVAL;1859 1860 sta_entry = (struct rtl_sta_info *)sta->drv_priv;1861 sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;1862 1863 return 0;1864}1865 1866void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv)1867{1868 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;1869 u8 reject_agg = 0, ctrl_agg_size = 0, agg_size = 0;1870 1871 if (rtlpriv->cfg->ops->get_btc_status())1872 btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg,1873 &ctrl_agg_size, &agg_size);1874 1875 rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,1876 "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d",1877 reject_agg, ctrl_agg_size, agg_size);1878 1879 rtlpriv->hw->max_rx_aggregation_subframes =1880 (ctrl_agg_size ? agg_size : IEEE80211_MAX_AMPDU_BUF_HT);1881}1882EXPORT_SYMBOL(rtl_rx_ampdu_apply);1883 1884/*********************************************************1885 *1886 * wq & timer callback functions1887 *1888 *********************************************************/1889/* this function is used for roaming */1890void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)1891{1892 struct rtl_priv *rtlpriv = rtl_priv(hw);1893 struct ieee80211_hdr *hdr = rtl_get_hdr(skb);1894 1895 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)1896 return;1897 1898 if (rtlpriv->mac80211.link_state < MAC80211_LINKED)1899 return;1900 1901 /* check if this really is a beacon */1902 if (!ieee80211_is_beacon(hdr->frame_control) &&1903 !ieee80211_is_probe_resp(hdr->frame_control))1904 return;1905 1906 /* min. beacon length + FCS_LEN */1907 if (skb->len <= 40 + FCS_LEN)1908 return;1909 1910 /* and only beacons from the associated BSSID, please */1911 if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))1912 return;1913 1914 rtlpriv->link_info.bcn_rx_inperiod++;1915}1916EXPORT_SYMBOL_GPL(rtl_beacon_statistic);1917 1918static void rtl_free_entries_from_scan_list(struct ieee80211_hw *hw)1919{1920 struct rtl_priv *rtlpriv = rtl_priv(hw);1921 struct rtl_bssid_entry *entry, *next;1922 1923 list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {1924 list_del(&entry->list);1925 kfree(entry);1926 rtlpriv->scan_list.num--;1927 }1928}1929 1930static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,1931 bool chk_timeout)1932{1933 struct rtl_priv *rtlpriv = rtl_priv(hw);1934 struct rtl_tx_report *tx_report = &rtlpriv->tx_report;1935 struct sk_buff_head *queue = &tx_report->queue;1936 struct sk_buff *skb, *tmp;1937 struct rtlwifi_tx_info *tx_info;1938 1939 skb_queue_walk_safe(queue, skb, tmp) {1940 tx_info = rtl_tx_skb_cb_info(skb);1941 if (chk_timeout &&1942 time_after(tx_info->send_time + HZ, jiffies))1943 continue;1944 skb_unlink(skb, queue);1945 rtl_tx_status(hw, skb, false);1946 }1947}1948 1949void rtl_scan_list_expire(struct ieee80211_hw *hw)1950{1951 struct rtl_priv *rtlpriv = rtl_priv(hw);1952 struct rtl_bssid_entry *entry, *next;1953 unsigned long flags;1954 1955 spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);1956 1957 list_for_each_entry_safe(entry, next, &rtlpriv->scan_list.list, list) {1958 /* 180 seconds */1959 if (jiffies_to_msecs(jiffies - entry->age) < 180000)1960 continue;1961 1962 list_del(&entry->list);1963 rtlpriv->scan_list.num--;1964 1965 rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,1966 "BSSID=%pM is expire in scan list (total=%d)\n",1967 entry->bssid, rtlpriv->scan_list.num);1968 kfree(entry);1969 }1970 1971 spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);1972 1973 rtlpriv->btcoexist.btc_info.ap_num = rtlpriv->scan_list.num;1974}1975 1976void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb)1977{1978 struct rtl_priv *rtlpriv = rtl_priv(hw);1979 struct ieee80211_hdr *hdr = rtl_get_hdr(skb);1980 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1981 unsigned long flags;1982 1983 struct rtl_bssid_entry *entry = NULL, *iter;1984 1985 /* check if it is scanning */1986 if (!mac->act_scanning)1987 return;1988 1989 /* check if this really is a beacon */1990 if (!ieee80211_is_beacon(hdr->frame_control) &&1991 !ieee80211_is_probe_resp(hdr->frame_control))1992 return;1993 1994 spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags);1995 1996 list_for_each_entry(iter, &rtlpriv->scan_list.list, list) {1997 if (memcmp(iter->bssid, hdr->addr3, ETH_ALEN) == 0) {1998 list_del_init(&iter->list);1999 entry = iter;2000 rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,2001 "Update BSSID=%pM to scan list (total=%d)\n",2002 hdr->addr3, rtlpriv->scan_list.num);2003 break;2004 }2005 }2006 2007 if (!entry) {2008 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);2009 2010 if (!entry)2011 goto label_err;2012 2013 memcpy(entry->bssid, hdr->addr3, ETH_ALEN);2014 rtlpriv->scan_list.num++;2015 2016 rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,2017 "Add BSSID=%pM to scan list (total=%d)\n",2018 hdr->addr3, rtlpriv->scan_list.num);2019 }2020 2021 entry->age = jiffies;2022 2023 list_add_tail(&entry->list, &rtlpriv->scan_list.list);2024 2025label_err:2026 spin_unlock_irqrestore(&rtlpriv->locks.scan_list_lock, flags);2027}2028EXPORT_SYMBOL(rtl_collect_scan_list);2029 2030static void rtl_watchdog_wq_callback(struct work_struct *work)2031{2032 struct rtl_works *rtlworks = container_of(work, struct rtl_works,2033 watchdog_wq.work);2034 struct ieee80211_hw *hw = rtlworks->hw;2035 struct rtl_priv *rtlpriv = rtl_priv(hw);2036 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));2037 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));2038 bool busytraffic = false;2039 bool tx_busy_traffic = false;2040 bool rx_busy_traffic = false;2041 bool higher_busytraffic = false;2042 bool higher_busyrxtraffic = false;2043 u8 idx, tid;2044 u32 rx_cnt_inp4eriod = 0;2045 u32 tx_cnt_inp4eriod = 0;2046 u32 aver_rx_cnt_inperiod = 0;2047 u32 aver_tx_cnt_inperiod = 0;2048 u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};2049 u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};2050 2051 if (is_hal_stop(rtlhal))2052 return;2053 2054 /* <1> Determine if action frame is allowed */2055 if (mac->link_state > MAC80211_NOLINK) {2056 if (mac->cnt_after_linked < 20)2057 mac->cnt_after_linked++;2058 } else {2059 mac->cnt_after_linked = 0;2060 }2061 2062 /* <2> to check if traffic busy, if2063 * busytraffic we don't change channel2064 */2065 if (mac->link_state >= MAC80211_LINKED) {2066 /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */2067 for (idx = 0; idx <= 2; idx++) {2068 rtlpriv->link_info.num_rx_in4period[idx] =2069 rtlpriv->link_info.num_rx_in4period[idx + 1];2070 rtlpriv->link_info.num_tx_in4period[idx] =2071 rtlpriv->link_info.num_tx_in4period[idx + 1];2072 }2073 rtlpriv->link_info.num_rx_in4period[3] =2074 rtlpriv->link_info.num_rx_inperiod;2075 rtlpriv->link_info.num_tx_in4period[3] =2076 rtlpriv->link_info.num_tx_inperiod;2077 for (idx = 0; idx <= 3; idx++) {2078 rx_cnt_inp4eriod +=2079 rtlpriv->link_info.num_rx_in4period[idx];2080 tx_cnt_inp4eriod +=2081 rtlpriv->link_info.num_tx_in4period[idx];2082 }2083 aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;2084 aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;2085 2086 /* (2) check traffic busy */2087 if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) {2088 busytraffic = true;2089 if (aver_rx_cnt_inperiod > aver_tx_cnt_inperiod)2090 rx_busy_traffic = true;2091 else2092 tx_busy_traffic = false;2093 }2094 2095 /* Higher Tx/Rx data. */2096 if (aver_rx_cnt_inperiod > 4000 ||2097 aver_tx_cnt_inperiod > 4000) {2098 higher_busytraffic = true;2099 2100 /* Extremely high Rx data. */2101 if (aver_rx_cnt_inperiod > 5000)2102 higher_busyrxtraffic = true;2103 }2104 2105 /* check every tid's tx traffic */2106 for (tid = 0; tid <= 7; tid++) {2107 for (idx = 0; idx <= 2; idx++)2108 rtlpriv->link_info.tidtx_in4period[tid][idx] =2109 rtlpriv->link_info.tidtx_in4period[tid]2110 [idx + 1];2111 rtlpriv->link_info.tidtx_in4period[tid][3] =2112 rtlpriv->link_info.tidtx_inperiod[tid];2113 2114 for (idx = 0; idx <= 3; idx++)2115 tidtx_inp4eriod[tid] +=2116 rtlpriv->link_info.tidtx_in4period[tid][idx];2117 aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;2118 if (aver_tidtx_inperiod[tid] > 5000)2119 rtlpriv->link_info.higher_busytxtraffic[tid] =2120 true;2121 else2122 rtlpriv->link_info.higher_busytxtraffic[tid] =2123 false;2124 }2125 2126 /* PS is controlled by coex. */2127 if (rtlpriv->cfg->ops->get_btc_status() &&2128 rtlpriv->btcoexist.btc_ops->btc_is_bt_ctrl_lps(rtlpriv))2129 goto label_lps_done;2130 2131 if (rtlpriv->link_info.num_rx_inperiod +2132 rtlpriv->link_info.num_tx_inperiod > 8 ||2133 rtlpriv->link_info.num_rx_inperiod > 2)2134 rtl_lps_leave(hw, true);2135 else2136 rtl_lps_enter(hw, true);2137 2138label_lps_done:2139 ;2140 }2141 2142 for (tid = 0; tid <= 7; tid++)2143 rtlpriv->link_info.tidtx_inperiod[tid] = 0;2144 2145 rtlpriv->link_info.busytraffic = busytraffic;2146 rtlpriv->link_info.higher_busytraffic = higher_busytraffic;2147 rtlpriv->link_info.rx_busy_traffic = rx_busy_traffic;2148 rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic;2149 rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;2150 2151 rtlpriv->stats.txbytesunicast_inperiod =2152 rtlpriv->stats.txbytesunicast -2153 rtlpriv->stats.txbytesunicast_last;2154 rtlpriv->stats.rxbytesunicast_inperiod =2155 rtlpriv->stats.rxbytesunicast -2156 rtlpriv->stats.rxbytesunicast_last;2157 rtlpriv->stats.txbytesunicast_last = rtlpriv->stats.txbytesunicast;2158 rtlpriv->stats.rxbytesunicast_last = rtlpriv->stats.rxbytesunicast;2159 2160 rtlpriv->stats.txbytesunicast_inperiod_tp =2161 (u32)(rtlpriv->stats.txbytesunicast_inperiod * 8 / 2 /2162 1024 / 1024);2163 rtlpriv->stats.rxbytesunicast_inperiod_tp =2164 (u32)(rtlpriv->stats.rxbytesunicast_inperiod * 8 / 2 /2165 1024 / 1024);2166 2167 /* <3> DM */2168 if (!rtlpriv->cfg->mod_params->disable_watchdog)2169 rtlpriv->cfg->ops->dm_watchdog(hw);2170 2171 /* <4> roaming */2172 if (mac->link_state == MAC80211_LINKED &&2173 mac->opmode == NL80211_IFTYPE_STATION) {2174 if ((rtlpriv->link_info.bcn_rx_inperiod +2175 rtlpriv->link_info.num_rx_inperiod) == 0) {2176 rtlpriv->link_info.roam_times++;2177 rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,2178 "AP off for %d s\n",2179 (rtlpriv->link_info.roam_times * 2));2180 2181 /* if we can't recv beacon for 10s,2182 * we should reconnect this AP2183 */2184 if (rtlpriv->link_info.roam_times >= 5) {2185 pr_err("AP off, try to reconnect now\n");2186 rtlpriv->link_info.roam_times = 0;2187 ieee80211_connection_loss(2188 rtlpriv->mac80211.vif);2189 }2190 } else {2191 rtlpriv->link_info.roam_times = 0;2192 }2193 }2194 2195 if (rtlpriv->cfg->ops->get_btc_status())2196 rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);2197 2198 if (rtlpriv->btcoexist.btc_info.in_4way) {2199 if (time_after(jiffies, rtlpriv->btcoexist.btc_info.in_4way_ts +2200 msecs_to_jiffies(IN_4WAY_TIMEOUT_TIME)))2201 rtlpriv->btcoexist.btc_info.in_4way = false;2202 }2203 2204 rtlpriv->link_info.num_rx_inperiod = 0;2205 rtlpriv->link_info.num_tx_inperiod = 0;2206 rtlpriv->link_info.bcn_rx_inperiod = 0;2207 2208 /* <6> scan list */2209 rtl_scan_list_expire(hw);2210 2211 /* <7> check ack queue */2212 rtl_free_entries_from_ack_queue(hw, true);2213}2214 2215void rtl_watch_dog_timer_callback(struct timer_list *t)2216{2217 struct rtl_priv *rtlpriv = from_timer(rtlpriv, t, works.watchdog_timer);2218 2219 queue_delayed_work(rtlpriv->works.rtl_wq,2220 &rtlpriv->works.watchdog_wq, 0);2221 2222 mod_timer(&rtlpriv->works.watchdog_timer,2223 jiffies + MSECS(RTL_WATCH_DOG_TIME));2224}2225 2226static void rtl_fwevt_wq_callback(struct work_struct *work)2227{2228 struct rtl_works *rtlworks = container_of(work, struct rtl_works,2229 fwevt_wq.work);2230 struct ieee80211_hw *hw = rtlworks->hw;2231 struct rtl_priv *rtlpriv = rtl_priv(hw);2232 2233 rtlpriv->cfg->ops->c2h_command_handle(hw);2234}2235 2236static void rtl_c2h_content_parsing(struct ieee80211_hw *hw,2237 struct sk_buff *skb);2238 2239static bool rtl_c2h_fast_cmd(struct ieee80211_hw *hw, struct sk_buff *skb)2240{2241 u8 cmd_id = GET_C2H_CMD_ID(skb->data);2242 2243 switch (cmd_id) {2244 case C2H_BT_MP:2245 return true;2246 default:2247 break;2248 }2249 2250 return false;2251}2252 2253void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb)2254{2255 struct rtl_priv *rtlpriv = rtl_priv(hw);2256 2257 if (rtl_c2h_fast_cmd(hw, skb)) {2258 rtl_c2h_content_parsing(hw, skb);2259 kfree_skb(skb);2260 return;2261 }2262 2263 /* enqueue */2264 skb_queue_tail(&rtlpriv->c2hcmd_queue, skb);2265 2266 /* wake up wq */2267 queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.c2hcmd_wq, 0);2268}2269EXPORT_SYMBOL(rtl_c2hcmd_enqueue);2270 2271static void rtl_c2h_content_parsing(struct ieee80211_hw *hw,2272 struct sk_buff *skb)2273{2274 struct rtl_priv *rtlpriv = rtl_priv(hw);2275 const struct rtl_hal_ops *hal_ops = rtlpriv->cfg->ops;2276 const struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;2277 u8 cmd_id, cmd_len;2278 u8 *cmd_buf = NULL;2279 2280 cmd_id = GET_C2H_CMD_ID(skb->data);2281 cmd_len = skb->len - C2H_DATA_OFFSET;2282 cmd_buf = GET_C2H_DATA_PTR(skb->data);2283 2284 switch (cmd_id) {2285 case C2H_DBG:2286 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n");2287 break;2288 case C2H_TXBF:2289 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE,2290 "[C2H], C2H_TXBF!!\n");2291 break;2292 case C2H_TX_REPORT:2293 rtl_tx_report_handler(hw, cmd_buf, cmd_len);2294 break;2295 case C2H_RA_RPT:2296 if (hal_ops->c2h_ra_report_handler)2297 hal_ops->c2h_ra_report_handler(hw, cmd_buf, cmd_len);2298 break;2299 case C2H_BT_INFO:2300 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE,2301 "[C2H], C2H_BT_INFO!!\n");2302 if (rtlpriv->cfg->ops->get_btc_status())2303 btc_ops->btc_btinfo_notify(rtlpriv, cmd_buf, cmd_len);2304 break;2305 case C2H_BT_MP:2306 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE,2307 "[C2H], C2H_BT_MP!!\n");2308 if (rtlpriv->cfg->ops->get_btc_status())2309 btc_ops->btc_btmpinfo_notify(rtlpriv, cmd_buf, cmd_len);2310 break;2311 default:2312 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE,2313 "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id);2314 break;2315 }2316}2317 2318void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec)2319{2320 struct rtl_priv *rtlpriv = rtl_priv(hw);2321 struct sk_buff *skb;2322 int i;2323 2324 for (i = 0; i < 200; i++) {2325 /* dequeue a task */2326 skb = skb_dequeue(&rtlpriv->c2hcmd_queue);2327 2328 /* do it */2329 if (!skb)2330 break;2331 2332 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n",2333 *((u8 *)skb->cb));2334 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG,2335 "C2H data: ", skb->data, skb->len);2336 2337 if (exec)2338 rtl_c2h_content_parsing(hw, skb);2339 2340 /* free */2341 dev_kfree_skb_any(skb);2342 }2343}2344 2345static void rtl_c2hcmd_wq_callback(struct work_struct *work)2346{2347 struct rtl_works *rtlworks = container_of(work, struct rtl_works,2348 c2hcmd_wq.work);2349 struct ieee80211_hw *hw = rtlworks->hw;2350 2351 rtl_c2hcmd_launcher(hw, 1);2352}2353 2354/*********************************************************2355 *2356 * frame process functions2357 *2358 *********************************************************/2359u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)2360{2361 struct ieee80211_mgmt *mgmt = (void *)data;2362 u8 *pos, *end;2363 2364 pos = (u8 *)mgmt->u.beacon.variable;2365 end = data + len;2366 while (pos < end) {2367 if (pos + 2 + pos[1] > end)2368 return NULL;2369 2370 if (pos[0] == ie)2371 return pos;2372 2373 pos += 2 + pos[1];2374 }2375 return NULL;2376}2377 2378/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */2379/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */2380static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,2381 enum ieee80211_smps_mode smps,2382 u8 *da, u8 *bssid)2383{2384 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));2385 struct sk_buff *skb;2386 struct ieee80211_mgmt *action_frame;2387 2388 /* 27 = header + category + action + smps mode */2389 skb = dev_alloc_skb(27 + hw->extra_tx_headroom);2390 if (!skb)2391 return NULL;2392 2393 skb_reserve(skb, hw->extra_tx_headroom);2394 action_frame = skb_put_zero(skb, 27);2395 memcpy(action_frame->da, da, ETH_ALEN);2396 memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);2397 memcpy(action_frame->bssid, bssid, ETH_ALEN);2398 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |2399 IEEE80211_STYPE_ACTION);2400 action_frame->u.action.category = WLAN_CATEGORY_HT;2401 action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;2402 switch (smps) {2403 case IEEE80211_SMPS_AUTOMATIC:/* 0 */2404 case IEEE80211_SMPS_NUM_MODES:/* 4 */2405 WARN_ON(1);2406 fallthrough;2407 case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/2408 action_frame->u.action.u.ht_smps.smps_control =2409 WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */2410 break;2411 case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/2412 action_frame->u.action.u.ht_smps.smps_control =2413 WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */2414 break;2415 case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/2416 action_frame->u.action.u.ht_smps.smps_control =2417 WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */2418 break;2419 }2420 2421 return skb;2422}2423 2424int rtl_send_smps_action(struct ieee80211_hw *hw,2425 struct ieee80211_sta *sta,2426 enum ieee80211_smps_mode smps)2427{2428 struct rtl_priv *rtlpriv = rtl_priv(hw);2429 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));2430 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));2431 struct sk_buff *skb = NULL;2432 struct rtl_tcb_desc tcb_desc;2433 u8 bssid[ETH_ALEN] = {0};2434 2435 memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));2436 2437 if (rtlpriv->mac80211.act_scanning)2438 goto err_free;2439 2440 if (!sta)2441 goto err_free;2442 2443 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))2444 goto err_free;2445 2446 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))2447 goto err_free;2448 2449 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP)2450 memcpy(bssid, rtlpriv->efuse.dev_addr, ETH_ALEN);2451 else2452 memcpy(bssid, rtlpriv->mac80211.bssid, ETH_ALEN);2453 2454 skb = rtl_make_smps_action(hw, smps, sta->addr, bssid);2455 /* this is a type = mgmt * stype = action frame */2456 if (skb) {2457 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);2458 struct rtl_sta_info *sta_entry =2459 (struct rtl_sta_info *) sta->drv_priv;2460 sta_entry->mimo_ps = smps;2461 /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); */2462 2463 info->control.rates[0].idx = 0;2464 info->band = hw->conf.chandef.chan->band;2465 rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc);2466 }2467 return 1;2468 2469err_free:2470 return 0;2471}2472EXPORT_SYMBOL(rtl_send_smps_action);2473 2474void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)2475{2476 struct rtl_priv *rtlpriv = rtl_priv(hw);2477 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));2478 enum io_type iotype;2479 2480 if (!is_hal_stop(rtlhal)) {2481 switch (operation) {2482 case SCAN_OPT_BACKUP:2483 iotype = IO_CMD_PAUSE_DM_BY_SCAN;2484 rtlpriv->cfg->ops->set_hw_reg(hw,2485 HW_VAR_IO_CMD,2486 (u8 *)&iotype);2487 break;2488 case SCAN_OPT_RESTORE:2489 iotype = IO_CMD_RESUME_DM_BY_SCAN;2490 rtlpriv->cfg->ops->set_hw_reg(hw,2491 HW_VAR_IO_CMD,2492 (u8 *)&iotype);2493 break;2494 default:2495 pr_err("Unknown Scan Backup operation.\n");2496 break;2497 }2498 }2499}2500EXPORT_SYMBOL(rtl_phy_scan_operation_backup);2501 2502/* because mac80211 have issues when can receive del ba2503 * so here we just make a fake del_ba if we receive a ba_req2504 * but rx_agg was opened to let mac80211 release some ba2505 * related resources, so please this del_ba for tx2506 */2507struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,2508 u8 *sa, u8 *bssid, u16 tid)2509{2510 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));2511 struct sk_buff *skb;2512 struct ieee80211_mgmt *action_frame;2513 u16 params;2514 2515 /* 27 = header + category + action + smps mode */2516 skb = dev_alloc_skb(34 + hw->extra_tx_headroom);2517 if (!skb)2518 return NULL;2519 2520 skb_reserve(skb, hw->extra_tx_headroom);2521 action_frame = skb_put_zero(skb, 34);2522 memcpy(action_frame->sa, sa, ETH_ALEN);2523 memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN);2524 memcpy(action_frame->bssid, bssid, ETH_ALEN);2525 action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |2526 IEEE80211_STYPE_ACTION);2527 action_frame->u.action.category = WLAN_CATEGORY_BACK;2528 action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA;2529 params = (u16)(1 << 11); /* bit 11 initiator */2530 params |= (u16)(tid << 12); /* bit 15:12 TID number */2531 2532 action_frame->u.action.u.delba.params = cpu_to_le16(params);2533 action_frame->u.action.u.delba.reason_code =2534 cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);2535 2536 return skb;2537}2538 2539/*********************************************************2540 *2541 * IOT functions2542 *2543 *********************************************************/2544static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,2545 struct octet_string vendor_ie)2546{2547 struct rtl_priv *rtlpriv = rtl_priv(hw);2548 bool matched = false;2549 static u8 athcap_1[] = { 0x00, 0x03, 0x7F };2550 static u8 athcap_2[] = { 0x00, 0x13, 0x74 };2551 static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };2552 static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };2553 static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };2554 static u8 racap[] = { 0x00, 0x0c, 0x43 };2555 static u8 ciscocap[] = { 0x00, 0x40, 0x96 };2556 static u8 marvcap[] = { 0x00, 0x50, 0x43 };2557 2558 if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||2559 memcmp(vendor_ie.octet, athcap_2, 3) == 0) {2560 rtlpriv->mac80211.vendor = PEER_ATH;2561 matched = true;2562 } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||2563 memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||2564 memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {2565 rtlpriv->mac80211.vendor = PEER_BROAD;2566 matched = true;2567 } else if (memcmp(vendor_ie.octet, racap, 3) == 0) {2568 rtlpriv->mac80211.vendor = PEER_RAL;2569 matched = true;2570 } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {2571 rtlpriv->mac80211.vendor = PEER_CISCO;2572 matched = true;2573 } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {2574 rtlpriv->mac80211.vendor = PEER_MARV;2575 matched = true;2576 }2577 2578 return matched;2579}2580 2581static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,2582 unsigned int len)2583{2584 struct ieee80211_mgmt *mgmt = (void *)data;2585 struct octet_string vendor_ie;2586 u8 *pos, *end;2587 2588 pos = (u8 *)mgmt->u.beacon.variable;2589 end = data + len;2590 while (pos < end) {2591 if (pos[0] == 221) {2592 vendor_ie.length = pos[1];2593 vendor_ie.octet = &pos[2];2594 if (rtl_chk_vendor_ouisub(hw, vendor_ie))2595 return true;2596 }2597 2598 if (pos + 2 + pos[1] > end)2599 return false;2600 2601 pos += 2 + pos[1];2602 }2603 return false;2604}2605 2606void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)2607{2608 struct rtl_priv *rtlpriv = rtl_priv(hw);2609 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));2610 struct ieee80211_hdr *hdr = (void *)data;2611 u32 vendor = PEER_UNKNOWN;2612 2613 static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };2614 static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };2615 static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };2616 static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };2617 static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };2618 static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };2619 static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };2620 static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };2621 static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };2622 static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };2623 static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };2624 static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };2625 static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };2626 static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };2627 static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };2628 static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };2629 2630 if (mac->opmode != NL80211_IFTYPE_STATION)2631 return;2632 2633 if (mac->link_state == MAC80211_NOLINK) {2634 mac->vendor = PEER_UNKNOWN;2635 return;2636 }2637 2638 if (mac->cnt_after_linked > 2)2639 return;2640 2641 /* check if this really is a beacon */2642 if (!ieee80211_is_beacon(hdr->frame_control))2643 return;2644 2645 /* min. beacon length + FCS_LEN */2646 if (len <= 40 + FCS_LEN)2647 return;2648 2649 /* and only beacons from the associated BSSID, please */2650 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))2651 return;2652 2653 if (rtl_find_221_ie(hw, data, len))2654 vendor = mac->vendor;2655 2656 if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||2657 (memcmp(mac->bssid, ap5_2, 3) == 0) ||2658 (memcmp(mac->bssid, ap5_3, 3) == 0) ||2659 (memcmp(mac->bssid, ap5_4, 3) == 0) ||2660 (memcmp(mac->bssid, ap5_5, 3) == 0) ||2661 (memcmp(mac->bssid, ap5_6, 3) == 0) ||2662 vendor == PEER_ATH) {2663 vendor = PEER_ATH;2664 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n");2665 } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||2666 (memcmp(mac->bssid, ap4_5, 3) == 0) ||2667 (memcmp(mac->bssid, ap4_1, 3) == 0) ||2668 (memcmp(mac->bssid, ap4_2, 3) == 0) ||2669 (memcmp(mac->bssid, ap4_3, 3) == 0) ||2670 vendor == PEER_RAL) {2671 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n");2672 vendor = PEER_RAL;2673 } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||2674 vendor == PEER_CISCO) {2675 vendor = PEER_CISCO;2676 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n");2677 } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||2678 (memcmp(mac->bssid, ap3_2, 3) == 0) ||2679 (memcmp(mac->bssid, ap3_3, 3) == 0) ||2680 vendor == PEER_BROAD) {2681 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n");2682 vendor = PEER_BROAD;2683 } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||2684 vendor == PEER_MARV) {2685 vendor = PEER_MARV;2686 rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n");2687 }2688 2689 mac->vendor = vendor;2690}2691EXPORT_SYMBOL_GPL(rtl_recognize_peer);2692 2693MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");2694MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");2695MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");2696MODULE_LICENSE("GPL");2697MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");2698 2699struct rtl_global_var rtl_global_var = {};2700EXPORT_SYMBOL_GPL(rtl_global_var);2701 2702static int __init rtl_core_module_init(void)2703{2704 BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION);2705 BUILD_BUG_ON(MAX_RATE_SECTION_NUM != MAX_RATE_SECTION);2706 BUILD_BUG_ON(MAX_BASE_NUM_IN_PHY_REG_PG_24G != MAX_RATE_SECTION);2707 BUILD_BUG_ON(MAX_BASE_NUM_IN_PHY_REG_PG_5G != (MAX_RATE_SECTION - 1));2708 2709 if (rtl_rate_control_register())2710 pr_err("rtl: Unable to register rtl_rc, use default RC !!\n");2711 2712 /* add debugfs */2713 rtl_debugfs_add_topdir();2714 2715 /* init some global vars */2716 INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);2717 spin_lock_init(&rtl_global_var.glb_list_lock);2718 2719 return 0;2720}2721 2722static void __exit rtl_core_module_exit(void)2723{2724 /*RC*/2725 rtl_rate_control_unregister();2726 2727 /* remove debugfs */2728 rtl_debugfs_remove_topdir();2729}2730 2731module_init(rtl_core_module_init);2732module_exit(rtl_core_module_exit);2733