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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/realtek/rtw88/wow.c
Extension
.c
Size
22268 bytes
Lines
914
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 ((mask[i / 8] >> (i % 8)) & 0x01) {
			content[count] = pattern[i];
			count++;
		}
	}

	rtw_pattern->crc = rtw_calc_crc(content, count);
}

static void rtw_wow_pattern_clear_cam(struct rtw_dev *rtwdev)
{
	bool ret;

	rtw_write32(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 |
		    BIT_WKFCAM_CLR_V1);

	ret = check_hw_ready(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1, 0);
	if (!ret)
		rtw_err(rtwdev, "failed to clean pattern cam\n");
}

static void rtw_wow_pattern_write(struct rtw_dev *rtwdev)
{
	struct rtw_wow_param *rtw_wow = &rtwdev->wow;
	struct rtw_wow_pattern *rtw_pattern = rtw_wow->patterns;
	int i = 0;

	for (i = 0; i < rtw_wow->pattern_cnt; i++)
		rtw_wow_pattern_write_cam_ent(rtwdev, i, rtw_pattern + i);
}

static void rtw_wow_pattern_clear(struct rtw_dev *rtwdev)
{
	struct rtw_wow_param *rtw_wow = &rtwdev->wow;

	rtw_wow_pattern_clear_cam(rtwdev);

	rtw_wow->pattern_cnt = 0;
	memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns));
}

static void rtw_wow_bb_stop(struct rtw_dev *rtwdev)
{
	struct rtw_wow_param *rtw_wow = &rtwdev->wow;

	/* wait 100ms for firmware to finish TX */
	msleep(100);

	if (!rtw_read32_mask(rtwdev, REG_BCNQ_INFO, BIT_MGQ_CPU_EMPTY))
		rtw_warn(rtwdev, "Wrong status of MGQ_CPU empty!\n");

	rtw_wow->txpause = rtw_read8(rtwdev, REG_TXPAUSE);
	rtw_write8(rtwdev, REG_TXPAUSE, 0xff);
	rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB);
}

static void rtw_wow_bb_start(struct rtw_dev *rtwdev)
{
	struct rtw_wow_param *rtw_wow = &rtwdev->wow;

	rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB);
	rtw_write8(rtwdev, REG_TXPAUSE, rtw_wow->txpause);
}

static void rtw_wow_rx_dma_stop(struct rtw_dev *rtwdev)
{
	/* wait 100ms for HW to finish rx dma */
	msleep(100);

	rtw_write32_set(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE);

	if (!check_hw_ready(rtwdev, REG_RXPKT_NUM, BIT_RXDMA_IDLE, 1))
		rtw_err(rtwdev, "failed to stop rx dma\n");
}

static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev)
{
	rtw_write32_clr(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE);
}

static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable)
{
	int ret;
	u8 check;
	u32 check_dis;

	if (wow_enable) {
		ret = read_poll_timeout(rtw_read8, check, !check, 1000,
					100000, true, rtwdev,
					REG_WOWLAN_WAKE_REASON);

Annotation

Implementation Notes