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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtw89/wow.c
Extension
.c
Size
49644 bytes
Lines
1827
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 (sta) {
			ret = rtw89_tx_pn_to_iv(rtwdev, key,
						key_info->ptk_tx_iv);
			if (ret)
				goto err;
			ret = rtw89_rx_pn_to_iv(rtwdev, key,
						key_info->ptk_rx_iv);
			if (ret)
				goto err;

			rtw_wow->ptk_alg = cipher_info->fw_alg;
			rtw_wow->ptk_keyidx = key->keyidx;
		} else {
			ret = rtw89_rx_pn_to_iv(rtwdev, key,
						key_info->gtk_rx_iv[key->keyidx]);
			if (ret)
				goto err;

			rtw_wow->gtk_alg = cipher_info->fw_alg;
			key_info->gtk_keyidx = key->keyidx;
		}
		break;
	case WLAN_CIPHER_SUITE_AES_CMAC:
		ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info);
		if (ret)
			goto err;
		break;
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
		/* WEP only set group key in mac80211, but fw need to set
		 * both of pairwise key and group key.
		 */
		rtw_wow->ptk_alg = cipher_info->fw_alg;
		rtw_wow->ptk_keyidx = key->keyidx;
		rtw_wow->gtk_alg = cipher_info->fw_alg;
		key_info->gtk_keyidx = key->keyidx;
		break;
	default:
		rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupport cipher %x\n",
			    key->cipher);
		goto err;
	}

	return;
err:
	*err = true;
}

static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
					struct ieee80211_sta *sta,
					struct ieee80211_key_conf *key,
					void *data)
{
	struct rtw89_dev *rtwdev = hw->priv;
	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
	struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
	struct rtw89_set_key_info_iter_data *iter_data = data;
	bool update_tx_key_info = iter_data->rx_ready;
	u8 tmp[RTW89_MIC_KEY_LEN];
	int ret;

	switch (key->cipher) {
	case WLAN_CIPHER_SUITE_TKIP:
		/*
		 * TX MIC KEY and RX MIC KEY is oppsite in FW,
		 * need to swap it before sending to mac80211.
		 */
		if (!sta && update_tx_key_info && aoac_rpt->rekey_ok &&
		    !iter_data->tkip_gtk_swapped) {
			memcpy(tmp, &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
			       RTW89_MIC_KEY_LEN);
			memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
			       &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
			       RTW89_MIC_KEY_LEN);
			memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
			       tmp, RTW89_MIC_KEY_LEN);
			iter_data->tkip_gtk_swapped = true;
		}
		fallthrough;
	case WLAN_CIPHER_SUITE_CCMP:
	case WLAN_CIPHER_SUITE_GCMP:
	case WLAN_CIPHER_SUITE_CCMP_256:
	case WLAN_CIPHER_SUITE_GCMP_256:
		if (sta && !update_tx_key_info) {
			ret = rtw89_rx_iv_to_pn(rtwdev, key,
						aoac_rpt->ptk_rx_iv);
			if (ret)
				goto err;
		}

Annotation

Implementation Notes