drivers/net/wireless/realtek/rtw88/tx.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/realtek/rtw88/tx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtw88/tx.c
Extension
.c
Size
20322 bytes
Lines
746
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (vif) {
			rtwvif = (struct rtw_vif *)vif->drv_priv;
			rtwvif->stats.tx_unicast += skb->len;
			rtwvif->stats.tx_cnt++;
		}
	}
}

void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
			 struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
{
	struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
	bool more_data = false;

	if (pkt_info->qsel == TX_DESC_QSEL_HIGH)
		more_data = true;

	tx_desc->w0 = le32_encode_bits(pkt_info->tx_pkt_size, RTW_TX_DESC_W0_TXPKTSIZE) |
		      le32_encode_bits(pkt_info->offset, RTW_TX_DESC_W0_OFFSET) |
		      le32_encode_bits(pkt_info->bmc, RTW_TX_DESC_W0_BMC) |
		      le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) |
		      le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ);

	tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) |
		      le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) |
		      le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) |
		      le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) |
		      le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) |
		      le32_encode_bits(more_data, RTW_TX_DESC_W1_MORE_DATA);

	tx_desc->w2 = le32_encode_bits(pkt_info->ampdu_en, RTW_TX_DESC_W2_AGG_EN) |
		      le32_encode_bits(pkt_info->report, RTW_TX_DESC_W2_SPE_RPT) |
		      le32_encode_bits(pkt_info->ampdu_density, RTW_TX_DESC_W2_AMPDU_DEN) |
		      le32_encode_bits(pkt_info->bt_null, RTW_TX_DESC_W2_BT_NULL);

	tx_desc->w3 = le32_encode_bits(pkt_info->hw_ssn_sel, RTW_TX_DESC_W3_HW_SSN_SEL) |
		      le32_encode_bits(pkt_info->use_rate, RTW_TX_DESC_W3_USE_RATE) |
		      le32_encode_bits(pkt_info->dis_rate_fallback, RTW_TX_DESC_W3_DISDATAFB) |
		      le32_encode_bits(pkt_info->rts, RTW_TX_DESC_W3_USE_RTS) |
		      le32_encode_bits(pkt_info->nav_use_hdr, RTW_TX_DESC_W3_NAVUSEHDR) |
		      le32_encode_bits(pkt_info->ampdu_factor, RTW_TX_DESC_W3_MAX_AGG_NUM);

	tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);

	if (rtwdev->chip->old_datarate_fb_limit)
		tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);

	tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
		      le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
		      le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |
		      le32_encode_bits(pkt_info->stbc, RTW_TX_DESC_W5_DATA_STBC);

	tx_desc->w6 = le32_encode_bits(pkt_info->sn, RTW_TX_DESC_W6_SW_DEFINE);

	tx_desc->w8 = le32_encode_bits(pkt_info->en_hwseq, RTW_TX_DESC_W8_EN_HWSEQ);

	tx_desc->w9 = le32_encode_bits(pkt_info->seq, RTW_TX_DESC_W9_SW_SEQ);

	if (pkt_info->rts) {
		tx_desc->w4 |= le32_encode_bits(DESC_RATE24M, RTW_TX_DESC_W4_RTSRATE);
		tx_desc->w5 |= le32_encode_bits(1, RTW_TX_DESC_W5_DATA_RTS_SHORT);
	}

	if (pkt_info->tim_offset)
		tx_desc->w9 |= le32_encode_bits(1, RTW_TX_DESC_W9_TIM_EN) |
			       le32_encode_bits(pkt_info->tim_offset, RTW_TX_DESC_W9_TIM_OFFSET);
}
EXPORT_SYMBOL(rtw_tx_fill_tx_desc);

static u8 get_tx_ampdu_factor(struct ieee80211_sta *sta)
{
	u8 exp = sta->deflink.ht_cap.ampdu_factor;

	/* the least ampdu factor is 8K, and the value in the tx desc is the
	 * max aggregation num, which represents val * 2 packets can be
	 * aggregated in an AMPDU, so here we should use 8/2=4 as the base
	 */
	return (BIT(2) << exp) - 1;
}

static u8 get_tx_ampdu_density(struct ieee80211_sta *sta)
{
	return sta->deflink.ht_cap.ampdu_density;
}

static u8 get_highest_ht_tx_rate(struct rtw_dev *rtwdev,
				 struct ieee80211_sta *sta)
{
	u8 rate;

Annotation

Implementation Notes