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 12 void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb) 13 { 14 } 15 16 int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, 17 struct sk_buff *skb) 18 { 19 return 0; 20 } 21 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 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 */ 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 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 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 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 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 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 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 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 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