xref: /linux/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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 
rtl92du_tx_cleanup(struct ieee80211_hw * hw,struct sk_buff * skb)12 void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb)
13 {
14 }
15 
rtl92du_tx_post_hdl(struct ieee80211_hw * hw,struct urb * urb,struct sk_buff * skb)16 int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
17 			struct sk_buff *skb)
18 {
19 	return 0;
20 }
21 
rtl92du_tx_aggregate_hdl(struct ieee80211_hw * hw,struct sk_buff_head * list)22 struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw,
23 					 struct sk_buff_head *list)
24 {
25 	return skb_dequeue(list);
26 }
27 
_rtl92du_hwq_to_descq(u16 queue_index)28 static 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 */
_rtl92du_tx_desc_checksum(__le32 * txdesc)48 static 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 
rtl92du_tx_fill_desc(struct ieee80211_hw * hw,struct ieee80211_hdr * hdr,u8 * pdesc_tx,u8 * pbd_desc_tx,struct ieee80211_tx_info * info,struct ieee80211_sta * sta,struct sk_buff * skb,u8 queue_index,struct rtl_tcb_desc * tcb_desc)61 void 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 		if (tid < MAX_TID_COUNT)
110 			agg_state = sta_entry->tids[tid].agg.agg_state;
111 		ampdu_density = sta->deflink.ht_cap.ampdu_density;
112 	}
113 
114 	if (agg_state == RTL_AGG_OPERATIONAL &&
115 	    info->flags & IEEE80211_TX_CTL_AMPDU) {
116 		set_tx_desc_agg_enable(txdesc, 1);
117 		set_tx_desc_max_agg_num(txdesc, 0x14);
118 		set_tx_desc_ampdu_density(txdesc, ampdu_density);
119 		tcb_desc->rts_enable = 1;
120 		tcb_desc->rts_rate = DESC_RATE24M;
121 	} else {
122 		set_tx_desc_agg_break(txdesc, 1);
123 	}
124 	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
125 	set_tx_desc_seq(txdesc, seq_number);
126 
127 	rts_en = tcb_desc->rts_enable && !tcb_desc->cts_enable;
128 	hw_rts_en = tcb_desc->rts_enable || tcb_desc->cts_enable;
129 	set_tx_desc_rts_enable(txdesc, rts_en);
130 	set_tx_desc_hw_rts_enable(txdesc, hw_rts_en);
131 	set_tx_desc_cts2self(txdesc, tcb_desc->cts_enable);
132 	set_tx_desc_rts_stbc(txdesc, tcb_desc->rts_stbc);
133 	/* 5G have no CCK rate */
134 	if (rtlhal->current_bandtype == BAND_ON_5G)
135 		if (tcb_desc->rts_rate < DESC_RATE6M)
136 			tcb_desc->rts_rate = DESC_RATE6M;
137 	set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate);
138 	set_tx_desc_rts_bw(txdesc, 0);
139 	set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc);
140 	set_tx_desc_rts_short(txdesc, tcb_desc->rts_use_shortpreamble);
141 
142 	rate_flag = info->control.rates[0].flags;
143 	if (mac->bw_40) {
144 		if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
145 			set_tx_desc_data_bw(txdesc, 1);
146 			set_tx_desc_tx_sub_carrier(txdesc, 3);
147 		} else if (rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH) {
148 			set_tx_desc_data_bw(txdesc, 1);
149 			set_tx_desc_tx_sub_carrier(txdesc, mac->cur_40_prime_sc);
150 		} else {
151 			set_tx_desc_data_bw(txdesc, 0);
152 			set_tx_desc_tx_sub_carrier(txdesc, 0);
153 		}
154 	} else {
155 		set_tx_desc_data_bw(txdesc, 0);
156 		set_tx_desc_tx_sub_carrier(txdesc, 0);
157 	}
158 
159 	if (info->control.hw_key) {
160 		struct ieee80211_key_conf *keyconf = info->control.hw_key;
161 
162 		switch (keyconf->cipher) {
163 		case WLAN_CIPHER_SUITE_WEP40:
164 		case WLAN_CIPHER_SUITE_WEP104:
165 		case WLAN_CIPHER_SUITE_TKIP:
166 			set_tx_desc_sec_type(txdesc, 0x1);
167 			break;
168 		case WLAN_CIPHER_SUITE_CCMP:
169 			set_tx_desc_sec_type(txdesc, 0x3);
170 			break;
171 		default:
172 			set_tx_desc_sec_type(txdesc, 0x0);
173 			break;
174 		}
175 	}
176 
177 	set_tx_desc_pkt_id(txdesc, 0);
178 	set_tx_desc_queue_sel(txdesc, _rtl92du_hwq_to_descq(queue_index));
179 	set_tx_desc_data_rate_fb_limit(txdesc, 0x1F);
180 	set_tx_desc_rts_rate_fb_limit(txdesc, 0xF);
181 	set_tx_desc_disable_fb(txdesc, 0);
182 	set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate);
183 
184 	if (ieee80211_is_data_qos(fc)) {
185 		if (mac->rdg_en) {
186 			rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
187 				"Enable RDG function\n");
188 			set_tx_desc_rdg_enable(txdesc, 1);
189 			set_tx_desc_htc(txdesc, 1);
190 		}
191 		set_tx_desc_qos(txdesc, 1);
192 	}
193 
194 	if (rtlpriv->dm.useramask) {
195 		set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index);
196 		set_tx_desc_macid(txdesc, tcb_desc->mac_id);
197 	} else {
198 		set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index);
199 		set_tx_desc_macid(txdesc, tcb_desc->ratr_index);
200 	}
201 
202 	if (!ieee80211_is_data_qos(fc) && ppsc->leisure_ps &&
203 	    ppsc->fwctrl_lps) {
204 		set_tx_desc_hwseq_en(txdesc, 1);
205 		set_tx_desc_pkt_id(txdesc, 8);
206 	}
207 
208 	if (ieee80211_has_morefrags(fc))
209 		set_tx_desc_more_frag(txdesc, 1);
210 	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
211 	    is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
212 		set_tx_desc_bmc(txdesc, 1);
213 
214 	set_tx_desc_own(txdesc, 1);
215 	set_tx_desc_last_seg(txdesc, 1);
216 	set_tx_desc_first_seg(txdesc, 1);
217 	_rtl92du_tx_desc_checksum(txdesc);
218 
219 	rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
220 }
221 
_rtl92du_config_out_ep(struct ieee80211_hw * hw,u8 num_out_pipe)222 static void _rtl92du_config_out_ep(struct ieee80211_hw *hw, u8 num_out_pipe)
223 {
224 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
225 	struct rtl_priv *rtlpriv = rtl_priv(hw);
226 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
227 	u16 ep_cfg;
228 
229 	rtlusb->out_queue_sel = 0;
230 	rtlusb->out_ep_nums = 0;
231 
232 	if (rtlhal->interfaceindex == 0)
233 		ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC0);
234 	else
235 		ep_cfg = rtl_read_word(rtlpriv, REG_USB_Queue_Select_MAC1);
236 
237 	if (ep_cfg & 0x00f) {
238 		rtlusb->out_queue_sel |= TX_SELE_HQ;
239 		rtlusb->out_ep_nums++;
240 	}
241 	if (ep_cfg & 0x0f0) {
242 		rtlusb->out_queue_sel |= TX_SELE_NQ;
243 		rtlusb->out_ep_nums++;
244 	}
245 	if (ep_cfg & 0xf00) {
246 		rtlusb->out_queue_sel |= TX_SELE_LQ;
247 		rtlusb->out_ep_nums++;
248 	}
249 
250 	switch (num_out_pipe) {
251 	case 3:
252 		rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ | TX_SELE_LQ;
253 		rtlusb->out_ep_nums = 3;
254 		break;
255 	case 2:
256 		rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_NQ;
257 		rtlusb->out_ep_nums = 2;
258 		break;
259 	case 1:
260 		rtlusb->out_queue_sel = TX_SELE_HQ;
261 		rtlusb->out_ep_nums = 1;
262 		break;
263 	default:
264 		break;
265 	}
266 }
267 
_rtl92du_one_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)268 static void _rtl92du_one_out_ep_mapping(struct rtl_usb *rtlusb,
269 					struct rtl_ep_map *ep_map)
270 {
271 	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[0];
272 	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[0];
273 	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0];
274 	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
275 	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
276 	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
277 	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
278 }
279 
_rtl92du_two_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)280 static void _rtl92du_two_out_ep_mapping(struct rtl_usb *rtlusb,
281 					struct rtl_ep_map *ep_map)
282 {
283 	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[1];
284 	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[1];
285 	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[0];
286 	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
287 	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
288 	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
289 	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
290 }
291 
_rtl92du_three_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)292 static void _rtl92du_three_out_ep_mapping(struct rtl_usb *rtlusb,
293 					  struct rtl_ep_map *ep_map)
294 {
295 	ep_map->ep_mapping[RTL_TXQ_BE] = rtlusb->out_eps[2];
296 	ep_map->ep_mapping[RTL_TXQ_BK] = rtlusb->out_eps[2];
297 	ep_map->ep_mapping[RTL_TXQ_VI] = rtlusb->out_eps[1];
298 	ep_map->ep_mapping[RTL_TXQ_VO] = rtlusb->out_eps[0];
299 	ep_map->ep_mapping[RTL_TXQ_MGT] = rtlusb->out_eps[0];
300 	ep_map->ep_mapping[RTL_TXQ_BCN] = rtlusb->out_eps[0];
301 	ep_map->ep_mapping[RTL_TXQ_HI] = rtlusb->out_eps[0];
302 }
303 
_rtl92du_out_ep_mapping(struct ieee80211_hw * hw)304 static int _rtl92du_out_ep_mapping(struct ieee80211_hw *hw)
305 {
306 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
307 	struct rtl_ep_map *ep_map = &rtlusb->ep_map;
308 
309 	switch (rtlusb->out_ep_nums) {
310 	case 1:
311 		_rtl92du_one_out_ep_mapping(rtlusb, ep_map);
312 		break;
313 	case 2:
314 		_rtl92du_two_out_ep_mapping(rtlusb, ep_map);
315 		break;
316 	case 3:
317 		_rtl92du_three_out_ep_mapping(rtlusb, ep_map);
318 		break;
319 	default:
320 		return -EINVAL;
321 	}
322 
323 	return 0;
324 }
325 
rtl92du_endpoint_mapping(struct ieee80211_hw * hw)326 int rtl92du_endpoint_mapping(struct ieee80211_hw *hw)
327 {
328 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
329 
330 	_rtl92du_config_out_ep(hw, rtlusb->out_ep_nums);
331 
332 	/* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
333 	if (rtlusb->out_ep_nums == 1 && rtlusb->in_ep_nums != 1)
334 		return -EINVAL;
335 
336 	return _rtl92du_out_ep_mapping(hw);
337 }
338 
rtl92du_mq_to_hwq(__le16 fc,u16 mac80211_queue_index)339 u16 rtl92du_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
340 {
341 	u16 hw_queue_index;
342 
343 	if (unlikely(ieee80211_is_beacon(fc))) {
344 		hw_queue_index = RTL_TXQ_BCN;
345 		goto out;
346 	}
347 	if (ieee80211_is_mgmt(fc)) {
348 		hw_queue_index = RTL_TXQ_MGT;
349 		goto out;
350 	}
351 
352 	switch (mac80211_queue_index) {
353 	case 0:
354 		hw_queue_index = RTL_TXQ_VO;
355 		break;
356 	case 1:
357 		hw_queue_index = RTL_TXQ_VI;
358 		break;
359 	case 2:
360 		hw_queue_index = RTL_TXQ_BE;
361 		break;
362 	case 3:
363 		hw_queue_index = RTL_TXQ_BK;
364 		break;
365 	default:
366 		hw_queue_index = RTL_TXQ_BE;
367 		WARN_ONCE(true, "rtl8192du: QSLT_BE queue, skb_queue:%d\n",
368 			  mac80211_queue_index);
369 		break;
370 	}
371 out:
372 	return hw_queue_index;
373 }
374