brintos

brintos / linux-shallow public Read only

0
0
Text · 9.9 KiB · 743ce0c Raw
373 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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	else234		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}373