brintos

brintos / linux-shallow public Read only

0
0
Text · 73.3 KiB · aab4605 Raw
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