Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
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 "fw.h"
 37#include "trx.h"
 38#include "led.h"
 39
 40static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,	u8 skb_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))
 47		return QSLT_MGNT;
 48	if (ieee80211_is_nullfunc(fc))
 49		return QSLT_HIGH;
 50
 
 
 
 
 
 
 51	return skb->priority;
 52}
 53
 54static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
 55{
 56	int rate_idx = 0;
 57
 58	if (first_ampdu) {
 59		if (false == isht) {
 60			switch (desc_rate) {
 61			case DESC92S_RATE1M:
 62				rate_idx = 0;
 63				break;
 64			case DESC92S_RATE2M:
 65				rate_idx = 1;
 66				break;
 67			case DESC92S_RATE5_5M:
 68				rate_idx = 2;
 69				break;
 70			case DESC92S_RATE11M:
 71				rate_idx = 3;
 72				break;
 73			case DESC92S_RATE6M:
 74				rate_idx = 4;
 75				break;
 76			case DESC92S_RATE9M:
 77				rate_idx = 5;
 78				break;
 79			case DESC92S_RATE12M:
 80				rate_idx = 6;
 81				break;
 82			case DESC92S_RATE18M:
 83				rate_idx = 7;
 84				break;
 85			case DESC92S_RATE24M:
 86				rate_idx = 8;
 87				break;
 88			case DESC92S_RATE36M:
 89				rate_idx = 9;
 90				break;
 91			case DESC92S_RATE48M:
 92				rate_idx = 10;
 93				break;
 94			case DESC92S_RATE54M:
 95				rate_idx = 11;
 96				break;
 97			default:
 98				rate_idx = 0;
 99				break;
100			}
101		} else {
102			rate_idx = 11;
103		}
104
105		return rate_idx;
106	}
107
108	switch (desc_rate) {
109	case DESC92S_RATE1M:
110		rate_idx = 0;
111		break;
112	case DESC92S_RATE2M:
113		rate_idx = 1;
114		break;
115	case DESC92S_RATE5_5M:
116		rate_idx = 2;
117		break;
118	case DESC92S_RATE11M:
119		rate_idx = 3;
120		break;
121	case DESC92S_RATE6M:
122		rate_idx = 4;
123		break;
124	case DESC92S_RATE9M:
125		rate_idx = 5;
126		break;
127	case DESC92S_RATE12M:
128		rate_idx = 6;
129		break;
130	case DESC92S_RATE18M:
131		rate_idx = 7;
132		break;
133	case DESC92S_RATE24M:
134		rate_idx = 8;
135		break;
136	case DESC92S_RATE36M:
137		rate_idx = 9;
138		break;
139	case DESC92S_RATE48M:
140		rate_idx = 10;
141		break;
142	case DESC92S_RATE54M:
143		rate_idx = 11;
144		break;
145	default:
146		rate_idx = 11;
147		break;
148	}
149	return rate_idx;
150}
151
152static u8 _rtl92s_query_rxpwrpercentage(char antpower)
153{
154	if ((antpower <= -100) || (antpower >= 20))
155		return 0;
156	else if (antpower >= 0)
157		return 100;
158	else
159		return 100 + antpower;
160}
161
162static u8 _rtl92s_evm_db_to_percentage(char value)
163{
164	char ret_val;
165	ret_val = value;
166
167	if (ret_val >= 0)
168		ret_val = 0;
169
170	if (ret_val <= -33)
171		ret_val = -33;
172
173	ret_val = 0 - ret_val;
174	ret_val *= 3;
175
176	if (ret_val == 99)
177		ret_val = 100;
178
179	return ret_val;
180}
181
182static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
183				     u8 signal_strength_index)
184{
185	long signal_power;
186
187	signal_power = (long)((signal_strength_index + 1) >> 1);
188	signal_power -= 95;
189	return signal_power;
190}
191
192static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
193		long currsig)
194{
195	long retsig = 0;
196
197	/* Step 1. Scale mapping. */
198	if (currsig > 47)
199		retsig = 100;
200	else if (currsig > 14 && currsig <= 47)
201		retsig = 100 - ((47 - currsig) * 3) / 2;
202	else if (currsig > 2 && currsig <= 14)
203		retsig = 48 - ((14 - currsig) * 15) / 7;
204	else if (currsig >= 0)
205		retsig = currsig * 9 + 1;
206
207	return retsig;
208}
209
210
211static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
212				       struct rtl_stats *pstats, u8 *pdesc,
213				       struct rx_fwinfo *p_drvinfo,
214				       bool packet_match_bssid,
215				       bool packet_toself,
216				       bool packet_beacon)
217{
218	struct rtl_priv *rtlpriv = rtl_priv(hw);
219	struct phy_sts_cck_8192s_t *cck_buf;
 
220	s8 rx_pwr_all = 0, rx_pwr[4];
221	u8 rf_rx_num = 0, evm, pwdb_all;
222	u8 i, max_spatial_stream;
223	u32 rssi, total_rssi = 0;
224	bool in_powersavemode = false;
225	bool is_cck_rate;
226
227	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
228	pstats->packet_matchbssid = packet_match_bssid;
229	pstats->packet_toself = packet_toself;
230	pstats->is_cck = is_cck_rate;
231	pstats->packet_beacon = packet_beacon;
232	pstats->is_cck = is_cck_rate;
233	pstats->rx_mimo_signalquality[0] = -1;
234	pstats->rx_mimo_signalquality[1] = -1;
235
236	if (is_cck_rate) {
237		u8 report, cck_highpwr;
238		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
239
240		if (!in_powersavemode)
241			cck_highpwr = (u8) rtl_get_bbreg(hw,
242						RFPGA0_XA_HSSIPARAMETER2,
243						0x200);
244		else
245			cck_highpwr = false;
246
247		if (!cck_highpwr) {
248			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
249			report = cck_buf->cck_agc_rpt & 0xc0;
250			report = report >> 6;
251			switch (report) {
252			case 0x3:
253				rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
254				break;
255			case 0x2:
256				rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
257				break;
258			case 0x1:
259				rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
260				break;
261			case 0x0:
262				rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
263				break;
264			}
265		} else {
266			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
267			report = p_drvinfo->cfosho[0] & 0x60;
268			report = report >> 5;
269			switch (report) {
270			case 0x3:
271				rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
272				break;
273			case 0x2:
274				rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
275				break;
276			case 0x1:
277				rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
278				break;
279			case 0x0:
280				rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
281				break;
282			}
283		}
284
285		pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
286
287		/* CCK gain is smaller than OFDM/MCS gain,  */
288		/* so we add gain diff by experiences, the val is 6 */
289		pwdb_all += 6;
290		if (pwdb_all > 100)
291			pwdb_all = 100;
292		/* modify the offset to make the same gain index with OFDM. */
293		if (pwdb_all > 34 && pwdb_all <= 42)
294			pwdb_all -= 2;
295		else if (pwdb_all > 26 && pwdb_all <= 34)
296			pwdb_all -= 6;
297		else if (pwdb_all > 14 && pwdb_all <= 26)
298			pwdb_all -= 8;
299		else if (pwdb_all > 4 && pwdb_all <= 14)
300			pwdb_all -= 4;
301
302		pstats->rx_pwdb_all = pwdb_all;
303		pstats->recvsignalpower = rx_pwr_all;
304
305		if (packet_match_bssid) {
306			u8 sq;
307			if (pstats->rx_pwdb_all > 40) {
308				sq = 100;
309			} else {
310				sq = cck_buf->sq_rpt;
311				if (sq > 64)
312					sq = 0;
313				else if (sq < 20)
314					sq = 100;
315				else
316					sq = ((64 - sq) * 100) / 44;
317			}
318
319			pstats->signalquality = sq;
320			pstats->rx_mimo_signalquality[0] = sq;
321			pstats->rx_mimo_signalquality[1] = -1;
322		}
323	} else {
324		rtlpriv->dm.rfpath_rxenable[0] =
325		    rtlpriv->dm.rfpath_rxenable[1] = true;
326		for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
327			if (rtlpriv->dm.rfpath_rxenable[i])
328				rf_rx_num++;
329
330			rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
331				    0x3f) * 2) - 110;
332			rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]);
333			total_rssi += rssi;
334			rtlpriv->stats.rx_snr_db[i] =
335					 (long)(p_drvinfo->rxsnr[i] / 2);
336
337			if (packet_match_bssid)
338				pstats->rx_mimo_signalstrength[i] = (u8) rssi;
339		}
340
341		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
342		pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
343		pstats->rx_pwdb_all = pwdb_all;
344		pstats->rxpower = rx_pwr_all;
345		pstats->recvsignalpower = rx_pwr_all;
346
347		if (GET_RX_STATUS_DESC_RX_HT(pdesc) &&
348			GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 &&
349		    GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15)
350			max_spatial_stream = 2;
351		else
352			max_spatial_stream = 1;
353
354		for (i = 0; i < max_spatial_stream; i++) {
355			evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]);
356
357			if (packet_match_bssid) {
358				if (i == 0)
359					pstats->signalquality = (u8)(evm &
360								 0xff);
361				pstats->rx_mimo_signalquality[i] =
362							 (u8) (evm & 0xff);
363			}
364		}
365	}
366
367	if (is_cck_rate)
368		pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
369					 pwdb_all));
370	else if (rf_rx_num != 0)
371		pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw,
372				total_rssi /= rf_rx_num));
373}
374
375static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
376				     struct rtl_stats *pstats)
377{
378	struct rtl_priv *rtlpriv = rtl_priv(hw);
379	struct rtl_phy *rtlphy = &(rtlpriv->phy);
380	u8 rfpath;
381	u32 last_rssi, tmpval;
382
383	if (pstats->packet_toself || pstats->packet_beacon) {
384		rtlpriv->stats.rssi_calculate_cnt++;
385
386		if (rtlpriv->stats.ui_rssi.total_num++ >=
387		    PHY_RSSI_SLID_WIN_MAX) {
388			rtlpriv->stats.ui_rssi.total_num =
389					 PHY_RSSI_SLID_WIN_MAX;
390			last_rssi = rtlpriv->stats.ui_rssi.elements[
391				rtlpriv->stats.ui_rssi.index];
392			rtlpriv->stats.ui_rssi.total_val -= last_rssi;
393		}
394
395		rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
396		rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
397			 = pstats->signalstrength;
398
399		if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
400			rtlpriv->stats.ui_rssi.index = 0;
401
402		tmpval = rtlpriv->stats.ui_rssi.total_val /
403			rtlpriv->stats.ui_rssi.total_num;
404		rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
405								(u8) tmpval);
406		pstats->rssi = rtlpriv->stats.signal_strength;
407	}
408
409	if (!pstats->is_cck && pstats->packet_toself) {
410		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
411		     rfpath++) {
412			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
413				rtlpriv->stats.rx_rssi_percentage[rfpath] =
414				    pstats->rx_mimo_signalstrength[rfpath];
415
416			}
417
418			if (pstats->rx_mimo_signalstrength[rfpath] >
419			    rtlpriv->stats.rx_rssi_percentage[rfpath]) {
420				rtlpriv->stats.rx_rssi_percentage[rfpath] =
421				    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
422				    * (RX_SMOOTH_FACTOR - 1)) +
423				    (pstats->rx_mimo_signalstrength[rfpath])) /
424				    (RX_SMOOTH_FACTOR);
425
426				rtlpriv->stats.rx_rssi_percentage[rfpath] =
427				    rtlpriv->stats.rx_rssi_percentage[rfpath]
428				    + 1;
429			} else {
430				rtlpriv->stats.rx_rssi_percentage[rfpath] =
431				    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
432				    * (RX_SMOOTH_FACTOR - 1)) +
433				    (pstats->rx_mimo_signalstrength[rfpath])) /
434				    (RX_SMOOTH_FACTOR);
435			}
436
437		}
438	}
439}
440
441static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
442					       struct rtl_stats *pstats)
443{
444	struct rtl_priv *rtlpriv = rtl_priv(hw);
445	int weighting = 0;
446
447	if (rtlpriv->stats.recv_signal_power == 0)
448		rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
449
450	if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
451		weighting = 5;
452	else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
453		weighting = (-5);
454
455	rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
456					   + pstats->recvsignalpower +
457					   weighting) / 6;
458}
459
460static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
461				  struct rtl_stats *pstats)
462{
463	struct rtl_priv *rtlpriv = rtl_priv(hw);
464	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
465	long undec_sm_pwdb = 0;
466
467	if (mac->opmode == NL80211_IFTYPE_ADHOC) {
468		return;
469	} else {
470		undec_sm_pwdb =
471		    rtlpriv->dm.undecorated_smoothed_pwdb;
472	}
473
474	if (pstats->packet_toself || pstats->packet_beacon) {
475		if (undec_sm_pwdb < 0)
476			undec_sm_pwdb = pstats->rx_pwdb_all;
477
478		if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
479			undec_sm_pwdb =
480			    (((undec_sm_pwdb) *
481			    (RX_SMOOTH_FACTOR - 1)) +
482			    (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
483
484			undec_sm_pwdb = undec_sm_pwdb + 1;
485		} else {
486			undec_sm_pwdb = (((undec_sm_pwdb) *
487			      (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
488			      (RX_SMOOTH_FACTOR);
489		}
490
491		rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb;
492		_rtl92se_update_rxsignalstatistics(hw, pstats);
493	}
494}
495
496static void rtl_92s_process_streams(struct ieee80211_hw *hw,
497				    struct rtl_stats *pstats)
498{
499	struct rtl_priv *rtlpriv = rtl_priv(hw);
500	u32 stream;
501
502	for (stream = 0; stream < 2; stream++) {
503		if (pstats->rx_mimo_signalquality[stream] != -1) {
504			if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
505				rtlpriv->stats.rx_evm_percentage[stream] =
506				    pstats->rx_mimo_signalquality[stream];
507			}
508
509			rtlpriv->stats.rx_evm_percentage[stream] =
510			    ((rtlpriv->stats.rx_evm_percentage[stream] *
511					(RX_SMOOTH_FACTOR - 1)) +
512			     (pstats->rx_mimo_signalquality[stream] *
513					1)) / (RX_SMOOTH_FACTOR);
514		}
515	}
516}
517
518static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
519					     struct rtl_stats *pstats)
520{
521	struct rtl_priv *rtlpriv = rtl_priv(hw);
522	u32 last_evm = 0, tmpval;
523
524	if (pstats->signalquality != 0) {
525		if (pstats->packet_toself || pstats->packet_beacon) {
526
527			if (rtlpriv->stats.ui_link_quality.total_num++ >=
528			    PHY_LINKQUALITY_SLID_WIN_MAX) {
529				rtlpriv->stats.ui_link_quality.total_num =
530				    PHY_LINKQUALITY_SLID_WIN_MAX;
531				last_evm =
532				    rtlpriv->stats.ui_link_quality.elements[
533				    rtlpriv->stats.ui_link_quality.index];
534				rtlpriv->stats.ui_link_quality.total_val -=
535				    last_evm;
536			}
537
538			rtlpriv->stats.ui_link_quality.total_val +=
539			    pstats->signalquality;
540			rtlpriv->stats.ui_link_quality.elements[
541				rtlpriv->stats.ui_link_quality.index++] =
542			    pstats->signalquality;
543
544			if (rtlpriv->stats.ui_link_quality.index >=
545			    PHY_LINKQUALITY_SLID_WIN_MAX)
546				rtlpriv->stats.ui_link_quality.index = 0;
547
548			tmpval = rtlpriv->stats.ui_link_quality.total_val /
549			    rtlpriv->stats.ui_link_quality.total_num;
550			rtlpriv->stats.signal_quality = tmpval;
551
552			rtlpriv->stats.last_sigstrength_inpercent = tmpval;
553
554			rtl_92s_process_streams(hw, pstats);
555
556		}
557	}
558}
559
560static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
561				     u8 *buffer,
562				     struct rtl_stats *pcurrent_stats)
563{
564
565	if (!pcurrent_stats->packet_matchbssid &&
566	    !pcurrent_stats->packet_beacon)
567		return;
568
569	_rtl92se_process_ui_rssi(hw, pcurrent_stats);
570	_rtl92se_process_pwdb(hw, pcurrent_stats);
571	_rtl92se_process_ui_link_quality(hw, pcurrent_stats);
572}
573
574static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
575		struct sk_buff *skb, struct rtl_stats *pstats,
576		u8 *pdesc, struct rx_fwinfo *p_drvinfo)
577{
578	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
579	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
580
581	struct ieee80211_hdr *hdr;
582	u8 *tmp_buf;
583	u8 *praddr;
584	__le16 fc;
585	u16 type, cfc;
586	bool packet_matchbssid, packet_toself, packet_beacon;
587
588	tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
589
590	hdr = (struct ieee80211_hdr *)tmp_buf;
591	fc = hdr->frame_control;
592	cfc = le16_to_cpu(fc);
593	type = WLAN_FC_GET_TYPE(fc);
594	praddr = hdr->addr1;
595
596	packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
597	     (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
598			hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
599			hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
600			(!pstats->crc) && (!pstats->icv));
 
601
602	packet_toself = packet_matchbssid &&
603	    (!compare_ether_addr(praddr, rtlefuse->dev_addr));
604
605	if (ieee80211_is_beacon(fc))
606		packet_beacon = true;
607
608	_rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
609			packet_matchbssid, packet_toself, packet_beacon);
610	_rtl92se_process_phyinfo(hw, tmp_buf, pstats);
611}
612
613bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
614			   struct ieee80211_rx_status *rx_status, u8 *pdesc,
615			   struct sk_buff *skb)
616{
617	struct rx_fwinfo *p_drvinfo;
618	u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
 
 
619
620	stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
621	stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
622	stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
623	stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
624	stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
625	stats->hwerror = (u16)(stats->crc | stats->icv);
626	stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
627
628	stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
629	stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
630	stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
 
 
631	stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
632	stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
 
 
633
634	if (stats->hwerror)
635		return false;
636
637	rx_status->freq = hw->conf.channel->center_freq;
638	rx_status->band = hw->conf.channel->band;
639
640	if (GET_RX_STATUS_DESC_CRC32(pdesc))
641		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
642
643	if (!GET_RX_STATUS_DESC_SWDEC(pdesc))
644		rx_status->flag |= RX_FLAG_DECRYPTED;
645
646	if (GET_RX_STATUS_DESC_BW(pdesc))
647		rx_status->flag |= RX_FLAG_40MHZ;
648
649	if (GET_RX_STATUS_DESC_RX_HT(pdesc))
650		rx_status->flag |= RX_FLAG_HT;
651
652	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
653
654	if (stats->decrypted)
655		rx_status->flag |= RX_FLAG_DECRYPTED;
656
657	rx_status->rate_idx = _rtl92se_rate_mapping((bool)
658			GET_RX_STATUS_DESC_RX_HT(pdesc),
659			(u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
660			(bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
661
 
 
662
663	rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc);
664	if (phystatus) {
665		p_drvinfo = (struct rx_fwinfo *)(skb->data +
666						 stats->rx_bufshift);
667		_rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
668						   p_drvinfo);
669	}
670
671	/*rx_status->qual = stats->signal; */
672	rx_status->signal = stats->rssi + 10;
673	/*rx_status->noise = -stats->noise; */
674
675	return true;
676}
677
678void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
679		struct ieee80211_hdr *hdr, u8 *pdesc_tx,
680		struct ieee80211_tx_info *info, struct sk_buff *skb,
 
 
681		u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
682{
683	struct rtl_priv *rtlpriv = rtl_priv(hw);
684	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
685	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
686	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
687	struct ieee80211_sta *sta = info->control.sta;
688	u8 *pdesc = (u8 *) pdesc_tx;
689	u16 seq_number;
690	__le16 fc = hdr->frame_control;
691	u8 reserved_macid = 0;
692	u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
693	bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
694	bool lastseg = (!(hdr->frame_control &
695			cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
696	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
697		    PCI_DMA_TODEVICE);
698	u8 bw_40 = 0;
699
 
 
 
 
 
700	if (mac->opmode == NL80211_IFTYPE_STATION) {
701		bw_40 = mac->bw_40;
702	} else if (mac->opmode == NL80211_IFTYPE_AP ||
703		mac->opmode == NL80211_IFTYPE_ADHOC) {
704		if (sta)
705			bw_40 = sta->ht_cap.cap &
706				    IEEE80211_HT_CAP_SUP_WIDTH_20_40;
707	}
708
709	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
710
711	rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
712
713	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
714
 
 
 
 
 
715	if (firstseg) {
716		if (rtlpriv->dm.useramask) {
717			/* set txdesc macId */
718			if (ptcb_desc->mac_id < 32) {
719				SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
720				reserved_macid |= ptcb_desc->mac_id;
721			}
722		}
723		SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
724
725		SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
726				 DESC92S_RATEMCS0) ? 1 : 0));
727
728		if (rtlhal->version == VERSION_8192S_ACUT) {
729			if (ptcb_desc->hw_rate == DESC92S_RATE1M ||
730				ptcb_desc->hw_rate  == DESC92S_RATE2M ||
731				ptcb_desc->hw_rate == DESC92S_RATE5_5M ||
732				ptcb_desc->hw_rate == DESC92S_RATE11M) {
733				ptcb_desc->hw_rate = DESC92S_RATE12M;
734			}
735		}
736
737		SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
738
739		if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
740			SET_TX_DESC_TX_SHORT(pdesc, 0);
741
742		/* Aggregation related */
743		if (info->flags & IEEE80211_TX_CTL_AMPDU)
744			SET_TX_DESC_AGG_ENABLE(pdesc, 1);
745
746		/* For AMPDU, we must insert SSN into TX_DESC */
747		SET_TX_DESC_SEQ(pdesc, seq_number);
748
749		/* Protection mode related */
750		/* For 92S, if RTS/CTS are set, HW will execute RTS. */
751		/* We choose only one protection mode to execute */
752		SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
753				!ptcb_desc->cts_enable) ? 1 : 0));
754		SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
755				       1 : 0));
756		SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
757
758		SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
759		SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
760		SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
761		SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
762		       DESC92S_RATE54M) ?
763		       (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
764		       : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
765
766
767		/* Set Bandwidth and sub-channel settings. */
768		if (bw_40) {
769			if (ptcb_desc->packet_bw) {
770				SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
771				/* use duplicated mode */
772				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
773			} else {
774				SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
775				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
776						   mac->cur_40_prime_sc);
777			}
778		} else {
779			SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
780			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
781		}
782
783		/* 3 Fill necessary field in First Descriptor */
784		/*DWORD 0*/
785		SET_TX_DESC_LINIP(pdesc, 0);
786		SET_TX_DESC_OFFSET(pdesc, 32);
787		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
788
789		/*DWORD 1*/
790		SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
791
792		/* Fill security related */
793		if (info->control.hw_key) {
794			struct ieee80211_key_conf *keyconf;
795
796			keyconf = info->control.hw_key;
797			switch (keyconf->cipher) {
798			case WLAN_CIPHER_SUITE_WEP40:
799			case WLAN_CIPHER_SUITE_WEP104:
800				SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
801				break;
802			case WLAN_CIPHER_SUITE_TKIP:
803				SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
804				break;
805			case WLAN_CIPHER_SUITE_CCMP:
806				SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
807				break;
808			default:
809				SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
810				break;
811
812			}
813		}
814
815		/* Set Packet ID */
816		SET_TX_DESC_PACKET_ID(pdesc, 0);
817
818		/* We will assign magement queue to BK. */
819		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
820
821		/* Alwasy enable all rate fallback range */
822		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
823
824		/* Fix: I don't kown why hw use 6.5M to tx when set it */
825		SET_TX_DESC_USER_RATE(pdesc,
826				      ptcb_desc->use_driver_rate ? 1 : 0);
827
828		/* Set NON_QOS bit. */
829		if (!ieee80211_is_data_qos(fc))
830			SET_TX_DESC_NON_QOS(pdesc, 1);
831
832	}
833
834	/* Fill fields that are required to be initialized
835	 * in all of the descriptors */
836	/*DWORD 0 */
837	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
838	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
839
840	/* DWORD 7 */
841	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
842
843	/* DOWRD 8 */
844	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
845
846	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
847}
848
849void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
850	bool firstseg, bool lastseg, struct sk_buff *skb)
851{
 
852	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
853	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
854	struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
855
856	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
857			PCI_DMA_TODEVICE);
858
859    /* Clear all status	*/
 
 
 
 
 
860	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
861
862	/* This bit indicate this packet is used for FW download. */
863	if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
864		/* For firmware downlaod we only need to set LINIP */
865		SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
866
867		/* 92SE must set as 1 for firmware download HW DMA error */
868		SET_TX_DESC_FIRST_SEG(pdesc, 1);
869		SET_TX_DESC_LAST_SEG(pdesc, 1);
870
871		/* 92SE need not to set TX packet size when firmware download */
872		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
873		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
874		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
875
876		wmb();
877		SET_TX_DESC_OWN(pdesc, 1);
878	} else { /* H2C Command Desc format (Host TXCMD) */
879		/* 92SE must set as 1 for firmware download HW DMA error */
880		SET_TX_DESC_FIRST_SEG(pdesc, 1);
881		SET_TX_DESC_LAST_SEG(pdesc, 1);
882
883		SET_TX_DESC_OFFSET(pdesc, 0x20);
884
885		/* Buffer size + command header */
886		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
887		/* Fixed queue of H2C command */
888		SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
889
890		SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
891
892		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
893		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
894
895		wmb();
896		SET_TX_DESC_OWN(pdesc, 1);
897
898	}
899}
900
901void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 
902{
903	if (istx) {
904		switch (desc_name) {
905		case HW_DESC_OWN:
906			wmb();
907			SET_TX_DESC_OWN(pdesc, 1);
908			break;
909		case HW_DESC_TX_NEXTDESC_ADDR:
910			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
911			break;
912		default:
913			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
914				  desc_name));
915			break;
916		}
917	} else {
918		switch (desc_name) {
919		case HW_DESC_RXOWN:
920			wmb();
921			SET_RX_STATUS_DESC_OWN(pdesc, 1);
922			break;
923		case HW_DESC_RXBUFF_ADDR:
924			SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
925			break;
926		case HW_DESC_RXPKT_LEN:
927			SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
928			break;
929		case HW_DESC_RXERO:
930			SET_RX_STATUS_DESC_EOR(pdesc, 1);
931			break;
932		default:
933			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
934				  desc_name));
935			break;
936		}
937	}
938}
939
940u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
941{
942	u32 ret = 0;
943
944	if (istx) {
945		switch (desc_name) {
946		case HW_DESC_OWN:
947			ret = GET_TX_DESC_OWN(desc);
948			break;
949		case HW_DESC_TXBUFF_ADDR:
950			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
951			break;
952		default:
953			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
954				  desc_name));
955			break;
956		}
957	} else {
958		switch (desc_name) {
959		case HW_DESC_OWN:
960			ret = GET_RX_STATUS_DESC_OWN(desc);
961			break;
962		case HW_DESC_RXPKT_LEN:
963			ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
964			break;
965		default:
966			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
967				  desc_name));
968			break;
969		}
970	}
971	return ret;
972}
973
974void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
975{
976	struct rtl_priv *rtlpriv = rtl_priv(hw);
977	rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
978}
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 "fw.h"
 38#include "trx.h"
 39#include "led.h"
 40
 41static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,	u8 skb_queue)
 42{
 43	__le16 fc = rtl_get_fc(skb);
 44
 45	if (unlikely(ieee80211_is_beacon(fc)))
 46		return QSLT_BEACON;
 47	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
 48		return QSLT_MGNT;
 49	if (ieee80211_is_nullfunc(fc))
 50		return QSLT_HIGH;
 51
 52	/* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
 53	 * queue V0 at priority 7; however, the RTL8192SE appears to have
 54	 * that queue at priority 6
 55	 */
 56	if (skb->priority == 7)
 57		return QSLT_VO;
 58	return skb->priority;
 59}
 60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 61static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
 62				       struct rtl_stats *pstats, u8 *pdesc,
 63				       struct rx_fwinfo *p_drvinfo,
 64				       bool packet_match_bssid,
 65				       bool packet_toself,
 66				       bool packet_beacon)
 67{
 68	struct rtl_priv *rtlpriv = rtl_priv(hw);
 69	struct phy_sts_cck_8192s_t *cck_buf;
 70	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 71	s8 rx_pwr_all = 0, rx_pwr[4];
 72	u8 rf_rx_num = 0, evm, pwdb_all;
 73	u8 i, max_spatial_stream;
 74	u32 rssi, total_rssi = 0;
 75	bool is_cck = pstats->is_cck;
 
 76
 
 77	pstats->packet_matchbssid = packet_match_bssid;
 78	pstats->packet_toself = packet_toself;
 
 79	pstats->packet_beacon = packet_beacon;
 80	pstats->rx_mimo_sig_qual[0] = -1;
 81	pstats->rx_mimo_sig_qual[1] = -1;
 
 82
 83	if (is_cck) {
 84		u8 report, cck_highpwr;
 85		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 86
 87		if (ppsc->rfpwr_state == ERFON)
 88			cck_highpwr = (u8) rtl_get_bbreg(hw,
 89						RFPGA0_XA_HSSIPARAMETER2,
 90						0x200);
 91		else
 92			cck_highpwr = false;
 93
 94		if (!cck_highpwr) {
 95			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 96			report = cck_buf->cck_agc_rpt & 0xc0;
 97			report = report >> 6;
 98			switch (report) {
 99			case 0x3:
100				rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
101				break;
102			case 0x2:
103				rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
104				break;
105			case 0x1:
106				rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
107				break;
108			case 0x0:
109				rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
110				break;
111			}
112		} else {
113			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
114			report = p_drvinfo->cfosho[0] & 0x60;
115			report = report >> 5;
116			switch (report) {
117			case 0x3:
118				rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
119				break;
120			case 0x2:
121				rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
122				break;
123			case 0x1:
124				rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
125				break;
126			case 0x0:
127				rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
128				break;
129			}
130		}
131
132		pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
133
134		/* CCK gain is smaller than OFDM/MCS gain,  */
135		/* so we add gain diff by experiences, the val is 6 */
136		pwdb_all += 6;
137		if (pwdb_all > 100)
138			pwdb_all = 100;
139		/* modify the offset to make the same gain index with OFDM. */
140		if (pwdb_all > 34 && pwdb_all <= 42)
141			pwdb_all -= 2;
142		else if (pwdb_all > 26 && pwdb_all <= 34)
143			pwdb_all -= 6;
144		else if (pwdb_all > 14 && pwdb_all <= 26)
145			pwdb_all -= 8;
146		else if (pwdb_all > 4 && pwdb_all <= 14)
147			pwdb_all -= 4;
148
149		pstats->rx_pwdb_all = pwdb_all;
150		pstats->recvsignalpower = rx_pwr_all;
151
152		if (packet_match_bssid) {
153			u8 sq;
154			if (pstats->rx_pwdb_all > 40) {
155				sq = 100;
156			} else {
157				sq = cck_buf->sq_rpt;
158				if (sq > 64)
159					sq = 0;
160				else if (sq < 20)
161					sq = 100;
162				else
163					sq = ((64 - sq) * 100) / 44;
164			}
165
166			pstats->signalquality = sq;
167			pstats->rx_mimo_sig_qual[0] = sq;
168			pstats->rx_mimo_sig_qual[1] = -1;
169		}
170	} else {
171		rtlpriv->dm.rfpath_rxenable[0] =
172		    rtlpriv->dm.rfpath_rxenable[1] = true;
173		for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
174			if (rtlpriv->dm.rfpath_rxenable[i])
175				rf_rx_num++;
176
177			rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
178				    0x3f) * 2) - 110;
179			rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
180			total_rssi += rssi;
181			rtlpriv->stats.rx_snr_db[i] =
182					 (long)(p_drvinfo->rxsnr[i] / 2);
183
184			if (packet_match_bssid)
185				pstats->rx_mimo_signalstrength[i] = (u8) rssi;
186		}
187
188		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
189		pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
190		pstats->rx_pwdb_all = pwdb_all;
191		pstats->rxpower = rx_pwr_all;
192		pstats->recvsignalpower = rx_pwr_all;
193
194		if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
195		    pstats->rate <= DESC92_RATEMCS15)
 
196			max_spatial_stream = 2;
197		else
198			max_spatial_stream = 1;
199
200		for (i = 0; i < max_spatial_stream; i++) {
201			evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
202
203			if (packet_match_bssid) {
204				if (i == 0)
205					pstats->signalquality = (u8)(evm &
206								 0xff);
207				pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
 
208			}
209		}
210	}
211
212	if (is_cck)
213		pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
214					 pwdb_all));
215	else if (rf_rx_num != 0)
216		pstats->signalstrength = (u8) (rtl_signal_scale_mapping(hw,
217				total_rssi /= rf_rx_num));
218}
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
221		struct sk_buff *skb, struct rtl_stats *pstats,
222		u8 *pdesc, struct rx_fwinfo *p_drvinfo)
223{
224	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
225	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
226
227	struct ieee80211_hdr *hdr;
228	u8 *tmp_buf;
229	u8 *praddr;
230	__le16 fc;
231	u16 type, cfc;
232	bool packet_matchbssid, packet_toself, packet_beacon = false;
233
234	tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
235
236	hdr = (struct ieee80211_hdr *)tmp_buf;
237	fc = hdr->frame_control;
238	cfc = le16_to_cpu(fc);
239	type = WLAN_FC_GET_TYPE(fc);
240	praddr = hdr->addr1;
241
242	packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
243	     ether_addr_equal(mac->bssid,
244			      (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
245			      (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
246			      hdr->addr3) &&
247	     (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
248
249	packet_toself = packet_matchbssid &&
250	    ether_addr_equal(praddr, rtlefuse->dev_addr);
251
252	if (ieee80211_is_beacon(fc))
253		packet_beacon = true;
254
255	_rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
256			packet_matchbssid, packet_toself, packet_beacon);
257	rtl_process_phyinfo(hw, tmp_buf, pstats);
258}
259
260bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
261			   struct ieee80211_rx_status *rx_status, u8 *pdesc,
262			   struct sk_buff *skb)
263{
264	struct rx_fwinfo *p_drvinfo;
265	u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
266	struct ieee80211_hdr *hdr;
267	bool first_ampdu = false;
268
269	stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
270	stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
271	stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
272	stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
273	stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
274	stats->hwerror = (u16)(stats->crc | stats->icv);
275	stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
276
277	stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
278	stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
279	stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
280	stats->isfirst_ampdu = (bool) ((GET_RX_STATUS_DESC_PAGGR(pdesc) == 1)
281			       && (GET_RX_STATUS_DESC_FAGGR(pdesc) == 1));
282	stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
283	stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
284	stats->is_ht = (bool)GET_RX_STATUS_DESC_RX_HT(pdesc);
285	stats->is_cck = SE_RX_HAL_IS_CCK_RATE(pdesc);
286
287	if (stats->hwerror)
288		return false;
289
290	rx_status->freq = hw->conf.chandef.chan->center_freq;
291	rx_status->band = hw->conf.chandef.chan->band;
292
293	if (stats->crc)
294		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
295
296	if (stats->rx_is40Mhzpacket)
 
 
 
297		rx_status->flag |= RX_FLAG_40MHZ;
298
299	if (stats->is_ht)
300		rx_status->flag |= RX_FLAG_HT;
301
302	rx_status->flag |= RX_FLAG_MACTIME_START;
 
 
 
303
304	/* hw will set stats->decrypted true, if it finds the
305	 * frame is open data frame or mgmt frame,
306	 * hw will not decrypt robust managment frame
307	 * for IEEE80211w but still set stats->decrypted
308	 * true, so here we should set it back to undecrypted
309	 * for IEEE80211w frame, and mac80211 sw will help
310	 * to decrypt it */
311	if (stats->decrypted) {
312		hdr = (struct ieee80211_hdr *)(skb->data +
313		       stats->rx_drvinfo_size + stats->rx_bufshift);
314
315		if (!hdr) {
316			/* during testing, hdr was NULL here */
317			return false;
318		}
319		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
320			(ieee80211_has_protected(hdr->frame_control)))
321			rx_status->flag &= ~RX_FLAG_DECRYPTED;
322		else
323			rx_status->flag |= RX_FLAG_DECRYPTED;
324	}
325
326	rx_status->rate_idx = rtlwifi_rate_mapping(hw,
327			      stats->is_ht, stats->rate, first_ampdu);
328
329	rx_status->mactime = stats->timestamp_low;
330	if (phystatus) {
331		p_drvinfo = (struct rx_fwinfo *)(skb->data +
332						 stats->rx_bufshift);
333		_rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
334						   p_drvinfo);
335	}
336
337	/*rx_status->qual = stats->signal; */
338	rx_status->signal = stats->recvsignalpower + 10;
 
339
340	return true;
341}
342
343void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
344		struct ieee80211_hdr *hdr, u8 *pdesc_tx,
345		u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
346		struct ieee80211_sta *sta,
347		struct sk_buff *skb,
348		u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
349{
350	struct rtl_priv *rtlpriv = rtl_priv(hw);
351	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
352	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
353	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
354	u8 *pdesc = pdesc_tx;
 
355	u16 seq_number;
356	__le16 fc = hdr->frame_control;
357	u8 reserved_macid = 0;
358	u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
359	bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
360	bool lastseg = (!(hdr->frame_control &
361			cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
362	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
363		    PCI_DMA_TODEVICE);
364	u8 bw_40 = 0;
365
366	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
367		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
368			 "DMA mapping error");
369		return;
370	}
371	if (mac->opmode == NL80211_IFTYPE_STATION) {
372		bw_40 = mac->bw_40;
373	} else if (mac->opmode == NL80211_IFTYPE_AP ||
374		mac->opmode == NL80211_IFTYPE_ADHOC) {
375		if (sta)
376			bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 
377	}
378
379	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
380
381	rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
382
383	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
384
385	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
386		firstseg = true;
387		lastseg = true;
388	}
389
390	if (firstseg) {
391		if (rtlpriv->dm.useramask) {
392			/* set txdesc macId */
393			if (ptcb_desc->mac_id < 32) {
394				SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
395				reserved_macid |= ptcb_desc->mac_id;
396			}
397		}
398		SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
399
400		SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
401				 DESC92_RATEMCS0) ? 1 : 0));
402
403		if (rtlhal->version == VERSION_8192S_ACUT) {
404			if (ptcb_desc->hw_rate == DESC92_RATE1M ||
405				ptcb_desc->hw_rate  == DESC92_RATE2M ||
406				ptcb_desc->hw_rate == DESC92_RATE5_5M ||
407				ptcb_desc->hw_rate == DESC92_RATE11M) {
408				ptcb_desc->hw_rate = DESC92_RATE12M;
409			}
410		}
411
412		SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
413
414		if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
415			SET_TX_DESC_TX_SHORT(pdesc, 0);
416
417		/* Aggregation related */
418		if (info->flags & IEEE80211_TX_CTL_AMPDU)
419			SET_TX_DESC_AGG_ENABLE(pdesc, 1);
420
421		/* For AMPDU, we must insert SSN into TX_DESC */
422		SET_TX_DESC_SEQ(pdesc, seq_number);
423
424		/* Protection mode related */
425		/* For 92S, if RTS/CTS are set, HW will execute RTS. */
426		/* We choose only one protection mode to execute */
427		SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
428				!ptcb_desc->cts_enable) ? 1 : 0));
429		SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
430				       1 : 0));
431		SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
432
433		SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
434		SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
435		SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
436		SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
437		       DESC92_RATE54M) ?
438		       (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
439		       : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
440
441
442		/* Set Bandwidth and sub-channel settings. */
443		if (bw_40) {
444			if (ptcb_desc->packet_bw) {
445				SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
446				/* use duplicated mode */
447				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
448			} else {
449				SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
450				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
451						   mac->cur_40_prime_sc);
452			}
453		} else {
454			SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
455			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
456		}
457
458		/* 3 Fill necessary field in First Descriptor */
459		/*DWORD 0*/
460		SET_TX_DESC_LINIP(pdesc, 0);
461		SET_TX_DESC_OFFSET(pdesc, 32);
462		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
463
464		/*DWORD 1*/
465		SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
466
467		/* Fill security related */
468		if (info->control.hw_key) {
469			struct ieee80211_key_conf *keyconf;
470
471			keyconf = info->control.hw_key;
472			switch (keyconf->cipher) {
473			case WLAN_CIPHER_SUITE_WEP40:
474			case WLAN_CIPHER_SUITE_WEP104:
475				SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
476				break;
477			case WLAN_CIPHER_SUITE_TKIP:
478				SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
479				break;
480			case WLAN_CIPHER_SUITE_CCMP:
481				SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
482				break;
483			default:
484				SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
485				break;
486
487			}
488		}
489
490		/* Set Packet ID */
491		SET_TX_DESC_PACKET_ID(pdesc, 0);
492
493		/* We will assign magement queue to BK. */
494		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
495
496		/* Alwasy enable all rate fallback range */
497		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
498
499		/* Fix: I don't kown why hw use 6.5M to tx when set it */
500		SET_TX_DESC_USER_RATE(pdesc,
501				      ptcb_desc->use_driver_rate ? 1 : 0);
502
503		/* Set NON_QOS bit. */
504		if (!ieee80211_is_data_qos(fc))
505			SET_TX_DESC_NON_QOS(pdesc, 1);
506
507	}
508
509	/* Fill fields that are required to be initialized
510	 * in all of the descriptors */
511	/*DWORD 0 */
512	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
513	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
514
515	/* DWORD 7 */
516	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
517
518	/* DOWRD 8 */
519	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
520
521	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
522}
523
524void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
525	bool firstseg, bool lastseg, struct sk_buff *skb)
526{
527	struct rtl_priv *rtlpriv = rtl_priv(hw);
528	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
529	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
530	struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
531
532	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
533			PCI_DMA_TODEVICE);
534
535	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
536		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
537			 "DMA mapping error");
538		return;
539	}
540	/* Clear all status	*/
541	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
542
543	/* This bit indicate this packet is used for FW download. */
544	if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
545		/* For firmware downlaod we only need to set LINIP */
546		SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
547
548		/* 92SE must set as 1 for firmware download HW DMA error */
549		SET_TX_DESC_FIRST_SEG(pdesc, 1);
550		SET_TX_DESC_LAST_SEG(pdesc, 1);
551
552		/* 92SE need not to set TX packet size when firmware download */
553		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
554		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
555		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
556
557		wmb();
558		SET_TX_DESC_OWN(pdesc, 1);
559	} else { /* H2C Command Desc format (Host TXCMD) */
560		/* 92SE must set as 1 for firmware download HW DMA error */
561		SET_TX_DESC_FIRST_SEG(pdesc, 1);
562		SET_TX_DESC_LAST_SEG(pdesc, 1);
563
564		SET_TX_DESC_OFFSET(pdesc, 0x20);
565
566		/* Buffer size + command header */
567		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
568		/* Fixed queue of H2C command */
569		SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
570
571		SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
572
573		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
574		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
575
576		wmb();
577		SET_TX_DESC_OWN(pdesc, 1);
578
579	}
580}
581
582void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
583		      u8 desc_name, u8 *val)
584{
585	if (istx) {
586		switch (desc_name) {
587		case HW_DESC_OWN:
588			wmb();
589			SET_TX_DESC_OWN(pdesc, 1);
590			break;
591		case HW_DESC_TX_NEXTDESC_ADDR:
592			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
593			break;
594		default:
595			RT_ASSERT(false, "ERR txdesc :%d not process\n",
596				  desc_name);
597			break;
598		}
599	} else {
600		switch (desc_name) {
601		case HW_DESC_RXOWN:
602			wmb();
603			SET_RX_STATUS_DESC_OWN(pdesc, 1);
604			break;
605		case HW_DESC_RXBUFF_ADDR:
606			SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
607			break;
608		case HW_DESC_RXPKT_LEN:
609			SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
610			break;
611		case HW_DESC_RXERO:
612			SET_RX_STATUS_DESC_EOR(pdesc, 1);
613			break;
614		default:
615			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
616				  desc_name);
617			break;
618		}
619	}
620}
621
622u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
623{
624	u32 ret = 0;
625
626	if (istx) {
627		switch (desc_name) {
628		case HW_DESC_OWN:
629			ret = GET_TX_DESC_OWN(desc);
630			break;
631		case HW_DESC_TXBUFF_ADDR:
632			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
633			break;
634		default:
635			RT_ASSERT(false, "ERR txdesc :%d not process\n",
636				  desc_name);
637			break;
638		}
639	} else {
640		switch (desc_name) {
641		case HW_DESC_OWN:
642			ret = GET_RX_STATUS_DESC_OWN(desc);
643			break;
644		case HW_DESC_RXPKT_LEN:
645			ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
646			break;
647		default:
648			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
649				  desc_name);
650			break;
651		}
652	}
653	return ret;
654}
655
656void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
657{
658	struct rtl_priv *rtlpriv = rtl_priv(hw);
659	rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
660}