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 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
_rtl92du_config_out_ep(struct ieee80211_hw * hw,u8 num_out_pipe)221 static 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
_rtl92du_one_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)267 static 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
_rtl92du_two_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)279 static 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
_rtl92du_three_out_ep_mapping(struct rtl_usb * rtlusb,struct rtl_ep_map * ep_map)291 static 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
_rtl92du_out_ep_mapping(struct ieee80211_hw * hw)303 static 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
rtl92du_endpoint_mapping(struct ieee80211_hw * hw)325 int 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
rtl92du_mq_to_hwq(__le16 fc,u16 mac80211_queue_index)338 u16 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 }
370 out:
371 return hw_queue_index;
372 }
373