File Index
Files and directories
Sign in
FILE

trx.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright(c) 2024  Realtek Corporation.*/
  3
  4#include "../wifi.h"
  5#include "../base.h"
  6#include "../usb.h"
  7#include "../rtl8192d/reg.h"
  8#include "../rtl8192d/def.h"
  9#include "../rtl8192d/trx_common.h"
 10#include "trx.h"
 11
 12void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb)
 13{
 14}
 15
 16int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
 17			struct sk_buff *skb)
 18{
 19	return 0;
 20}
 21
 22struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw,
 23					 struct sk_buff_head *list)
 24{
 25	return skb_dequeue(list);
 26}
 27
 28static enum rtl_desc_qsel _rtl92du_hwq_to_descq(u16 queue_index)
 29{
 30	switch (queue_index) {
 31	case RTL_TXQ_BCN:
 32		return QSLT_BEACON;
 33	case RTL_TXQ_MGT:
 34		return QSLT_MGNT;
 35	case RTL_TXQ_VO:
 36		return QSLT_VO;
 37	case RTL_TXQ_VI:
 38		return QSLT_VI;
 39	case RTL_TXQ_BK:
 40		return QSLT_BK;
 41	default:
 42	case RTL_TXQ_BE:
 43		return QSLT_BE;
 44	}
 45}
 46
 47/* For HW recovery information */
 48static void _rtl92du_tx_desc_checksum(__le32 *txdesc)
 49{
 50	__le16 *ptr = (__le16 *)txdesc;
 51	u16 checksum = 0;
 52	u32 index;
 53
 54	/* Clear first */
 55	set_tx_desc_tx_desc_checksum(txdesc, 0);
 56	for (index = 0; index < 16; index++)
 57		checksum = checksum ^ le16_to_cpu(*(ptr + index));
 58	set_tx_desc_tx_desc_checksum(txdesc, checksum);
 59}
 60
 61void rtl92du_tx_fill_desc(struct ieee80211_hw *hw,
 62			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 63			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 64			  struct ieee80211_sta *sta,
 65			  struct sk_buff *skb,
 66			  u8 queue_index,
 67			  struct rtl_tcb_desc *tcb_desc)
 68{
 69	struct rtl_priv *rtlpriv = rtl_priv(hw);
 70	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 71	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 72	struct rtl_mac *mac = rtl_mac(rtlpriv);
 73	struct rtl_sta_info *sta_entry;
 74	__le16 fc = hdr->frame_control;
 75	u8 agg_state = RTL_AGG_STOP;
 76	u16 pktlen = skb->len;
 77	u32 rts_en, hw_rts_en;
 78	u8 ampdu_density = 0;
 79	u16 seq_number;
 80	__le32 *txdesc;
 81	u8 rate_flag;
 82	u8 tid;
 83
 84	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 85
 86	txdesc = (__le32 *)skb_push(skb, RTL_TX_HEADER_SIZE);
 87	memset(txdesc, 0, RTL_TX_HEADER_SIZE);
 88
 89	set_tx_desc_pkt_size(txdesc, pktlen);
 90	set_tx_desc_linip(txdesc, 0);
 91	set_tx_desc_pkt_offset(txdesc, RTL_DUMMY_OFFSET);
 92	set_tx_desc_offset(txdesc, RTL_TX_HEADER_SIZE);
 93	/* 5G have no CCK rate */
 94	if (rtlhal->current_bandtype == BAND_ON_5G)
 95		if (tcb_desc->hw_rate < DESC_RATE6M)
 96			tcb_desc->hw_rate = DESC_RATE6M;
 97
 98	set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate);
 99	if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
100		set_tx_desc_data_shortgi(txdesc, 1);
101
102	if (rtlhal->macphymode == DUALMAC_DUALPHY &&
103	    tcb_desc->hw_rate == DESC_RATEMCS7)
104		set_tx_desc_data_shortgi(txdesc, 1);
105
106	if (sta) {
107		sta_entry = (struct rtl_sta_info *)sta->drv_priv;
108		tid = ieee80211_get_tid(hdr);
109		agg_state = sta_entry->tids[tid].agg.agg_state;
110		ampdu_density = sta->deflink.ht_cap.ampdu_density;
111	}
112
113	if (agg_state == RTL_AGG_OPERATIONAL &&
114	    info->flags & IEEE80211_TX_CTL_AMPDU) {
115		set_tx_desc_agg_enable(txdesc, 1);
116		set_tx_desc_max_agg_num(txdesc, 0x14);
117		set_tx_desc_ampdu_density(txdesc, ampdu_density);
118		tcb_desc->rts_enable = 1;
119		tcb_desc->rts_rate = DESC_RATE24M;
120	} else {
121		set_tx_desc_agg_break(txdesc, 1);
122	}
123	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
124	set_tx_desc_seq(txdesc, seq_number);
125
126	rts_en = tcb_desc->rts_enable && !tcb_desc->cts_enable;
127	hw_rts_en = tcb_desc->rts_enable || tcb_desc->cts_enable;
128	set_tx_desc_rts_enable(txdesc, rts_en);
129	set_tx_desc_hw_rts_enable(txdesc, hw_rts_en);
130	set_tx_desc_cts2self(txdesc, tcb_desc->cts_enable);
131	set_tx_desc_rts_stbc(txdesc, tcb_desc->rts_stbc);
132	/* 5G have no CCK rate */
133	if (rtlhal->current_bandtype == BAND_ON_5G)
134		if (tcb_desc->rts_rate < DESC_RATE6M)
135			tcb_desc->rts_rate = DESC_RATE6M;
136	set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate);
137	set_tx_desc_rts_bw(txdesc, 0);
138	set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc);
139	set_tx_desc_rts_short(txdesc, tcb_desc->rts_use_shortpreamble);
140
141	rate_flag = info->control.rates[0].flags;
142	if (mac->bw_40) {
143		if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
144			set_tx_desc_data_bw(txdesc, 1);
145			set_tx_desc_tx_sub_carrier(txdesc, 3);
146		} else if (rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH) {
147			set_tx_desc_data_bw(txdesc, 1);
148			set_tx_desc_tx_sub_carrier(txdesc, mac->cur_40_prime_sc);
149		} else {
150			set_tx_desc_data_bw(txdesc, 0);
151			set_tx_desc_tx_sub_carrier(txdesc, 0);
152		}
153	} else {
154		set_tx_desc_data_bw(txdesc, 0);
155		set_tx_desc_tx_sub_carrier(txdesc, 0);
156	}
157
158	if (info->control.hw_key) {
159		struct ieee80211_key_conf *keyconf = info->control.hw_key;
160
161		switch (keyconf->cipher) {
162		case WLAN_CIPHER_SUITE_WEP40:
163		case WLAN_CIPHER_SUITE_WEP104:
164		case WLAN_CIPHER_SUITE_TKIP:
165			set_tx_desc_sec_type(txdesc, 0x1);
166			break;
167		case WLAN_CIPHER_SUITE_CCMP:
168			set_tx_desc_sec_type(txdesc, 0x3);
169			break;
170		default:
171			set_tx_desc_sec_type(txdesc, 0x0);
172			break;
173		}
174	}
175
176	set_tx_desc_pkt_id(txdesc, 0);
177	set_tx_desc_queue_sel(txdesc, _rtl92du_hwq_to_descq(queue_index));
178	set_tx_desc_data_rate_fb_limit(txdesc, 0x1F);
179	set_tx_desc_rts_rate_fb_limit(txdesc, 0xF);
180	set_tx_desc_disable_fb(txdesc, 0);
181	set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate);
182
183	if (ieee80211_is_data_qos(fc)) {
184		if (mac->rdg_en) {
185			rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
186				"Enable RDG function\n");
187			set_tx_desc_rdg_enable(txdesc, 1);
188			set_tx_desc_htc(txdesc, 1);
189		}
190		set_tx_desc_qos(txdesc, 1);
191	}
192
193	if (rtlpriv->dm.useramask) {
194		set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index);
195		set_tx_desc_macid(txdesc, tcb_desc->mac_id);
196	} else {
197		set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index);
198		set_tx_desc_macid(txdesc, tcb_desc->ratr_index);
199	}
200
201	if (!ieee80211_is_data_qos(fc) && ppsc->leisure_ps &&
202	    ppsc->fwctrl_lps) {
203		set_tx_desc_hwseq_en(txdesc, 1);
204		set_tx_desc_pkt_id(txdesc, 8);
205	}
206
207	if (ieee80211_has_morefrags(fc))
208		set_tx_desc_more_frag(txdesc, 1);
209	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
210	    is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
211		set_tx_desc_bmc(txdesc, 1);
212
213	set_tx_desc_own(txdesc, 1);
214	set_tx_desc_last_seg(txdesc, 1);
215	set_tx_desc_first_seg(txdesc, 1);
216	_rtl92du_tx_desc_checksum(txdesc);
217
218	rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
219}
220
221static void _rtl92du_config_out_ep(struct ieee80211_hw *hw, u8 num_out_pipe)
222{
223	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
224	struct rtl_priv *rtlpriv = rtl_priv(hw);
225	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
226	u16 ep_cfg;
227
228	rtlusb->out_queue_sel = 0;
229	rtlusb->out_ep_nums = 0;
230
231	if (rtlhal->interfaceindex == 0)
232		ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC0);
233	else
234		ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC1);
235
236	if (ep_cfg & 0x00f) {
237		rtlusb->out_queue_sel |= TX_SELE_HQ;
238		rtlusb->out_ep_nums++;
239	}
240	if (ep_cfg & 0x0f0) {
241		rtlusb->out_queue_sel |= TX_SELE_NQ;
242		rtlusb->out_ep_nums++;
243	}
244	if (ep_cfg & 0xf00) {
245		rtlusb->out_queue_sel |= TX_SELE_LQ;
246		rtlusb->out_ep_nums++;
247	}
248
249	switch (num_out_pipe) {
250	case 3:
251		rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ | TX_SELE_LQ;
252		rtlusb->out_ep_nums = 3;
253		break;
254	case 2:
255		rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ;
256		rtlusb->out_ep_nums = 2;
257		break;
258	case 1:
259		rtlusb->out_queue_sel = TX_SELE_HQ;
260		rtlusb->out_ep_nums = 1;
261		break;
262	default:
263		break;
264	}
265}
266
267static void _rtl92du_one_out_ep_mapping(struct rtl_usb *rtlusb,
268					struct rtl_ep_map *ep_map)
269{
270	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[0];
271	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[0];
272	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0];
273	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
274	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
275	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
276	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
277}
278
279static void _rtl92du_two_out_ep_mapping(struct rtl_usb *rtlusb,
280					struct rtl_ep_map *ep_map)
281{
282	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[1];
283	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1];
284	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0];
285	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
286	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
287	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
288	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
289}
290
291static void _rtl92du_three_out_ep_mapping(struct rtl_usb *rtlusb,
292					  struct rtl_ep_map *ep_map)
293{
294	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[2];
295	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[2];
296	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1];
297	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
298	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
299	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
300	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
301}
302
303static int _rtl92du_out_ep_mapping(struct ieee80211_hw *hw)
304{
305	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
306	struct rtl_ep_map *ep_map = &rtlusb->ep_map;
307
308	switch (rtlusb->out_ep_nums) {
309	case 1:
310		_rtl92du_one_out_ep_mapping(rtlusb, ep_map);
311		break;
312	case 2:
313		_rtl92du_two_out_ep_mapping(rtlusb, ep_map);
314		break;
315	case 3:
316		_rtl92du_three_out_ep_mapping(rtlusb, ep_map);
317		break;
318	default:
319		return -EINVAL;
320	}
321
322	return 0;
323}
324
325int rtl92du_endpoint_mapping(struct ieee80211_hw *hw)
326{
327	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
328
329	_rtl92du_config_out_ep(hw, rtlusb->out_ep_nums);
330
331	/* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
332	if (rtlusb->out_ep_nums == 1 && rtlusb->in_ep_nums != 1)
333		return -EINVAL;
334
335	return _rtl92du_out_ep_mapping(hw);
336}
337
338u16 rtl92du_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
339{
340	u16 hw_queue_index;
341
342	if (unlikely(ieee80211_is_beacon(fc))) {
343		hw_queue_index = RTL_TXQ_BCN;
344		goto out;
345	}
346	if (ieee80211_is_mgmt(fc)) {
347		hw_queue_index = RTL_TXQ_MGT;
348		goto out;
349	}
350
351	switch (mac80211_queue_index) {
352	case 0:
353		hw_queue_index = RTL_TXQ_VO;
354		break;
355	case 1:
356		hw_queue_index = RTL_TXQ_VI;
357		break;
358	case 2:
359		hw_queue_index = RTL_TXQ_BE;
360		break;
361	case 3:
362		hw_queue_index = RTL_TXQ_BK;
363		break;
364	default:
365		hw_queue_index = RTL_TXQ_BE;
366		WARN_ONCE(true, "rtl8192du: QSLT_BE queue, skb_queue:%d\n",
367			  mac80211_queue_index);
368		break;
369	}
370out:
371	return hw_queue_index;
372}
~/ Read-only file preview.