1 /******************************************************************************
3 * Copyright(c) 2009-2012 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
35 static u8
_rtl92de_map_hwqueue_to_fwqueue(struct sk_buff
*skb
, u8 hw_queue
)
37 __le16 fc
= rtl_get_fc(skb
);
39 if (unlikely(ieee80211_is_beacon(fc
)))
41 if (ieee80211_is_mgmt(fc
))
47 static u8
_rtl92d_query_rxpwrpercentage(s8 antpower
)
49 if ((antpower
<= -100) || (antpower
>= 20))
51 else if (antpower
>= 0)
54 return 100 + antpower
;
57 static u8
_rtl92d_evm_db_to_percentage(s8 value
)
65 ret_val
= 0 - ret_val
;
72 static long _rtl92de_translate_todbm(struct ieee80211_hw
*hw
,
73 u8 signal_strength_index
)
77 signal_power
= (long)((signal_strength_index
+ 1) >> 1);
82 static long _rtl92de_signal_scale_mapping(struct ieee80211_hw
*hw
, long currsig
)
86 if (currsig
>= 61 && currsig
<= 100)
87 retsig
= 90 + ((currsig
- 60) / 4);
88 else if (currsig
>= 41 && currsig
<= 60)
89 retsig
= 78 + ((currsig
- 40) / 2);
90 else if (currsig
>= 31 && currsig
<= 40)
91 retsig
= 66 + (currsig
- 30);
92 else if (currsig
>= 21 && currsig
<= 30)
93 retsig
= 54 + (currsig
- 20);
94 else if (currsig
>= 5 && currsig
<= 20)
95 retsig
= 42 + (((currsig
- 5) * 2) / 3);
96 else if (currsig
== 4)
98 else if (currsig
== 3)
100 else if (currsig
== 2)
102 else if (currsig
== 1)
109 static void _rtl92de_query_rxphystatus(struct ieee80211_hw
*hw
,
110 struct rtl_stats
*pstats
,
111 struct rx_desc_92d
*pdesc
,
112 struct rx_fwinfo_92d
*p_drvinfo
,
113 bool packet_match_bssid
,
117 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
118 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtlpriv
);
119 struct phy_sts_cck_8192d
*cck_buf
;
120 s8 rx_pwr_all
, rx_pwr
[4];
121 u8 rf_rx_num
= 0, evm
, pwdb_all
;
122 u8 i
, max_spatial_stream
;
123 u32 rssi
, total_rssi
= 0;
126 is_cck_rate
= RX_HAL_IS_CCK_RATE(pdesc
->rxmcs
);
127 pstats
->packet_matchbssid
= packet_match_bssid
;
128 pstats
->packet_toself
= packet_toself
;
129 pstats
->packet_beacon
= packet_beacon
;
130 pstats
->is_cck
= is_cck_rate
;
131 pstats
->rx_mimo_sig_qual
[0] = -1;
132 pstats
->rx_mimo_sig_qual
[1] = -1;
135 u8 report
, cck_highpwr
;
136 cck_buf
= (struct phy_sts_cck_8192d
*)p_drvinfo
;
137 if (ppsc
->rfpwr_state
== ERFON
)
138 cck_highpwr
= (u8
) rtl_get_bbreg(hw
,
139 RFPGA0_XA_HSSIPARAMETER2
,
144 u8 cck_agc_rpt
= cck_buf
->cck_agc_rpt
;
145 report
= cck_buf
->cck_agc_rpt
& 0xc0;
146 report
= report
>> 6;
149 rx_pwr_all
= -46 - (cck_agc_rpt
& 0x3e);
152 rx_pwr_all
= -26 - (cck_agc_rpt
& 0x3e);
155 rx_pwr_all
= -12 - (cck_agc_rpt
& 0x3e);
158 rx_pwr_all
= 16 - (cck_agc_rpt
& 0x3e);
162 u8 cck_agc_rpt
= cck_buf
->cck_agc_rpt
;
163 report
= p_drvinfo
->cfosho
[0] & 0x60;
164 report
= report
>> 5;
167 rx_pwr_all
= -46 - ((cck_agc_rpt
& 0x1f) << 1);
170 rx_pwr_all
= -26 - ((cck_agc_rpt
& 0x1f) << 1);
173 rx_pwr_all
= -12 - ((cck_agc_rpt
& 0x1f) << 1);
176 rx_pwr_all
= 16 - ((cck_agc_rpt
& 0x1f) << 1);
180 pwdb_all
= _rtl92d_query_rxpwrpercentage(rx_pwr_all
);
181 /* CCK gain is smaller than OFDM/MCS gain, */
182 /* so we add gain diff by experiences, the val is 6 */
186 /* modify the offset to make the same gain index with OFDM. */
187 if (pwdb_all
> 34 && pwdb_all
<= 42)
189 else if (pwdb_all
> 26 && pwdb_all
<= 34)
191 else if (pwdb_all
> 14 && pwdb_all
<= 26)
193 else if (pwdb_all
> 4 && pwdb_all
<= 14)
195 pstats
->rx_pwdb_all
= pwdb_all
;
196 pstats
->recvsignalpower
= rx_pwr_all
;
197 if (packet_match_bssid
) {
199 if (pstats
->rx_pwdb_all
> 40) {
202 sq
= cck_buf
->sq_rpt
;
208 sq
= ((64 - sq
) * 100) / 44;
210 pstats
->signalquality
= sq
;
211 pstats
->rx_mimo_sig_qual
[0] = sq
;
212 pstats
->rx_mimo_sig_qual
[1] = -1;
215 rtlpriv
->dm
.rfpath_rxenable
[0] = true;
216 rtlpriv
->dm
.rfpath_rxenable
[1] = true;
217 for (i
= RF90_PATH_A
; i
< RF6052_MAX_PATH
; i
++) {
218 if (rtlpriv
->dm
.rfpath_rxenable
[i
])
220 rx_pwr
[i
] = ((p_drvinfo
->gain_trsw
[i
] & 0x3f) * 2)
222 rssi
= _rtl92d_query_rxpwrpercentage(rx_pwr
[i
]);
224 rtlpriv
->stats
.rx_snr_db
[i
] =
225 (long)(p_drvinfo
->rxsnr
[i
] / 2);
226 if (packet_match_bssid
)
227 pstats
->rx_mimo_signalstrength
[i
] = (u8
) rssi
;
229 rx_pwr_all
= ((p_drvinfo
->pwdb_all
>> 1) & 0x7f) - 106;
230 pwdb_all
= _rtl92d_query_rxpwrpercentage(rx_pwr_all
);
231 pstats
->rx_pwdb_all
= pwdb_all
;
232 pstats
->rxpower
= rx_pwr_all
;
233 pstats
->recvsignalpower
= rx_pwr_all
;
234 if (pdesc
->rxht
&& pdesc
->rxmcs
>= DESC_RATEMCS8
&&
235 pdesc
->rxmcs
<= DESC_RATEMCS15
)
236 max_spatial_stream
= 2;
238 max_spatial_stream
= 1;
239 for (i
= 0; i
< max_spatial_stream
; i
++) {
240 evm
= _rtl92d_evm_db_to_percentage(p_drvinfo
->rxevm
[i
]);
241 if (packet_match_bssid
) {
243 pstats
->signalquality
=
245 pstats
->rx_mimo_sig_qual
[i
] =
251 pstats
->signalstrength
= (u8
)(_rtl92de_signal_scale_mapping(hw
,
253 else if (rf_rx_num
!= 0)
254 pstats
->signalstrength
= (u8
)(_rtl92de_signal_scale_mapping(hw
,
255 total_rssi
/= rf_rx_num
));
258 static void rtl92d_loop_over_paths(struct ieee80211_hw
*hw
,
259 struct rtl_stats
*pstats
)
261 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
262 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
265 for (rfpath
= RF90_PATH_A
; rfpath
< rtlphy
->num_total_rfpath
;
267 if (rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] == 0) {
268 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
269 pstats
->rx_mimo_signalstrength
[rfpath
];
272 if (pstats
->rx_mimo_signalstrength
[rfpath
] >
273 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
]) {
274 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
275 ((rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] *
276 (RX_SMOOTH_FACTOR
- 1)) +
277 (pstats
->rx_mimo_signalstrength
[rfpath
])) /
279 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
280 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] + 1;
282 rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] =
283 ((rtlpriv
->stats
.rx_rssi_percentage
[rfpath
] *
284 (RX_SMOOTH_FACTOR
- 1)) +
285 (pstats
->rx_mimo_signalstrength
[rfpath
])) /
291 static void _rtl92de_process_ui_rssi(struct ieee80211_hw
*hw
,
292 struct rtl_stats
*pstats
)
294 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
295 u32 last_rssi
, tmpval
;
297 if (pstats
->packet_toself
|| pstats
->packet_beacon
) {
298 rtlpriv
->stats
.rssi_calculate_cnt
++;
299 if (rtlpriv
->stats
.ui_rssi
.total_num
++ >=
300 PHY_RSSI_SLID_WIN_MAX
) {
301 rtlpriv
->stats
.ui_rssi
.total_num
=
302 PHY_RSSI_SLID_WIN_MAX
;
303 last_rssi
= rtlpriv
->stats
.ui_rssi
.elements
[
304 rtlpriv
->stats
.ui_rssi
.index
];
305 rtlpriv
->stats
.ui_rssi
.total_val
-= last_rssi
;
307 rtlpriv
->stats
.ui_rssi
.total_val
+= pstats
->signalstrength
;
308 rtlpriv
->stats
.ui_rssi
.elements
309 [rtlpriv
->stats
.ui_rssi
.index
++] =
310 pstats
->signalstrength
;
311 if (rtlpriv
->stats
.ui_rssi
.index
>= PHY_RSSI_SLID_WIN_MAX
)
312 rtlpriv
->stats
.ui_rssi
.index
= 0;
313 tmpval
= rtlpriv
->stats
.ui_rssi
.total_val
/
314 rtlpriv
->stats
.ui_rssi
.total_num
;
315 rtlpriv
->stats
.signal_strength
= _rtl92de_translate_todbm(hw
,
317 pstats
->rssi
= rtlpriv
->stats
.signal_strength
;
319 if (!pstats
->is_cck
&& pstats
->packet_toself
)
320 rtl92d_loop_over_paths(hw
, pstats
);
323 static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw
*hw
,
324 struct rtl_stats
*pstats
)
326 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
329 if (rtlpriv
->stats
.recv_signal_power
== 0)
330 rtlpriv
->stats
.recv_signal_power
= pstats
->recvsignalpower
;
331 if (pstats
->recvsignalpower
> rtlpriv
->stats
.recv_signal_power
)
333 else if (pstats
->recvsignalpower
< rtlpriv
->stats
.recv_signal_power
)
335 rtlpriv
->stats
.recv_signal_power
= (rtlpriv
->stats
.recv_signal_power
*
336 5 + pstats
->recvsignalpower
+ weighting
) / 6;
339 static void _rtl92de_process_pwdb(struct ieee80211_hw
*hw
,
340 struct rtl_stats
*pstats
)
342 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
343 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
346 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
||
347 mac
->opmode
== NL80211_IFTYPE_AP
)
350 undec_sm_pwdb
= rtlpriv
->dm
.undec_sm_pwdb
;
352 if (pstats
->packet_toself
|| pstats
->packet_beacon
) {
353 if (undec_sm_pwdb
< 0)
354 undec_sm_pwdb
= pstats
->rx_pwdb_all
;
355 if (pstats
->rx_pwdb_all
> (u32
) undec_sm_pwdb
) {
356 undec_sm_pwdb
= (((undec_sm_pwdb
) *
357 (RX_SMOOTH_FACTOR
- 1)) +
358 (pstats
->rx_pwdb_all
)) / (RX_SMOOTH_FACTOR
);
359 undec_sm_pwdb
= undec_sm_pwdb
+ 1;
361 undec_sm_pwdb
= (((undec_sm_pwdb
) *
362 (RX_SMOOTH_FACTOR
- 1)) +
363 (pstats
->rx_pwdb_all
)) / (RX_SMOOTH_FACTOR
);
365 rtlpriv
->dm
.undec_sm_pwdb
= undec_sm_pwdb
;
366 _rtl92de_update_rxsignalstatistics(hw
, pstats
);
370 static void rtl92d_loop_over_streams(struct ieee80211_hw
*hw
,
371 struct rtl_stats
*pstats
)
373 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
376 for (stream
= 0; stream
< 2; stream
++) {
377 if (pstats
->rx_mimo_sig_qual
[stream
] != -1) {
378 if (rtlpriv
->stats
.rx_evm_percentage
[stream
] == 0) {
379 rtlpriv
->stats
.rx_evm_percentage
[stream
] =
380 pstats
->rx_mimo_sig_qual
[stream
];
382 rtlpriv
->stats
.rx_evm_percentage
[stream
] =
383 ((rtlpriv
->stats
.rx_evm_percentage
[stream
]
384 * (RX_SMOOTH_FACTOR
- 1)) +
385 (pstats
->rx_mimo_sig_qual
[stream
] * 1)) /
391 static void _rtl92de_process_ui_link_quality(struct ieee80211_hw
*hw
,
392 struct rtl_stats
*pstats
)
394 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
395 u32 last_evm
, tmpval
;
397 if (pstats
->signalquality
== 0)
399 if (pstats
->packet_toself
|| pstats
->packet_beacon
) {
400 if (rtlpriv
->stats
.ui_link_quality
.total_num
++ >=
401 PHY_LINKQUALITY_SLID_WIN_MAX
) {
402 rtlpriv
->stats
.ui_link_quality
.total_num
=
403 PHY_LINKQUALITY_SLID_WIN_MAX
;
404 last_evm
= rtlpriv
->stats
.ui_link_quality
.elements
[
405 rtlpriv
->stats
.ui_link_quality
.index
];
406 rtlpriv
->stats
.ui_link_quality
.total_val
-= last_evm
;
408 rtlpriv
->stats
.ui_link_quality
.total_val
+=
409 pstats
->signalquality
;
410 rtlpriv
->stats
.ui_link_quality
.elements
[
411 rtlpriv
->stats
.ui_link_quality
.index
++] =
412 pstats
->signalquality
;
413 if (rtlpriv
->stats
.ui_link_quality
.index
>=
414 PHY_LINKQUALITY_SLID_WIN_MAX
)
415 rtlpriv
->stats
.ui_link_quality
.index
= 0;
416 tmpval
= rtlpriv
->stats
.ui_link_quality
.total_val
/
417 rtlpriv
->stats
.ui_link_quality
.total_num
;
418 rtlpriv
->stats
.signal_quality
= tmpval
;
419 rtlpriv
->stats
.last_sigstrength_inpercent
= tmpval
;
420 rtl92d_loop_over_streams(hw
, pstats
);
424 static void _rtl92de_process_phyinfo(struct ieee80211_hw
*hw
,
426 struct rtl_stats
*pcurrent_stats
)
429 if (!pcurrent_stats
->packet_matchbssid
&&
430 !pcurrent_stats
->packet_beacon
)
433 _rtl92de_process_ui_rssi(hw
, pcurrent_stats
);
434 _rtl92de_process_pwdb(hw
, pcurrent_stats
);
435 _rtl92de_process_ui_link_quality(hw
, pcurrent_stats
);
438 static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw
*hw
,
440 struct rtl_stats
*pstats
,
441 struct rx_desc_92d
*pdesc
,
442 struct rx_fwinfo_92d
*p_drvinfo
)
444 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
445 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
446 struct ieee80211_hdr
*hdr
;
451 bool packet_matchbssid
, packet_toself
, packet_beacon
= false;
453 tmp_buf
= skb
->data
+ pstats
->rx_drvinfo_size
+ pstats
->rx_bufshift
;
454 hdr
= (struct ieee80211_hdr
*)tmp_buf
;
455 fc
= hdr
->frame_control
;
456 cfc
= le16_to_cpu(fc
);
457 type
= WLAN_FC_GET_TYPE(fc
);
459 packet_matchbssid
= ((IEEE80211_FTYPE_CTL
!= type
) &&
460 ether_addr_equal(mac
->bssid
,
461 (cfc
& IEEE80211_FCTL_TODS
) ? hdr
->addr1
:
462 (cfc
& IEEE80211_FCTL_FROMDS
) ? hdr
->addr2
:
464 (!pstats
->hwerror
) && (!pstats
->crc
) && (!pstats
->icv
));
465 packet_toself
= packet_matchbssid
&&
466 ether_addr_equal(praddr
, rtlefuse
->dev_addr
);
467 if (ieee80211_is_beacon(fc
))
468 packet_beacon
= true;
469 _rtl92de_query_rxphystatus(hw
, pstats
, pdesc
, p_drvinfo
,
470 packet_matchbssid
, packet_toself
,
472 _rtl92de_process_phyinfo(hw
, tmp_buf
, pstats
);
475 bool rtl92de_rx_query_desc(struct ieee80211_hw
*hw
, struct rtl_stats
*stats
,
476 struct ieee80211_rx_status
*rx_status
,
477 u8
*p_desc
, struct sk_buff
*skb
)
479 struct rx_fwinfo_92d
*p_drvinfo
;
480 struct rx_desc_92d
*pdesc
= (struct rx_desc_92d
*)p_desc
;
481 u32 phystatus
= GET_RX_DESC_PHYST(pdesc
);
483 stats
->length
= (u16
) GET_RX_DESC_PKT_LEN(pdesc
);
484 stats
->rx_drvinfo_size
= (u8
) GET_RX_DESC_DRV_INFO_SIZE(pdesc
) *
485 RX_DRV_INFO_SIZE_UNIT
;
486 stats
->rx_bufshift
= (u8
) (GET_RX_DESC_SHIFT(pdesc
) & 0x03);
487 stats
->icv
= (u16
) GET_RX_DESC_ICV(pdesc
);
488 stats
->crc
= (u16
) GET_RX_DESC_CRC32(pdesc
);
489 stats
->hwerror
= (stats
->crc
| stats
->icv
);
490 stats
->decrypted
= !GET_RX_DESC_SWDEC(pdesc
);
491 stats
->rate
= (u8
) GET_RX_DESC_RXMCS(pdesc
);
492 stats
->shortpreamble
= (u16
) GET_RX_DESC_SPLCP(pdesc
);
493 stats
->isampdu
= (bool) (GET_RX_DESC_PAGGR(pdesc
) == 1);
494 stats
->isfirst_ampdu
= (bool) ((GET_RX_DESC_PAGGR(pdesc
) == 1)
495 && (GET_RX_DESC_FAGGR(pdesc
) == 1));
496 stats
->timestamp_low
= GET_RX_DESC_TSFL(pdesc
);
497 stats
->rx_is40Mhzpacket
= (bool) GET_RX_DESC_BW(pdesc
);
498 stats
->is_ht
= (bool)GET_RX_DESC_RXHT(pdesc
);
499 rx_status
->freq
= hw
->conf
.chandef
.chan
->center_freq
;
500 rx_status
->band
= hw
->conf
.chandef
.chan
->band
;
501 if (GET_RX_DESC_CRC32(pdesc
))
502 rx_status
->flag
|= RX_FLAG_FAILED_FCS_CRC
;
503 if (!GET_RX_DESC_SWDEC(pdesc
))
504 rx_status
->flag
|= RX_FLAG_DECRYPTED
;
505 if (GET_RX_DESC_BW(pdesc
))
506 rx_status
->bw
= RATE_INFO_BW_40
;
507 if (GET_RX_DESC_RXHT(pdesc
))
508 rx_status
->encoding
= RX_ENC_HT
;
509 rx_status
->flag
|= RX_FLAG_MACTIME_START
;
510 if (stats
->decrypted
)
511 rx_status
->flag
|= RX_FLAG_DECRYPTED
;
512 rx_status
->rate_idx
= rtlwifi_rate_mapping(hw
, stats
->is_ht
,
514 rx_status
->mactime
= GET_RX_DESC_TSFL(pdesc
);
516 p_drvinfo
= (struct rx_fwinfo_92d
*)(skb
->data
+
518 _rtl92de_translate_rx_signal_stuff(hw
,
522 /*rx_status->qual = stats->signal; */
523 rx_status
->signal
= stats
->recvsignalpower
+ 10;
527 static void _rtl92de_insert_emcontent(struct rtl_tcb_desc
*ptcb_desc
,
530 memset(virtualaddress
, 0, 8);
532 SET_EARLYMODE_PKTNUM(virtualaddress
, ptcb_desc
->empkt_num
);
533 SET_EARLYMODE_LEN0(virtualaddress
, ptcb_desc
->empkt_len
[0]);
534 SET_EARLYMODE_LEN1(virtualaddress
, ptcb_desc
->empkt_len
[1]);
535 SET_EARLYMODE_LEN2_1(virtualaddress
, ptcb_desc
->empkt_len
[2] & 0xF);
536 SET_EARLYMODE_LEN2_2(virtualaddress
, ptcb_desc
->empkt_len
[2] >> 4);
537 SET_EARLYMODE_LEN3(virtualaddress
, ptcb_desc
->empkt_len
[3]);
538 SET_EARLYMODE_LEN4(virtualaddress
, ptcb_desc
->empkt_len
[4]);
541 void rtl92de_tx_fill_desc(struct ieee80211_hw
*hw
,
542 struct ieee80211_hdr
*hdr
, u8
*pdesc_tx
,
543 u8
*pbd_desc_tx
, struct ieee80211_tx_info
*info
,
544 struct ieee80211_sta
*sta
,
546 u8 hw_queue
, struct rtl_tcb_desc
*ptcb_desc
)
548 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
549 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
550 struct rtl_pci
*rtlpci
= rtl_pcidev(rtl_pcipriv(hw
));
551 struct rtl_hal
*rtlhal
= rtl_hal(rtlpriv
);
552 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtl_priv(hw
));
553 u8
*pdesc
= pdesc_tx
;
555 __le16 fc
= hdr
->frame_control
;
556 unsigned int buf_len
= 0;
557 unsigned int skb_len
= skb
->len
;
558 u8 fw_qsel
= _rtl92de_map_hwqueue_to_fwqueue(skb
, hw_queue
);
559 bool firstseg
= ((hdr
->seq_ctrl
&
560 cpu_to_le16(IEEE80211_SCTL_FRAG
)) == 0);
561 bool lastseg
= ((hdr
->frame_control
&
562 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS
)) == 0);
566 if (mac
->opmode
== NL80211_IFTYPE_STATION
) {
568 } else if (mac
->opmode
== NL80211_IFTYPE_AP
||
569 mac
->opmode
== NL80211_IFTYPE_ADHOC
) {
571 bw_40
= sta
->bandwidth
>= IEEE80211_STA_RX_BW_40
;
573 seq_number
= (le16_to_cpu(hdr
->seq_ctrl
) & IEEE80211_SCTL_SEQ
) >> 4;
574 rtl_get_tcb_desc(hw
, info
, sta
, skb
, ptcb_desc
);
575 /* reserve 8 byte for AMPDU early mode */
576 if (rtlhal
->earlymode_enable
) {
577 skb_push(skb
, EM_HDR_LEN
);
578 memset(skb
->data
, 0, EM_HDR_LEN
);
581 mapping
= pci_map_single(rtlpci
->pdev
, skb
->data
, skb
->len
,
583 if (pci_dma_mapping_error(rtlpci
->pdev
, mapping
)) {
584 RT_TRACE(rtlpriv
, COMP_SEND
, DBG_TRACE
,
585 "DMA mapping error\n");
588 CLEAR_PCI_TX_DESC_CONTENT(pdesc
, sizeof(struct tx_desc_92d
));
589 if (ieee80211_is_nullfunc(fc
) || ieee80211_is_ctl(fc
)) {
594 if (rtlhal
->earlymode_enable
) {
595 SET_TX_DESC_PKT_OFFSET(pdesc
, 1);
596 SET_TX_DESC_OFFSET(pdesc
, USB_HWDESC_HEADER_LEN
+
598 if (ptcb_desc
->empkt_num
) {
599 RT_TRACE(rtlpriv
, COMP_SEND
, DBG_LOUD
,
600 "Insert 8 byte.pTcb->EMPktNum:%d\n",
601 ptcb_desc
->empkt_num
);
602 _rtl92de_insert_emcontent(ptcb_desc
,
606 SET_TX_DESC_OFFSET(pdesc
, USB_HWDESC_HEADER_LEN
);
608 /* 5G have no CCK rate */
609 if (rtlhal
->current_bandtype
== BAND_ON_5G
)
610 if (ptcb_desc
->hw_rate
< DESC_RATE6M
)
611 ptcb_desc
->hw_rate
= DESC_RATE6M
;
612 SET_TX_DESC_TX_RATE(pdesc
, ptcb_desc
->hw_rate
);
613 if (ptcb_desc
->use_shortgi
|| ptcb_desc
->use_shortpreamble
)
614 SET_TX_DESC_DATA_SHORTGI(pdesc
, 1);
616 if (rtlhal
->macphymode
== DUALMAC_DUALPHY
&&
617 ptcb_desc
->hw_rate
== DESC_RATEMCS7
)
618 SET_TX_DESC_DATA_SHORTGI(pdesc
, 1);
620 if (info
->flags
& IEEE80211_TX_CTL_AMPDU
) {
621 SET_TX_DESC_AGG_ENABLE(pdesc
, 1);
622 SET_TX_DESC_MAX_AGG_NUM(pdesc
, 0x14);
624 SET_TX_DESC_SEQ(pdesc
, seq_number
);
625 SET_TX_DESC_RTS_ENABLE(pdesc
, ((ptcb_desc
->rts_enable
&&
626 !ptcb_desc
->cts_enable
) ? 1 : 0));
627 SET_TX_DESC_HW_RTS_ENABLE(pdesc
, ((ptcb_desc
->rts_enable
628 || ptcb_desc
->cts_enable
) ? 1 : 0));
629 SET_TX_DESC_CTS2SELF(pdesc
, ((ptcb_desc
->cts_enable
) ? 1 : 0));
630 SET_TX_DESC_RTS_STBC(pdesc
, ((ptcb_desc
->rts_stbc
) ? 1 : 0));
631 /* 5G have no CCK rate */
632 if (rtlhal
->current_bandtype
== BAND_ON_5G
)
633 if (ptcb_desc
->rts_rate
< DESC_RATE6M
)
634 ptcb_desc
->rts_rate
= DESC_RATE6M
;
635 SET_TX_DESC_RTS_RATE(pdesc
, ptcb_desc
->rts_rate
);
636 SET_TX_DESC_RTS_BW(pdesc
, 0);
637 SET_TX_DESC_RTS_SC(pdesc
, ptcb_desc
->rts_sc
);
638 SET_TX_DESC_RTS_SHORT(pdesc
, ((ptcb_desc
->rts_rate
<=
640 (ptcb_desc
->rts_use_shortpreamble
? 1 : 0) :
641 (ptcb_desc
->rts_use_shortgi
? 1 : 0)));
643 if (ptcb_desc
->packet_bw
) {
644 SET_TX_DESC_DATA_BW(pdesc
, 1);
645 SET_TX_DESC_TX_SUB_CARRIER(pdesc
, 3);
647 SET_TX_DESC_DATA_BW(pdesc
, 0);
648 SET_TX_DESC_TX_SUB_CARRIER(pdesc
,
649 mac
->cur_40_prime_sc
);
652 SET_TX_DESC_DATA_BW(pdesc
, 0);
653 SET_TX_DESC_TX_SUB_CARRIER(pdesc
, 0);
655 SET_TX_DESC_LINIP(pdesc
, 0);
656 SET_TX_DESC_PKT_SIZE(pdesc
, (u16
) skb_len
);
658 u8 ampdu_density
= sta
->ht_cap
.ampdu_density
;
659 SET_TX_DESC_AMPDU_DENSITY(pdesc
, ampdu_density
);
661 if (info
->control
.hw_key
) {
662 struct ieee80211_key_conf
*keyconf
;
664 keyconf
= info
->control
.hw_key
;
665 switch (keyconf
->cipher
) {
666 case WLAN_CIPHER_SUITE_WEP40
:
667 case WLAN_CIPHER_SUITE_WEP104
:
668 case WLAN_CIPHER_SUITE_TKIP
:
669 SET_TX_DESC_SEC_TYPE(pdesc
, 0x1);
671 case WLAN_CIPHER_SUITE_CCMP
:
672 SET_TX_DESC_SEC_TYPE(pdesc
, 0x3);
675 SET_TX_DESC_SEC_TYPE(pdesc
, 0x0);
680 SET_TX_DESC_PKT_ID(pdesc
, 0);
681 SET_TX_DESC_QUEUE_SEL(pdesc
, fw_qsel
);
682 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc
, 0x1F);
683 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc
, 0xF);
684 SET_TX_DESC_DISABLE_FB(pdesc
, ptcb_desc
->disable_ratefallback
?
686 SET_TX_DESC_USE_RATE(pdesc
, ptcb_desc
->use_driver_rate
? 1 : 0);
688 /* Set TxRate and RTSRate in TxDesc */
689 /* This prevent Tx initial rate of new-coming packets */
690 /* from being overwritten by retried packet rate.*/
691 if (!ptcb_desc
->use_driver_rate
) {
692 SET_TX_DESC_RTS_RATE(pdesc
, 0x08);
693 /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
695 if (ieee80211_is_data_qos(fc
)) {
697 RT_TRACE(rtlpriv
, COMP_SEND
, DBG_TRACE
,
698 "Enable RDG function\n");
699 SET_TX_DESC_RDG_ENABLE(pdesc
, 1);
700 SET_TX_DESC_HTC(pdesc
, 1);
705 SET_TX_DESC_FIRST_SEG(pdesc
, (firstseg
? 1 : 0));
706 SET_TX_DESC_LAST_SEG(pdesc
, (lastseg
? 1 : 0));
707 SET_TX_DESC_TX_BUFFER_SIZE(pdesc
, (u16
) buf_len
);
708 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc
, mapping
);
709 if (rtlpriv
->dm
.useramask
) {
710 SET_TX_DESC_RATE_ID(pdesc
, ptcb_desc
->ratr_index
);
711 SET_TX_DESC_MACID(pdesc
, ptcb_desc
->mac_id
);
713 SET_TX_DESC_RATE_ID(pdesc
, 0xC + ptcb_desc
->ratr_index
);
714 SET_TX_DESC_MACID(pdesc
, ptcb_desc
->ratr_index
);
716 if (ieee80211_is_data_qos(fc
))
717 SET_TX_DESC_QOS(pdesc
, 1);
719 if ((!ieee80211_is_data_qos(fc
)) && ppsc
->fwctrl_lps
) {
720 SET_TX_DESC_HWSEQ_EN(pdesc
, 1);
721 SET_TX_DESC_PKT_ID(pdesc
, 8);
723 SET_TX_DESC_MORE_FRAG(pdesc
, (lastseg
? 0 : 1));
724 RT_TRACE(rtlpriv
, COMP_SEND
, DBG_TRACE
, "\n");
727 void rtl92de_tx_fill_cmddesc(struct ieee80211_hw
*hw
,
728 u8
*pdesc
, bool firstseg
,
729 bool lastseg
, struct sk_buff
*skb
)
731 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
732 struct rtl_pci
*rtlpci
= rtl_pcidev(rtl_pcipriv(hw
));
733 struct rtl_ps_ctl
*ppsc
= rtl_psc(rtlpriv
);
734 struct rtl_hal
*rtlhal
= rtl_hal(rtlpriv
);
735 u8 fw_queue
= QSLT_BEACON
;
736 dma_addr_t mapping
= pci_map_single(rtlpci
->pdev
,
737 skb
->data
, skb
->len
, PCI_DMA_TODEVICE
);
738 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)(skb
->data
);
739 __le16 fc
= hdr
->frame_control
;
741 if (pci_dma_mapping_error(rtlpci
->pdev
, mapping
)) {
742 RT_TRACE(rtlpriv
, COMP_SEND
, DBG_TRACE
,
743 "DMA mapping error\n");
746 CLEAR_PCI_TX_DESC_CONTENT(pdesc
, TX_DESC_SIZE
);
748 SET_TX_DESC_OFFSET(pdesc
, USB_HWDESC_HEADER_LEN
);
749 /* 5G have no CCK rate
750 * Caution: The macros below are multi-line expansions.
751 * The braces are needed no matter what checkpatch says
753 if (rtlhal
->current_bandtype
== BAND_ON_5G
) {
754 SET_TX_DESC_TX_RATE(pdesc
, DESC_RATE6M
);
756 SET_TX_DESC_TX_RATE(pdesc
, DESC_RATE1M
);
758 SET_TX_DESC_SEQ(pdesc
, 0);
759 SET_TX_DESC_LINIP(pdesc
, 0);
760 SET_TX_DESC_QUEUE_SEL(pdesc
, fw_queue
);
761 SET_TX_DESC_FIRST_SEG(pdesc
, 1);
762 SET_TX_DESC_LAST_SEG(pdesc
, 1);
763 SET_TX_DESC_TX_BUFFER_SIZE(pdesc
, (u16
)skb
->len
);
764 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc
, mapping
);
765 SET_TX_DESC_RATE_ID(pdesc
, 7);
766 SET_TX_DESC_MACID(pdesc
, 0);
767 SET_TX_DESC_PKT_SIZE(pdesc
, (u16
) (skb
->len
));
768 SET_TX_DESC_FIRST_SEG(pdesc
, 1);
769 SET_TX_DESC_LAST_SEG(pdesc
, 1);
770 SET_TX_DESC_OFFSET(pdesc
, 0x20);
771 SET_TX_DESC_USE_RATE(pdesc
, 1);
773 if (!ieee80211_is_data_qos(fc
) && ppsc
->fwctrl_lps
) {
774 SET_TX_DESC_HWSEQ_EN(pdesc
, 1);
775 SET_TX_DESC_PKT_ID(pdesc
, 8);
778 RT_PRINT_DATA(rtlpriv
, COMP_CMD
, DBG_LOUD
,
779 "H2C Tx Cmd Content", pdesc
, TX_DESC_SIZE
);
781 SET_TX_DESC_OWN(pdesc
, 1);
784 void rtl92de_set_desc(struct ieee80211_hw
*hw
, u8
*pdesc
, bool istx
,
785 u8 desc_name
, u8
*val
)
791 SET_TX_DESC_OWN(pdesc
, 1);
793 case HW_DESC_TX_NEXTDESC_ADDR
:
794 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc
, *(u32
*) val
);
797 WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
805 SET_RX_DESC_OWN(pdesc
, 1);
807 case HW_DESC_RXBUFF_ADDR
:
808 SET_RX_DESC_BUFF_ADDR(pdesc
, *(u32
*) val
);
810 case HW_DESC_RXPKT_LEN
:
811 SET_RX_DESC_PKT_LEN(pdesc
, *(u32
*) val
);
814 SET_RX_DESC_EOR(pdesc
, 1);
817 WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
824 u64
rtl92de_get_desc(struct ieee80211_hw
*hw
,
825 u8
*p_desc
, bool istx
, u8 desc_name
)
832 ret
= GET_TX_DESC_OWN(p_desc
);
834 case HW_DESC_TXBUFF_ADDR
:
835 ret
= GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc
);
838 WARN_ONCE(true, "rtl8192de: ERR txdesc :%d not processed\n",
843 struct rx_desc_92c
*pdesc
= (struct rx_desc_92c
*)p_desc
;
846 ret
= GET_RX_DESC_OWN(pdesc
);
848 case HW_DESC_RXPKT_LEN
:
849 ret
= GET_RX_DESC_PKT_LEN(pdesc
);
852 WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n",
860 void rtl92de_tx_polling(struct ieee80211_hw
*hw
, u8 hw_queue
)
862 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
863 if (hw_queue
== BEACON_QUEUE
)
864 rtl_write_word(rtlpriv
, REG_PCIE_CTRL_REG
, BIT(4));
866 rtl_write_word(rtlpriv
, REG_PCIE_CTRL_REG
,
867 BIT(0) << (hw_queue
));