Linux Audio

Check our new training course

Loading...
v3.1
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2010  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 * The full GNU General Public License is included in this distribution in the
  19 * file called LICENSE.
  20 *
  21 * Contact Information:
  22 * wlanfae <wlanfae@realtek.com>
  23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24 * Hsinchu 300, Taiwan.
  25 *
  26 * Larry Finger <Larry.Finger@lwfinger.net>
  27 *
  28 *****************************************************************************/
  29
  30#include "../wifi.h"
  31#include "../pci.h"
  32#include "../base.h"
 
  33#include "reg.h"
  34#include "def.h"
  35#include "phy.h"
  36#include "trx.h"
  37#include "led.h"
  38
  39static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
  40{
  41	__le16 fc = rtl_get_fc(skb);
  42
  43	if (unlikely(ieee80211_is_beacon(fc)))
  44		return QSLT_BEACON;
  45	if (ieee80211_is_mgmt(fc))
  46		return QSLT_MGNT;
  47
  48	return skb->priority;
  49}
  50
  51static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
  52{
  53	int rate_idx;
  54
  55	if (first_ampdu) {
  56		if (false == isht) {
  57			switch (desc_rate) {
  58			case DESC92C_RATE1M:
  59				rate_idx = 0;
  60				break;
  61			case DESC92C_RATE2M:
  62				rate_idx = 1;
  63				break;
  64			case DESC92C_RATE5_5M:
  65				rate_idx = 2;
  66				break;
  67			case DESC92C_RATE11M:
  68				rate_idx = 3;
  69				break;
  70			case DESC92C_RATE6M:
  71				rate_idx = 4;
  72				break;
  73			case DESC92C_RATE9M:
  74				rate_idx = 5;
  75				break;
  76			case DESC92C_RATE12M:
  77				rate_idx = 6;
  78				break;
  79			case DESC92C_RATE18M:
  80				rate_idx = 7;
  81				break;
  82			case DESC92C_RATE24M:
  83				rate_idx = 8;
  84				break;
  85			case DESC92C_RATE36M:
  86				rate_idx = 9;
  87				break;
  88			case DESC92C_RATE48M:
  89				rate_idx = 10;
  90				break;
  91			case DESC92C_RATE54M:
  92				rate_idx = 11;
  93				break;
  94			default:
  95				rate_idx = 0;
  96				break;
  97			}
  98		} else {
  99			rate_idx = 11;
 100		}
 101
 102		return rate_idx;
 103	}
 104
 105	switch (desc_rate) {
 106	case DESC92C_RATE1M:
 107		rate_idx = 0;
 108		break;
 109	case DESC92C_RATE2M:
 110		rate_idx = 1;
 111		break;
 112	case DESC92C_RATE5_5M:
 113		rate_idx = 2;
 114		break;
 115	case DESC92C_RATE11M:
 116		rate_idx = 3;
 117		break;
 118	case DESC92C_RATE6M:
 119		rate_idx = 4;
 120		break;
 121	case DESC92C_RATE9M:
 122		rate_idx = 5;
 123		break;
 124	case DESC92C_RATE12M:
 125		rate_idx = 6;
 126		break;
 127	case DESC92C_RATE18M:
 128		rate_idx = 7;
 129		break;
 130	case DESC92C_RATE24M:
 131		rate_idx = 8;
 132		break;
 133	case DESC92C_RATE36M:
 134		rate_idx = 9;
 135		break;
 136	case DESC92C_RATE48M:
 137		rate_idx = 10;
 138		break;
 139	case DESC92C_RATE54M:
 140		rate_idx = 11;
 141		break;
 142	default:
 143		rate_idx = 11;
 144		break;
 145	}
 146	return rate_idx;
 147}
 148
 149static u8 _rtl92c_query_rxpwrpercentage(char antpower)
 150{
 151	if ((antpower <= -100) || (antpower >= 20))
 152		return 0;
 153	else if (antpower >= 0)
 154		return 100;
 155	else
 156		return 100 + antpower;
 157}
 158
 159static u8 _rtl92c_evm_db_to_percentage(char value)
 160{
 161	char ret_val;
 162	ret_val = value;
 163
 164	if (ret_val >= 0)
 165		ret_val = 0;
 166
 167	if (ret_val <= -33)
 168		ret_val = -33;
 169
 170	ret_val = 0 - ret_val;
 171	ret_val *= 3;
 172
 173	if (ret_val == 99)
 174		ret_val = 100;
 175
 176	return ret_val;
 177}
 178
 179static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
 180				     u8 signal_strength_index)
 181{
 182	long signal_power;
 183
 184	signal_power = (long)((signal_strength_index + 1) >> 1);
 185	signal_power -= 95;
 186	return signal_power;
 187}
 188
 189static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
 190		long currsig)
 191{
 192	long retsig;
 193
 194	if (currsig >= 61 && currsig <= 100)
 195		retsig = 90 + ((currsig - 60) / 4);
 196	else if (currsig >= 41 && currsig <= 60)
 197		retsig = 78 + ((currsig - 40) / 2);
 198	else if (currsig >= 31 && currsig <= 40)
 199		retsig = 66 + (currsig - 30);
 200	else if (currsig >= 21 && currsig <= 30)
 201		retsig = 54 + (currsig - 20);
 202	else if (currsig >= 5 && currsig <= 20)
 203		retsig = 42 + (((currsig - 5) * 2) / 3);
 204	else if (currsig == 4)
 205		retsig = 36;
 206	else if (currsig == 3)
 207		retsig = 27;
 208	else if (currsig == 2)
 209		retsig = 18;
 210	else if (currsig == 1)
 211		retsig = 9;
 212	else
 213		retsig = currsig;
 214
 215	return retsig;
 216}
 217
 218static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
 219				       struct rtl_stats *pstats,
 220				       struct rx_desc_92c *pdesc,
 221				       struct rx_fwinfo_92c *p_drvinfo,
 222				       bool packet_match_bssid,
 223				       bool packet_toself,
 224				       bool packet_beacon)
 225{
 226	struct rtl_priv *rtlpriv = rtl_priv(hw);
 227	struct phy_sts_cck_8192s_t *cck_buf;
 
 228	s8 rx_pwr_all = 0, rx_pwr[4];
 229	u8 evm, pwdb_all, rf_rx_num = 0;
 230	u8 i, max_spatial_stream;
 231	u32 rssi, total_rssi = 0;
 232	bool in_powersavemode = false;
 233	bool is_cck_rate;
 234
 235	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
 236	pstats->packet_matchbssid = packet_match_bssid;
 237	pstats->packet_toself = packet_toself;
 238	pstats->is_cck = is_cck_rate;
 239	pstats->packet_beacon = packet_beacon;
 240	pstats->is_cck = is_cck_rate;
 241	pstats->rx_mimo_signalquality[0] = -1;
 242	pstats->rx_mimo_signalquality[1] = -1;
 243
 244	if (is_cck_rate) {
 245		u8 report, cck_highpwr;
 246		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 247
 248		if (!in_powersavemode)
 249			cck_highpwr = (u8) rtl_get_bbreg(hw,
 250						 RFPGA0_XA_HSSIPARAMETER2,
 251						 BIT(9));
 252		else
 253			cck_highpwr = false;
 254
 255		if (!cck_highpwr) {
 256			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 257			report = cck_buf->cck_agc_rpt & 0xc0;
 258			report = report >> 6;
 259			switch (report) {
 260			case 0x3:
 261				rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
 262				break;
 263			case 0x2:
 264				rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
 265				break;
 266			case 0x1:
 267				rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
 268				break;
 269			case 0x0:
 270				rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
 271				break;
 272			}
 273		} else {
 274			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 275			report = p_drvinfo->cfosho[0] & 0x60;
 276			report = report >> 5;
 277			switch (report) {
 278			case 0x3:
 279				rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
 280				break;
 281			case 0x2:
 282				rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
 283				break;
 284			case 0x1:
 285				rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
 286				break;
 287			case 0x0:
 288				rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
 289				break;
 290			}
 291		}
 292
 293		pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 294		pstats->rx_pwdb_all = pwdb_all;
 295		pstats->recvsignalpower = rx_pwr_all;
 296
 
 297		if (packet_match_bssid) {
 298			u8 sq;
 299			if (pstats->rx_pwdb_all > 40)
 300				sq = 100;
 301			else {
 302				sq = cck_buf->sq_rpt;
 303				if (sq > 64)
 304					sq = 0;
 305				else if (sq < 20)
 306					sq = 100;
 307				else
 308					sq = ((64 - sq) * 100) / 44;
 309			}
 310
 311			pstats->signalquality = sq;
 312			pstats->rx_mimo_signalquality[0] = sq;
 313			pstats->rx_mimo_signalquality[1] = -1;
 314		}
 315	} else {
 316		rtlpriv->dm.rfpath_rxenable[0] =
 317		    rtlpriv->dm.rfpath_rxenable[1] = true;
 
 318		for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
 
 319			if (rtlpriv->dm.rfpath_rxenable[i])
 320				rf_rx_num++;
 321
 322			rx_pwr[i] =
 323			    ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
 
 324			rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
 325			total_rssi += rssi;
 
 326			rtlpriv->stats.rx_snr_db[i] =
 327			    (long)(p_drvinfo->rxsnr[i] / 2);
 328
 
 329			if (packet_match_bssid)
 330				pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 331		}
 332
 
 
 
 333		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 334		pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 335		pstats->rx_pwdb_all = pwdb_all;
 336		pstats->rxpower = rx_pwr_all;
 337		pstats->recvsignalpower = rx_pwr_all;
 338
 339		if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
 340		    pdesc->rxmcs <= DESC92C_RATEMCS15)
 
 341			max_spatial_stream = 2;
 342		else
 343			max_spatial_stream = 1;
 344
 345		for (i = 0; i < max_spatial_stream; i++) {
 346			evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 347
 348			if (packet_match_bssid) {
 
 
 
 349				if (i == 0)
 350					pstats->signalquality =
 351					    (u8) (evm & 0xff);
 352				pstats->rx_mimo_signalquality[i] =
 353				    (u8) (evm & 0xff);
 354			}
 355		}
 356	}
 357
 
 
 
 358	if (is_cck_rate)
 359		pstats->signalstrength =
 360		    (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
 361	else if (rf_rx_num != 0)
 362		pstats->signalstrength =
 363		    (u8) (_rtl92ce_signal_scale_mapping
 364			  (hw, total_rssi /= rf_rx_num));
 365}
 366
 367static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
 368		struct rtl_stats *pstats)
 369{
 370	struct rtl_priv *rtlpriv = rtl_priv(hw);
 371	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 372	u8 rfpath;
 373	u32 last_rssi, tmpval;
 374
 375	if (pstats->packet_toself || pstats->packet_beacon) {
 376		rtlpriv->stats.rssi_calculate_cnt++;
 377
 378		if (rtlpriv->stats.ui_rssi.total_num++ >=
 379		    PHY_RSSI_SLID_WIN_MAX) {
 380
 381			rtlpriv->stats.ui_rssi.total_num =
 382			    PHY_RSSI_SLID_WIN_MAX;
 383			last_rssi =
 384			    rtlpriv->stats.ui_rssi.elements[rtlpriv->
 385						    stats.ui_rssi.index];
 386			rtlpriv->stats.ui_rssi.total_val -= last_rssi;
 387		}
 388
 389		rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
 390		rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
 391						index++] =
 392		    pstats->signalstrength;
 393
 394		if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
 395			rtlpriv->stats.ui_rssi.index = 0;
 396
 397		tmpval = rtlpriv->stats.ui_rssi.total_val /
 398		    rtlpriv->stats.ui_rssi.total_num;
 399		rtlpriv->stats.signal_strength =
 400		    _rtl92ce_translate_todbm(hw, (u8) tmpval);
 401		pstats->rssi = rtlpriv->stats.signal_strength;
 402	}
 403
 404	if (!pstats->is_cck && pstats->packet_toself) {
 405		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
 406		     rfpath++) {
 407			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
 408				rtlpriv->stats.rx_rssi_percentage[rfpath] =
 409				    pstats->rx_mimo_signalstrength[rfpath];
 410
 411			}
 412
 413			if (pstats->rx_mimo_signalstrength[rfpath] >
 414			    rtlpriv->stats.rx_rssi_percentage[rfpath]) {
 415				rtlpriv->stats.rx_rssi_percentage[rfpath] =
 416				    ((rtlpriv->stats.
 417				      rx_rssi_percentage[rfpath] *
 418				      (RX_SMOOTH_FACTOR - 1)) +
 419				     (pstats->rx_mimo_signalstrength[rfpath])) /
 420				    (RX_SMOOTH_FACTOR);
 421
 422				rtlpriv->stats.rx_rssi_percentage[rfpath] =
 423				    rtlpriv->stats.rx_rssi_percentage[rfpath] +
 424				    1;
 425			} else {
 426				rtlpriv->stats.rx_rssi_percentage[rfpath] =
 427				    ((rtlpriv->stats.
 428				      rx_rssi_percentage[rfpath] *
 429				      (RX_SMOOTH_FACTOR - 1)) +
 430				     (pstats->rx_mimo_signalstrength[rfpath])) /
 431				    (RX_SMOOTH_FACTOR);
 432			}
 433
 434		}
 435	}
 436}
 437
 438static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
 439					       struct rtl_stats *pstats)
 440{
 441	struct rtl_priv *rtlpriv = rtl_priv(hw);
 442	int weighting = 0;
 443
 444	if (rtlpriv->stats.recv_signal_power == 0)
 445		rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
 446
 447	if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
 448		weighting = 5;
 449
 450	else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
 451		weighting = (-5);
 452
 453	rtlpriv->stats.recv_signal_power =
 454	    (rtlpriv->stats.recv_signal_power * 5 +
 455	     pstats->recvsignalpower + weighting) / 6;
 456}
 457
 458static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
 459		struct rtl_stats *pstats)
 460{
 461	struct rtl_priv *rtlpriv = rtl_priv(hw);
 462	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 463	long undecorated_smoothed_pwdb;
 464
 465	if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 466		return;
 467	} else {
 468		undecorated_smoothed_pwdb =
 469		    rtlpriv->dm.undecorated_smoothed_pwdb;
 470	}
 471
 472	if (pstats->packet_toself || pstats->packet_beacon) {
 473		if (undecorated_smoothed_pwdb < 0)
 474			undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
 475
 476		if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
 477			undecorated_smoothed_pwdb =
 478			    (((undecorated_smoothed_pwdb) *
 479			      (RX_SMOOTH_FACTOR - 1)) +
 480			     (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 481
 482			undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
 483			    + 1;
 484		} else {
 485			undecorated_smoothed_pwdb =
 486			    (((undecorated_smoothed_pwdb) *
 487			      (RX_SMOOTH_FACTOR - 1)) +
 488			     (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 489		}
 490
 491		rtlpriv->dm.undecorated_smoothed_pwdb =
 492		    undecorated_smoothed_pwdb;
 493		_rtl92ce_update_rxsignalstatistics(hw, pstats);
 494	}
 495}
 496
 497static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
 498					     struct rtl_stats *pstats)
 499{
 500	struct rtl_priv *rtlpriv = rtl_priv(hw);
 501	u32 last_evm, n_spatialstream, tmpval;
 502
 503	if (pstats->signalquality != 0) {
 504		if (pstats->packet_toself || pstats->packet_beacon) {
 505
 506			if (rtlpriv->stats.ui_link_quality.total_num++ >=
 507			    PHY_LINKQUALITY_SLID_WIN_MAX) {
 508				rtlpriv->stats.ui_link_quality.total_num =
 509				    PHY_LINKQUALITY_SLID_WIN_MAX;
 510				last_evm =
 511				    rtlpriv->stats.
 512				    ui_link_quality.elements[rtlpriv->
 513							  stats.ui_link_quality.
 514							  index];
 515				rtlpriv->stats.ui_link_quality.total_val -=
 516				    last_evm;
 517			}
 518
 519			rtlpriv->stats.ui_link_quality.total_val +=
 520			    pstats->signalquality;
 521			rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
 522								ui_link_quality.
 523								index++] =
 524			    pstats->signalquality;
 525
 526			if (rtlpriv->stats.ui_link_quality.index >=
 527			    PHY_LINKQUALITY_SLID_WIN_MAX)
 528				rtlpriv->stats.ui_link_quality.index = 0;
 529
 530			tmpval = rtlpriv->stats.ui_link_quality.total_val /
 531			    rtlpriv->stats.ui_link_quality.total_num;
 532			rtlpriv->stats.signal_quality = tmpval;
 533
 534			rtlpriv->stats.last_sigstrength_inpercent = tmpval;
 535
 536			for (n_spatialstream = 0; n_spatialstream < 2;
 537			     n_spatialstream++) {
 538				if (pstats->
 539				    rx_mimo_signalquality[n_spatialstream] !=
 540				    -1) {
 541					if (rtlpriv->stats.
 542					    rx_evm_percentage[n_spatialstream]
 543					    == 0) {
 544						rtlpriv->stats.
 545						   rx_evm_percentage
 546						   [n_spatialstream] =
 547						   pstats->rx_mimo_signalquality
 548						   [n_spatialstream];
 549					}
 550
 551					rtlpriv->stats.
 552					    rx_evm_percentage[n_spatialstream] =
 553					    ((rtlpriv->
 554					      stats.rx_evm_percentage
 555					      [n_spatialstream] *
 556					      (RX_SMOOTH_FACTOR - 1)) +
 557					     (pstats->
 558					      rx_mimo_signalquality
 559					      [n_spatialstream] * 1)) /
 560					    (RX_SMOOTH_FACTOR);
 561				}
 562			}
 563		}
 564	} else {
 565		;
 566	}
 567}
 568
 569static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
 570				     u8 *buffer,
 571				     struct rtl_stats *pcurrent_stats)
 572{
 573
 574	if (!pcurrent_stats->packet_matchbssid &&
 575	    !pcurrent_stats->packet_beacon)
 576		return;
 577
 578	_rtl92ce_process_ui_rssi(hw, pcurrent_stats);
 579	_rtl92ce_process_pwdb(hw, pcurrent_stats);
 580	_rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
 581}
 582
 583static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 584					       struct sk_buff *skb,
 585					       struct rtl_stats *pstats,
 586					       struct rx_desc_92c *pdesc,
 587					       struct rx_fwinfo_92c *p_drvinfo)
 588{
 589	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 590	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 591
 592	struct ieee80211_hdr *hdr;
 593	u8 *tmp_buf;
 594	u8 *praddr;
 595	__le16 fc;
 596	u16 type, c_fc;
 597	bool packet_matchbssid, packet_toself, packet_beacon;
 598
 599	tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 600
 601	hdr = (struct ieee80211_hdr *)tmp_buf;
 602	fc = hdr->frame_control;
 603	c_fc = le16_to_cpu(fc);
 604	type = WLAN_FC_GET_TYPE(fc);
 605	praddr = hdr->addr1;
 606
 607	packet_matchbssid =
 608	    ((IEEE80211_FTYPE_CTL != type) &&
 609	     (!compare_ether_addr(mac->bssid,
 610				  (c_fc & IEEE80211_FCTL_TODS) ?
 611				  hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ?
 612				  hdr->addr2 : hdr->addr3)) &&
 613	     (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 614
 615	packet_toself = packet_matchbssid &&
 616	    (!compare_ether_addr(praddr, rtlefuse->dev_addr));
 617
 618	if (ieee80211_is_beacon(fc))
 619		packet_beacon = true;
 620
 621	_rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 622				   packet_matchbssid, packet_toself,
 623				   packet_beacon);
 624
 625	_rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
 626}
 627
 628bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
 629			   struct rtl_stats *stats,
 630			   struct ieee80211_rx_status *rx_status,
 631			   u8 *p_desc, struct sk_buff *skb)
 632{
 633	struct rx_fwinfo_92c *p_drvinfo;
 634	struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 635
 636	u32 phystatus = GET_RX_DESC_PHYST(pdesc);
 637	stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
 638	stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
 639	    RX_DRV_INFO_SIZE_UNIT;
 640	stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
 641	stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
 642	stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
 643	stats->hwerror = (stats->crc | stats->icv);
 644	stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
 645	stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
 646	stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
 647	stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
 648	stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
 649				   && (GET_RX_DESC_FAGGR(pdesc) == 1));
 650	stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
 651	stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
 
 652
 653	rx_status->freq = hw->conf.channel->center_freq;
 654	rx_status->band = hw->conf.channel->band;
 655
 656	if (GET_RX_DESC_CRC32(pdesc))
 657		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 
 
 
 658
 659	if (!GET_RX_DESC_SWDEC(pdesc))
 660		rx_status->flag |= RX_FLAG_DECRYPTED;
 661
 662	if (GET_RX_DESC_BW(pdesc))
 663		rx_status->flag |= RX_FLAG_40MHZ;
 664
 665	if (GET_RX_DESC_RXHT(pdesc))
 666		rx_status->flag |= RX_FLAG_HT;
 667
 668	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 669
 670	if (stats->decrypted)
 671		rx_status->flag |= RX_FLAG_DECRYPTED;
 672
 673	rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
 674						    GET_RX_DESC_RXHT(pdesc),
 675						    (u8)
 676						    GET_RX_DESC_RXMCS(pdesc),
 677						    (bool)
 678						    GET_RX_DESC_PAGGR(pdesc));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 679
 680	rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
 681	if (phystatus) {
 682		p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
 683						     stats->rx_bufshift);
 684
 685		_rtl92ce_translate_rx_signal_stuff(hw,
 686						   skb, stats, pdesc,
 687						   p_drvinfo);
 688	}
 689
 690	/*rx_status->qual = stats->signal; */
 691	rx_status->signal = stats->rssi + 10;
 692	/*rx_status->noise = -stats->noise; */
 693
 694	return true;
 695}
 696
 697void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 698			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 699			  struct ieee80211_tx_info *info, struct sk_buff *skb,
 
 
 700			  u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
 701{
 702	struct rtl_priv *rtlpriv = rtl_priv(hw);
 703	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 704	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 705	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 706	bool defaultadapter = true;
 707	struct ieee80211_sta *sta;
 708	u8 *pdesc = (u8 *) pdesc_tx;
 709	u16 seq_number;
 710	__le16 fc = hdr->frame_control;
 711	u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
 712	bool firstseg = ((hdr->seq_ctrl &
 713			  cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 714
 715	bool lastseg = ((hdr->frame_control &
 716			 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 717
 718	dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 719					    skb->data, skb->len,
 720					    PCI_DMA_TODEVICE);
 
 721	u8 bw_40 = 0;
 722
 
 
 
 
 
 723	rcu_read_lock();
 724	sta = get_sta(hw, mac->vif, mac->bssid);
 725	if (mac->opmode == NL80211_IFTYPE_STATION) {
 726		bw_40 = mac->bw_40;
 727	} else if (mac->opmode == NL80211_IFTYPE_AP ||
 728		mac->opmode == NL80211_IFTYPE_ADHOC) {
 
 729		if (sta)
 730			bw_40 = sta->ht_cap.cap &
 731				IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 732	}
 733
 734	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 735
 736	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 737
 738	CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
 739
 740	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 741		firstseg = true;
 742		lastseg = true;
 743	}
 744	if (firstseg) {
 745		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 746
 747		SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
 748
 749		if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 750			SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 751
 752		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 753			SET_TX_DESC_AGG_BREAK(pdesc, 1);
 754			SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 755		}
 756		SET_TX_DESC_SEQ(pdesc, seq_number);
 757
 758		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
 759						!tcb_desc->
 760						cts_enable) ? 1 : 0));
 761		SET_TX_DESC_HW_RTS_ENABLE(pdesc,
 762					  ((tcb_desc->rts_enable
 763					    || tcb_desc->cts_enable) ? 1 : 0));
 764		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
 765		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
 766
 767		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
 768		SET_TX_DESC_RTS_BW(pdesc, 0);
 769		SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
 770		SET_TX_DESC_RTS_SHORT(pdesc,
 771				      ((tcb_desc->rts_rate <= DESC92C_RATE54M) ?
 772				       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
 773				       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 774
 775		if (bw_40) {
 776			if (tcb_desc->packet_bw) {
 777				SET_TX_DESC_DATA_BW(pdesc, 1);
 778				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 779			} else {
 780				SET_TX_DESC_DATA_BW(pdesc, 0);
 781				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 782						 mac->cur_40_prime_sc);
 783			}
 784		} else {
 785			SET_TX_DESC_DATA_BW(pdesc, 0);
 786			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 787		}
 788
 789		SET_TX_DESC_LINIP(pdesc, 0);
 790		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 791
 792		if (sta) {
 793			u8 ampdu_density = sta->ht_cap.ampdu_density;
 794			SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 795		}
 796
 797		if (info->control.hw_key) {
 798			struct ieee80211_key_conf *keyconf =
 799			    info->control.hw_key;
 800
 801			switch (keyconf->cipher) {
 802			case WLAN_CIPHER_SUITE_WEP40:
 803			case WLAN_CIPHER_SUITE_WEP104:
 804			case WLAN_CIPHER_SUITE_TKIP:
 805				SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 806				break;
 807			case WLAN_CIPHER_SUITE_CCMP:
 808				SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 809				break;
 810			default:
 811				SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 812				break;
 813
 814			}
 815		}
 816
 817		SET_TX_DESC_PKT_ID(pdesc, 0);
 818		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 819
 820		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 821		SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 822		SET_TX_DESC_DISABLE_FB(pdesc, 0);
 823		SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
 824
 825		if (ieee80211_is_data_qos(fc)) {
 826			if (mac->rdg_en) {
 827				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 828					 ("Enable RDG function.\n"));
 829				SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 830				SET_TX_DESC_HTC(pdesc, 1);
 831			}
 832		}
 833	}
 834	rcu_read_unlock();
 835
 836	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 837	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 838
 839	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 840
 841	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 842
 843	if (rtlpriv->dm.useramask) {
 844		SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
 845		SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
 846	} else {
 847		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
 848		SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
 849	}
 850
 851	if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 852		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 853		SET_TX_DESC_PKT_ID(pdesc, 8);
 854
 855		if (!defaultadapter)
 856			SET_TX_DESC_QOS(pdesc, 1);
 857	}
 858
 859	SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 860
 861	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
 862	    is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
 863		SET_TX_DESC_BMC(pdesc, 1);
 864	}
 865
 866	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
 867}
 868
 869void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
 870			     u8 *pdesc, bool firstseg,
 871			     bool lastseg, struct sk_buff *skb)
 872{
 873	struct rtl_priv *rtlpriv = rtl_priv(hw);
 874	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 875	u8 fw_queue = QSLT_BEACON;
 876
 877	dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 878					    skb->data, skb->len,
 879					    PCI_DMA_TODEVICE);
 880
 881	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 882	__le16 fc = hdr->frame_control;
 883
 
 
 
 
 
 884	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 885
 886	if (firstseg)
 887		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 888
 889	SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
 890
 891	SET_TX_DESC_SEQ(pdesc, 0);
 892
 893	SET_TX_DESC_LINIP(pdesc, 0);
 894
 895	SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 896
 897	SET_TX_DESC_FIRST_SEG(pdesc, 1);
 898	SET_TX_DESC_LAST_SEG(pdesc, 1);
 899
 900	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
 901
 902	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 903
 904	SET_TX_DESC_RATE_ID(pdesc, 7);
 905	SET_TX_DESC_MACID(pdesc, 0);
 906
 907	SET_TX_DESC_OWN(pdesc, 1);
 908
 909	SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
 910
 911	SET_TX_DESC_FIRST_SEG(pdesc, 1);
 912	SET_TX_DESC_LAST_SEG(pdesc, 1);
 913
 914	SET_TX_DESC_OFFSET(pdesc, 0x20);
 915
 916	SET_TX_DESC_USE_RATE(pdesc, 1);
 917
 918	if (!ieee80211_is_data_qos(fc)) {
 919		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 920		SET_TX_DESC_PKT_ID(pdesc, 8);
 921	}
 922
 923	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 924		      "H2C Tx Cmd Content\n",
 925		      pdesc, TX_DESC_SIZE);
 926}
 927
 928void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 
 929{
 930	if (istx) {
 931		switch (desc_name) {
 932		case HW_DESC_OWN:
 933			wmb();
 934			SET_TX_DESC_OWN(pdesc, 1);
 935			break;
 936		case HW_DESC_TX_NEXTDESC_ADDR:
 937			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 938			break;
 939		default:
 940			RT_ASSERT(false, ("ERR txdesc :%d"
 941					  " not process\n", desc_name));
 942			break;
 943		}
 944	} else {
 945		switch (desc_name) {
 946		case HW_DESC_RXOWN:
 947			wmb();
 948			SET_RX_DESC_OWN(pdesc, 1);
 949			break;
 950		case HW_DESC_RXBUFF_ADDR:
 951			SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 952			break;
 953		case HW_DESC_RXPKT_LEN:
 954			SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
 955			break;
 956		case HW_DESC_RXERO:
 957			SET_RX_DESC_EOR(pdesc, 1);
 958			break;
 959		default:
 960			RT_ASSERT(false, ("ERR rxdesc :%d "
 961					  "not process\n", desc_name));
 962			break;
 963		}
 964	}
 965}
 966
 967u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 968{
 969	u32 ret = 0;
 970
 971	if (istx) {
 972		switch (desc_name) {
 973		case HW_DESC_OWN:
 974			ret = GET_TX_DESC_OWN(p_desc);
 975			break;
 976		case HW_DESC_TXBUFF_ADDR:
 977			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 978			break;
 979		default:
 980			RT_ASSERT(false, ("ERR txdesc :%d "
 981					  "not process\n", desc_name));
 982			break;
 983		}
 984	} else {
 985		struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 986		switch (desc_name) {
 987		case HW_DESC_OWN:
 988			ret = GET_RX_DESC_OWN(pdesc);
 989			break;
 990		case HW_DESC_RXPKT_LEN:
 991			ret = GET_RX_DESC_PKT_LEN(pdesc);
 992			break;
 993		default:
 994			RT_ASSERT(false, ("ERR rxdesc :%d "
 995					  "not process\n", desc_name));
 996			break;
 997		}
 998	}
 999	return ret;
1000}
1001
1002void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
1003{
1004	struct rtl_priv *rtlpriv = rtl_priv(hw);
1005	if (hw_queue == BEACON_QUEUE) {
1006		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1007	} else {
1008		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1009			       BIT(0) << (hw_queue));
1010	}
1011}
1012
v3.15
  1/******************************************************************************
  2 *
  3 * Copyright(c) 2009-2012  Realtek Corporation.
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms of version 2 of the GNU General Public License as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 12 * more details.
 13 *
 14 * You should have received a copy of the GNU General Public License along with
 15 * this program; if not, write to the Free Software Foundation, Inc.,
 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 17 *
 18 * The full GNU General Public License is included in this distribution in the
 19 * file called LICENSE.
 20 *
 21 * Contact Information:
 22 * wlanfae <wlanfae@realtek.com>
 23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
 24 * Hsinchu 300, Taiwan.
 25 *
 26 * Larry Finger <Larry.Finger@lwfinger.net>
 27 *
 28 *****************************************************************************/
 29
 30#include "../wifi.h"
 31#include "../pci.h"
 32#include "../base.h"
 33#include "../stats.h"
 34#include "reg.h"
 35#include "def.h"
 36#include "phy.h"
 37#include "trx.h"
 38#include "led.h"
 39
 40static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
 41{
 42	__le16 fc = rtl_get_fc(skb);
 43
 44	if (unlikely(ieee80211_is_beacon(fc)))
 45		return QSLT_BEACON;
 46	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
 47		return QSLT_MGNT;
 48
 49	return skb->priority;
 50}
 51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 52static u8 _rtl92c_query_rxpwrpercentage(char antpower)
 53{
 54	if ((antpower <= -100) || (antpower >= 20))
 55		return 0;
 56	else if (antpower >= 0)
 57		return 100;
 58	else
 59		return 100 + antpower;
 60}
 61
 62static u8 _rtl92c_evm_db_to_percentage(char value)
 63{
 64	char ret_val;
 65	ret_val = value;
 66
 67	if (ret_val >= 0)
 68		ret_val = 0;
 69
 70	if (ret_val <= -33)
 71		ret_val = -33;
 72
 73	ret_val = 0 - ret_val;
 74	ret_val *= 3;
 75
 76	if (ret_val == 99)
 77		ret_val = 100;
 78
 79	return ret_val;
 80}
 81
 
 
 
 
 
 
 
 
 
 
 82static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
 83		long currsig)
 84{
 85	long retsig;
 86
 87	if (currsig >= 61 && currsig <= 100)
 88		retsig = 90 + ((currsig - 60) / 4);
 89	else if (currsig >= 41 && currsig <= 60)
 90		retsig = 78 + ((currsig - 40) / 2);
 91	else if (currsig >= 31 && currsig <= 40)
 92		retsig = 66 + (currsig - 30);
 93	else if (currsig >= 21 && currsig <= 30)
 94		retsig = 54 + (currsig - 20);
 95	else if (currsig >= 5 && currsig <= 20)
 96		retsig = 42 + (((currsig - 5) * 2) / 3);
 97	else if (currsig == 4)
 98		retsig = 36;
 99	else if (currsig == 3)
100		retsig = 27;
101	else if (currsig == 2)
102		retsig = 18;
103	else if (currsig == 1)
104		retsig = 9;
105	else
106		retsig = currsig;
107
108	return retsig;
109}
110
111static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
112				       struct rtl_stats *pstats,
113				       struct rx_desc_92c *pdesc,
114				       struct rx_fwinfo_92c *p_drvinfo,
115				       bool packet_match_bssid,
116				       bool packet_toself,
117				       bool packet_beacon)
118{
119	struct rtl_priv *rtlpriv = rtl_priv(hw);
120	struct phy_sts_cck_8192s_t *cck_buf;
121	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
122	s8 rx_pwr_all = 0, rx_pwr[4];
123	u8 evm, pwdb_all, rf_rx_num = 0;
124	u8 i, max_spatial_stream;
125	u32 rssi, total_rssi = 0;
 
126	bool is_cck_rate;
127
128	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
129	pstats->packet_matchbssid = packet_match_bssid;
130	pstats->packet_toself = packet_toself;
131	pstats->is_cck = is_cck_rate;
132	pstats->packet_beacon = packet_beacon;
133	pstats->rx_mimo_sig_qual[0] = -1;
134	pstats->rx_mimo_sig_qual[1] = -1;
 
135
136	if (is_cck_rate) {
137		u8 report, cck_highpwr;
138		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
139
140		if (ppsc->rfpwr_state == ERFON)
141			cck_highpwr = (u8) rtl_get_bbreg(hw,
142						 RFPGA0_XA_HSSIPARAMETER2,
143						 BIT(9));
144		else
145			cck_highpwr = false;
146
147		if (!cck_highpwr) {
148			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
149			report = cck_buf->cck_agc_rpt & 0xc0;
150			report = report >> 6;
151			switch (report) {
152			case 0x3:
153				rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
154				break;
155			case 0x2:
156				rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
157				break;
158			case 0x1:
159				rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
160				break;
161			case 0x0:
162				rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
163				break;
164			}
165		} else {
166			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
167			report = p_drvinfo->cfosho[0] & 0x60;
168			report = report >> 5;
169			switch (report) {
170			case 0x3:
171				rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
172				break;
173			case 0x2:
174				rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
175				break;
176			case 0x1:
177				rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
178				break;
179			case 0x0:
180				rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
181				break;
182			}
183		}
184
185		pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
186		/* CCK gain is smaller than OFDM/MCS gain,
187		 * so we add gain diff by experiences,
188		 * the val is 6
189		 */
190		pwdb_all += 6;
191		if (pwdb_all > 100)
192			pwdb_all = 100;
193		/* modify the offset to make the same
194		 * gain index with OFDM.
195		 */
196		if (pwdb_all > 34 && pwdb_all <= 42)
197			pwdb_all -= 2;
198		else if (pwdb_all > 26 && pwdb_all <= 34)
199			pwdb_all -= 6;
200		else if (pwdb_all > 14 && pwdb_all <= 26)
201			pwdb_all -= 8;
202		else if (pwdb_all > 4 && pwdb_all <= 14)
203			pwdb_all -= 4;
204
205		pstats->rx_pwdb_all = pwdb_all;
206		pstats->recvsignalpower = rx_pwr_all;
207
208		/* (3) Get Signal Quality (EVM) */
209		if (packet_match_bssid) {
210			u8 sq;
211			if (pstats->rx_pwdb_all > 40)
212				sq = 100;
213			else {
214				sq = cck_buf->sq_rpt;
215				if (sq > 64)
216					sq = 0;
217				else if (sq < 20)
218					sq = 100;
219				else
220					sq = ((64 - sq) * 100) / 44;
221			}
222
223			pstats->signalquality = sq;
224			pstats->rx_mimo_sig_qual[0] = sq;
225			pstats->rx_mimo_sig_qual[1] = -1;
226		}
227	} else {
228		rtlpriv->dm.rfpath_rxenable[0] =
229		    rtlpriv->dm.rfpath_rxenable[1] = true;
230		/* (1)Get RSSI for HT rate */
231		for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
232			/* we will judge RF RX path now. */
233			if (rtlpriv->dm.rfpath_rxenable[i])
234				rf_rx_num++;
235
236			rx_pwr[i] =
237			    ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
238			/* Translate DBM to percentage. */
239			rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
240			total_rssi += rssi;
241			/* Get Rx snr value in DB */
242			rtlpriv->stats.rx_snr_db[i] =
243			    (long)(p_drvinfo->rxsnr[i] / 2);
244
245			/* Record Signal Strength for next packet */
246			if (packet_match_bssid)
247				pstats->rx_mimo_signalstrength[i] = (u8) rssi;
248		}
249
250		/* (2)PWDB, Average PWDB cacluated by
251		 * hardware (for rate adaptive)
252		 */
253		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
254		pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
255		pstats->rx_pwdb_all = pwdb_all;
256		pstats->rxpower = rx_pwr_all;
257		pstats->recvsignalpower = rx_pwr_all;
258
259		/* (3)EVM of HT rate */
260		if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
261		    pstats->rate <= DESC92_RATEMCS15)
262			max_spatial_stream = 2;
263		else
264			max_spatial_stream = 1;
265
266		for (i = 0; i < max_spatial_stream; i++) {
267			evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
268
269			if (packet_match_bssid) {
270				/* Fill value in RFD, Get the first
271				 * spatial stream only
272				 */
273				if (i == 0)
274					pstats->signalquality =
275					    (u8) (evm & 0xff);
276				pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
 
277			}
278		}
279	}
280
281	/* UI BSS List signal strength(in percentage),
282	 * make it good looking, from 0~100.
283	 */
284	if (is_cck_rate)
285		pstats->signalstrength =
286		    (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
287	else if (rf_rx_num != 0)
288		pstats->signalstrength =
289		    (u8) (_rtl92ce_signal_scale_mapping
290			  (hw, total_rssi /= rf_rx_num));
291}
292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
294					       struct sk_buff *skb,
295					       struct rtl_stats *pstats,
296					       struct rx_desc_92c *pdesc,
297					       struct rx_fwinfo_92c *p_drvinfo)
298{
299	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
300	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
301
302	struct ieee80211_hdr *hdr;
303	u8 *tmp_buf;
304	u8 *praddr;
305	__le16 fc;
306	u16 type, c_fc;
307	bool packet_matchbssid, packet_toself, packet_beacon = false;
308
309	tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
310
311	hdr = (struct ieee80211_hdr *)tmp_buf;
312	fc = hdr->frame_control;
313	c_fc = le16_to_cpu(fc);
314	type = WLAN_FC_GET_TYPE(fc);
315	praddr = hdr->addr1;
316
317	packet_matchbssid =
318	    ((IEEE80211_FTYPE_CTL != type) &&
319	     ether_addr_equal(mac->bssid,
320			      (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
321			      (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
322			      hdr->addr3) &&
323	     (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
324
325	packet_toself = packet_matchbssid &&
326	     ether_addr_equal(praddr, rtlefuse->dev_addr);
327
328	if (ieee80211_is_beacon(fc))
329		packet_beacon = true;
330
331	_rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
332				   packet_matchbssid, packet_toself,
333				   packet_beacon);
334
335	rtl_process_phyinfo(hw, tmp_buf, pstats);
336}
337
338bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
339			   struct rtl_stats *stats,
340			   struct ieee80211_rx_status *rx_status,
341			   u8 *p_desc, struct sk_buff *skb)
342{
343	struct rx_fwinfo_92c *p_drvinfo;
344	struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
345	struct ieee80211_hdr *hdr;
346	u32 phystatus = GET_RX_DESC_PHYST(pdesc);
347	stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
348	stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
349	    RX_DRV_INFO_SIZE_UNIT;
350	stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
351	stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
352	stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
353	stats->hwerror = (stats->crc | stats->icv);
354	stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
355	stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
356	stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
357	stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
358	stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
359				   && (GET_RX_DESC_FAGGR(pdesc) == 1));
360	stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
361	stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
362	stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
363
364	stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc);
 
365
366	rx_status->freq = hw->conf.chandef.chan->center_freq;
367	rx_status->band = hw->conf.chandef.chan->band;
368
369	hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
370			+ stats->rx_bufshift);
371
372	if (stats->crc)
373		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
374
375	if (stats->rx_is40Mhzpacket)
376		rx_status->flag |= RX_FLAG_40MHZ;
377
378	if (stats->is_ht)
379		rx_status->flag |= RX_FLAG_HT;
380
381	rx_status->flag |= RX_FLAG_MACTIME_START;
 
 
 
382
383	/* hw will set stats->decrypted true, if it finds the
384	 * frame is open data frame or mgmt frame.
385	 * So hw will not decryption robust managment frame
386	 * for IEEE80211w but still set status->decrypted
387	 * true, so here we should set it back to undecrypted
388	 * for IEEE80211w frame, and mac80211 sw will help
389	 * to decrypt it
390	 */
391	if (stats->decrypted) {
392		if (!hdr) {
393			/* In testing, hdr was NULL here */
394			return false;
395		}
396		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
397		    (ieee80211_has_protected(hdr->frame_control)))
398			rx_status->flag &= ~RX_FLAG_DECRYPTED;
399		else
400			rx_status->flag |= RX_FLAG_DECRYPTED;
401	}
402	/* rate_idx: index of data rate into band's
403	 * supported rates or MCS index if HT rates
404	 * are use (RX_FLAG_HT)
405	 * Notice: this is diff with windows define
406	 */
407	rx_status->rate_idx = rtlwifi_rate_mapping(hw,
408				stats->is_ht, stats->rate,
409				stats->isfirst_ampdu);
410
411	rx_status->mactime = stats->timestamp_low;
412	if (phystatus) {
413		p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
414						     stats->rx_bufshift);
415
416		_rtl92ce_translate_rx_signal_stuff(hw,
417						   skb, stats, pdesc,
418						   p_drvinfo);
419	}
420
421	/*rx_status->qual = stats->signal; */
422	rx_status->signal = stats->recvsignalpower + 10;
 
423
424	return true;
425}
426
427void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
428			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
429			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
430			  struct ieee80211_sta *sta,
431			  struct sk_buff *skb,
432			  u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
433{
434	struct rtl_priv *rtlpriv = rtl_priv(hw);
435	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
436	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
437	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
438	bool defaultadapter = true;
439	u8 *pdesc = pdesc_tx;
 
440	u16 seq_number;
441	__le16 fc = hdr->frame_control;
442	u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
443	bool firstseg = ((hdr->seq_ctrl &
444			  cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
445
446	bool lastseg = ((hdr->frame_control &
447			 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
448
449	dma_addr_t mapping = pci_map_single(rtlpci->pdev,
450					    skb->data, skb->len,
451					    PCI_DMA_TODEVICE);
452
453	u8 bw_40 = 0;
454
455	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
456		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
457			 "DMA mapping error");
458		return;
459	}
460	rcu_read_lock();
461	sta = get_sta(hw, mac->vif, mac->bssid);
462	if (mac->opmode == NL80211_IFTYPE_STATION) {
463		bw_40 = mac->bw_40;
464	} else if (mac->opmode == NL80211_IFTYPE_AP ||
465		   mac->opmode == NL80211_IFTYPE_ADHOC ||
466		   mac->opmode == NL80211_IFTYPE_MESH_POINT) {
467		if (sta)
468			bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 
469	}
470
471	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
472
473	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
474
475	CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
476
477	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
478		firstseg = true;
479		lastseg = true;
480	}
481	if (firstseg) {
482		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
483
484		SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
485
486		if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
487			SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
488
489		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
490			SET_TX_DESC_AGG_BREAK(pdesc, 1);
491			SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
492		}
493		SET_TX_DESC_SEQ(pdesc, seq_number);
494
495		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
496						!tcb_desc->
497						cts_enable) ? 1 : 0));
498		SET_TX_DESC_HW_RTS_ENABLE(pdesc,
499					  ((tcb_desc->rts_enable
500					    || tcb_desc->cts_enable) ? 1 : 0));
501		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
502		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
503
504		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
505		SET_TX_DESC_RTS_BW(pdesc, 0);
506		SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
507		SET_TX_DESC_RTS_SHORT(pdesc,
508				      ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
509				       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
510				       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
511
512		if (bw_40) {
513			if (tcb_desc->packet_bw) {
514				SET_TX_DESC_DATA_BW(pdesc, 1);
515				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
516			} else {
517				SET_TX_DESC_DATA_BW(pdesc, 0);
518				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
519						 mac->cur_40_prime_sc);
520			}
521		} else {
522			SET_TX_DESC_DATA_BW(pdesc, 0);
523			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
524		}
525
526		SET_TX_DESC_LINIP(pdesc, 0);
527		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
528
529		if (sta) {
530			u8 ampdu_density = sta->ht_cap.ampdu_density;
531			SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
532		}
533
534		if (info->control.hw_key) {
535			struct ieee80211_key_conf *keyconf =
536			    info->control.hw_key;
537
538			switch (keyconf->cipher) {
539			case WLAN_CIPHER_SUITE_WEP40:
540			case WLAN_CIPHER_SUITE_WEP104:
541			case WLAN_CIPHER_SUITE_TKIP:
542				SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
543				break;
544			case WLAN_CIPHER_SUITE_CCMP:
545				SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
546				break;
547			default:
548				SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
549				break;
550
551			}
552		}
553
554		SET_TX_DESC_PKT_ID(pdesc, 0);
555		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
556
557		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
558		SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
559		SET_TX_DESC_DISABLE_FB(pdesc, 0);
560		SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
561
562		if (ieee80211_is_data_qos(fc)) {
563			if (mac->rdg_en) {
564				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
565					 "Enable RDG function\n");
566				SET_TX_DESC_RDG_ENABLE(pdesc, 1);
567				SET_TX_DESC_HTC(pdesc, 1);
568			}
569		}
570	}
571	rcu_read_unlock();
572
573	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
574	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
575
576	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
577
578	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
579
580	if (rtlpriv->dm.useramask) {
581		SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
582		SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
583	} else {
584		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
585		SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
586	}
587
588	if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
589		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
590		SET_TX_DESC_PKT_ID(pdesc, 8);
591
592		if (!defaultadapter)
593			SET_TX_DESC_QOS(pdesc, 1);
594	}
595
596	SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
597
598	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
599	    is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
600		SET_TX_DESC_BMC(pdesc, 1);
601	}
602
603	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
604}
605
606void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
607			     u8 *pdesc, bool firstseg,
608			     bool lastseg, struct sk_buff *skb)
609{
610	struct rtl_priv *rtlpriv = rtl_priv(hw);
611	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
612	u8 fw_queue = QSLT_BEACON;
613
614	dma_addr_t mapping = pci_map_single(rtlpci->pdev,
615					    skb->data, skb->len,
616					    PCI_DMA_TODEVICE);
617
618	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
619	__le16 fc = hdr->frame_control;
620
621	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
622		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
623			 "DMA mapping error");
624		return;
625	}
626	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
627
628	if (firstseg)
629		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
630
631	SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
632
633	SET_TX_DESC_SEQ(pdesc, 0);
634
635	SET_TX_DESC_LINIP(pdesc, 0);
636
637	SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
638
639	SET_TX_DESC_FIRST_SEG(pdesc, 1);
640	SET_TX_DESC_LAST_SEG(pdesc, 1);
641
642	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
643
644	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
645
646	SET_TX_DESC_RATE_ID(pdesc, 7);
647	SET_TX_DESC_MACID(pdesc, 0);
648
649	SET_TX_DESC_OWN(pdesc, 1);
650
651	SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
652
653	SET_TX_DESC_FIRST_SEG(pdesc, 1);
654	SET_TX_DESC_LAST_SEG(pdesc, 1);
655
656	SET_TX_DESC_OFFSET(pdesc, 0x20);
657
658	SET_TX_DESC_USE_RATE(pdesc, 1);
659
660	if (!ieee80211_is_data_qos(fc)) {
661		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
662		SET_TX_DESC_PKT_ID(pdesc, 8);
663	}
664
665	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
666		      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 
667}
668
669void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
670		      u8 desc_name, u8 *val)
671{
672	if (istx) {
673		switch (desc_name) {
674		case HW_DESC_OWN:
675			wmb();
676			SET_TX_DESC_OWN(pdesc, 1);
677			break;
678		case HW_DESC_TX_NEXTDESC_ADDR:
679			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
680			break;
681		default:
682			RT_ASSERT(false, "ERR txdesc :%d not process\n",
683				  desc_name);
684			break;
685		}
686	} else {
687		switch (desc_name) {
688		case HW_DESC_RXOWN:
689			wmb();
690			SET_RX_DESC_OWN(pdesc, 1);
691			break;
692		case HW_DESC_RXBUFF_ADDR:
693			SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
694			break;
695		case HW_DESC_RXPKT_LEN:
696			SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
697			break;
698		case HW_DESC_RXERO:
699			SET_RX_DESC_EOR(pdesc, 1);
700			break;
701		default:
702			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
703				  desc_name);
704			break;
705		}
706	}
707}
708
709u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
710{
711	u32 ret = 0;
712
713	if (istx) {
714		switch (desc_name) {
715		case HW_DESC_OWN:
716			ret = GET_TX_DESC_OWN(p_desc);
717			break;
718		case HW_DESC_TXBUFF_ADDR:
719			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
720			break;
721		default:
722			RT_ASSERT(false, "ERR txdesc :%d not process\n",
723				  desc_name);
724			break;
725		}
726	} else {
727		struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
728		switch (desc_name) {
729		case HW_DESC_OWN:
730			ret = GET_RX_DESC_OWN(pdesc);
731			break;
732		case HW_DESC_RXPKT_LEN:
733			ret = GET_RX_DESC_PKT_LEN(pdesc);
734			break;
735		default:
736			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
737				  desc_name);
738			break;
739		}
740	}
741	return ret;
742}
743
744void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
745{
746	struct rtl_priv *rtlpriv = rtl_priv(hw);
747	if (hw_queue == BEACON_QUEUE) {
748		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
749	} else {
750		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
751			       BIT(0) << (hw_queue));
752	}
753}
754