drivers/net/wireless/realtek/rtw89/core.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/realtek/rtw89/core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtw89/core.c
Extension
.c
Size
227596 bytes
Lines
7634
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

struct rtw89_vif_rx_stats_iter_data {
	struct rtw89_dev *rtwdev;
	struct rtw89_rx_phy_ppdu *phy_ppdu;
	struct rtw89_rx_desc_info *desc_info;
	struct sk_buff *skb;
	const u8 *bssid;
};

static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
				      struct rtw89_vif_link *rtwvif_link,
				      struct ieee80211_bss_conf *bss_conf,
				      struct sk_buff *skb)
{
	struct ieee80211_trigger *tf = (struct ieee80211_trigger *)skb->data;
	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
	u8 *pos, *end, type, tf_bw;
	u16 aid, tf_rua;

	if (!ether_addr_equal(bss_conf->bssid, tf->ta) ||
	    rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION ||
	    rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK)
		return;

	type = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_TYPE_MASK);
	if (type != IEEE80211_TRIGGER_TYPE_BASIC && type != IEEE80211_TRIGGER_TYPE_MU_BAR)
		return;

	end = (u8 *)tf + skb->len;
	pos = tf->variable;

	while (end - pos >= RTW89_TF_BASIC_USER_INFO_SZ) {
		aid = RTW89_GET_TF_USER_INFO_AID12(pos);
		tf_rua = RTW89_GET_TF_USER_INFO_RUA(pos);
		tf_bw = le64_get_bits(tf->common_info, IEEE80211_TRIGGER_ULBW_MASK);
		rtw89_debug(rtwdev, RTW89_DBG_TXRX,
			    "[TF] aid: %d, ul_mcs: %d, rua: %d, bw: %d\n",
			    aid, RTW89_GET_TF_USER_INFO_UL_MCS(pos),
			    tf_rua, tf_bw);

		if (aid == RTW89_TF_PAD)
			break;

		if (aid == vif->cfg.aid) {
			enum nl80211_he_ru_alloc rua;

			rtwvif->stats.rx_tf_acc++;
			rtwdev->stats.rx_tf_acc++;

			/* The following only required for HE trigger frame, but we
			 * cannot use UL HE-SIG-A2 reserved subfield to identify it
			 * since some 11ax APs will fill it with all 0s, which will
			 * be misunderstood as EHT trigger frame.
			 */
			if (bss_conf->eht_support)
				break;

			rua = rtw89_he_rua_to_ru_alloc(tf_rua >> 1);

			if (tf_bw == IEEE80211_TRIGGER_ULBW_160_80P80MHZ &&
			    rua <= NL80211_RATE_INFO_HE_RU_ALLOC_106)
				rtwvif_link->pwr_diff_en = true;
			break;
		}

		pos += RTW89_TF_BASIC_USER_INFO_SZ;
	}
}

static void rtw89_cancel_6ghz_probe_work(struct wiphy *wiphy, struct wiphy_work *work)
{
	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
						cancel_6ghz_probe_work);
	struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
	struct rtw89_pktofld_info *info;

	lockdep_assert_wiphy(wiphy);

	if (!rtwdev->scanning)
		return;

	list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) {
		if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload))
			continue;

		rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);

		/* Don't delete/free info from pkt_list at this moment. Let it
		 * be deleted/freed in rtw89_release_pkt_list() after scanning,
		 * since if during scanning, pkt_list is accessed in bottom half.

Annotation

Implementation Notes