Commit 41d56769 authored by Chih-Kang Chang's avatar Chih-Kang Chang Committed by Kalle Valo
Browse files

wifi: rtw89: add drop tx packet function



When entering WoWLAN mode, we need to drop all transmit packets,
including those in mac buffer, to avoid memory leakage, so implement
the drop_tx function.

Signed-off-by: default avatarChih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: default avatarChin-Yen Lee <timlee@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221027052707.14605-5-pkshih@realtek.com
parent 7a68ec3d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2624,6 +2624,8 @@ struct rtw89_chip_info {
	u32 rsvd_ple_ofst;
	const struct rtw89_hfc_param_ini *hfc_param_ini;
	const struct rtw89_dle_mem *dle_mem;
	u8 wde_qempty_acq_num;
	u8 wde_qempty_mgq_sel;
	u32 rf_base_addr[2];
	u8 support_chanctx_num;
	u8 support_bands;
@@ -2949,6 +2951,7 @@ struct rtw89_pkt_drop_params {
	u8 port;
	u8 mbssid;
	bool tf_trs;
	u32 macid_band_sel[4];
};

struct rtw89_pkt_stat {
+9 −0
Original line number Diff line number Diff line
@@ -2900,6 +2900,7 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
	case RTW89_PKT_DROP_SEL_MACID_BK_ONCE:
	case RTW89_PKT_DROP_SEL_MACID_VI_ONCE:
	case RTW89_PKT_DROP_SEL_MACID_VO_ONCE:
	case RTW89_PKT_DROP_SEL_BAND_ONCE:
		break;
	default:
		rtw89_debug(rtwdev, RTW89_DBG_FW,
@@ -2915,6 +2916,14 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
	RTW89_SET_FWCMD_PKT_DROP_PORT(skb->data, params->port);
	RTW89_SET_FWCMD_PKT_DROP_MBSSID(skb->data, params->mbssid);
	RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(skb->data, params->tf_trs);
	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(skb->data,
						  params->macid_band_sel[0]);
	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(skb->data,
						  params->macid_band_sel[1]);
	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(skb->data,
						  params->macid_band_sel[2]);
	RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(skb->data,
						  params->macid_band_sel[3]);

	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
			      H2C_CAT_MAC,
+20 −0
Original line number Diff line number Diff line
@@ -1873,6 +1873,26 @@ static inline void RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(void *cmd, u32 va
	le32p_replace_bits((__le32 *)cmd + 1, val, GENMASK(15, 8));
}

static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_0(void *cmd, u32 val)
{
	le32p_replace_bits((__le32 *)cmd + 2, val, GENMASK(31, 0));
}

static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_1(void *cmd, u32 val)
{
	le32p_replace_bits((__le32 *)cmd + 3, val, GENMASK(31, 0));
}

static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_2(void *cmd, u32 val)
{
	le32p_replace_bits((__le32 *)cmd + 4, val, GENMASK(31, 0));
}

static inline void RTW89_SET_FWCMD_PKT_DROP_MACID_BAND_SEL_3(void *cmd, u32 val)
{
	le32p_replace_bits((__le32 *)cmd + 5, val, GENMASK(31, 0));
}

enum rtw89_btc_btf_h2c_class {
	BTFC_SET = 0x10,
	BTFC_GET = 0x11,
+75 −0
Original line number Diff line number Diff line
@@ -1335,6 +1335,60 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev,
	return cfg;
}

static bool mac_is_txq_empty(struct rtw89_dev *rtwdev)
{
	struct rtw89_mac_dle_dfi_qempty qempty;
	u32 qnum, qtmp, val32, msk32;
	int i, j, ret;

	qnum = rtwdev->chip->wde_qempty_acq_num;
	qempty.dle_type = DLE_CTRL_TYPE_WDE;

	for (i = 0; i < qnum; i++) {
		qempty.grpsel = i;
		ret = dle_dfi_qempty(rtwdev, &qempty);
		if (ret) {
			rtw89_warn(rtwdev, "dle dfi acq empty %d\n", ret);
			return false;
		}
		qtmp = qempty.qempty;
		for (j = 0 ; j < QEMP_ACQ_GRP_MACID_NUM; j++) {
			val32 = FIELD_GET(QEMP_ACQ_GRP_QSEL_MASK, qtmp);
			if (val32 != QEMP_ACQ_GRP_QSEL_MASK)
				return false;
			qtmp >>= QEMP_ACQ_GRP_QSEL_SH;
		}
	}

	qempty.grpsel = rtwdev->chip->wde_qempty_mgq_sel;
	ret = dle_dfi_qempty(rtwdev, &qempty);
	if (ret) {
		rtw89_warn(rtwdev, "dle dfi mgq empty %d\n", ret);
		return false;
	}
	msk32 = B_CMAC0_MGQ_NORMAL | B_CMAC0_MGQ_NO_PWRSAV | B_CMAC0_CPUMGQ;
	if ((qempty.qempty & msk32) != msk32)
		return false;

	if (rtwdev->dbcc_en) {
		msk32 |= B_CMAC1_MGQ_NORMAL | B_CMAC1_MGQ_NO_PWRSAV | B_CMAC1_CPUMGQ;
		if ((qempty.qempty & msk32) != msk32)
			return false;
	}

	msk32 = B_AX_WDE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_WDE_EMPTY_QTA_DMAC_DATA_CPU |
		B_AX_PLE_EMPTY_QTA_DMAC_WLAN_CPU | B_AX_PLE_EMPTY_QTA_DMAC_H2C |
		B_AX_WDE_EMPTY_QUE_OTHERS | B_AX_PLE_EMPTY_QUE_DMAC_MPDU_TX |
		B_AX_WDE_EMPTY_QTA_DMAC_CPUIO | B_AX_PLE_EMPTY_QTA_DMAC_CPUIO |
		B_AX_WDE_EMPTY_QUE_DMAC_PKTIN | B_AX_WDE_EMPTY_QTA_DMAC_HIF |
		B_AX_PLE_EMPTY_QUE_DMAC_SEC_TX | B_AX_WDE_EMPTY_QTA_DMAC_PKTIN |
		B_AX_PLE_EMPTY_QTA_DMAC_B0_TXPL | B_AX_PLE_EMPTY_QTA_DMAC_B1_TXPL |
		B_AX_PLE_EMPTY_QTA_DMAC_MPDU_TX;
	val32 = rtw89_read32(rtwdev, R_AX_DLE_EMPTY0);

	return (val32 & msk32) == msk32;
}

static inline u32 dle_used_size(const struct rtw89_dle_size *wde,
				const struct rtw89_dle_size *ple)
{
@@ -4893,3 +4947,24 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
					  rtw89_mac_pkt_drop_vif_iter,
					  rtwvif);
}

int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
					enum rtw89_mac_idx band)
{
	struct rtw89_pkt_drop_params params = {0};
	bool empty;
	int i, ret = 0, try_cnt = 3;

	params.mac_band = band;
	params.sel = RTW89_PKT_DROP_SEL_BAND_ONCE;

	for (i = 0; i < try_cnt; i++) {
		ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50,
					50000, false, rtwdev);
		if (ret)
			rtw89_fw_h2c_pkt_drop(rtwdev, &params);
		else
			return 0;
	}
	return ret;
}
+13 −0
Original line number Diff line number Diff line
@@ -420,6 +420,17 @@ enum rtw89_mac_bf_rrsc_rate {
#define S_AX_PLE_PAGE_SEL_128	1
#define S_AX_PLE_PAGE_SEL_256	2

#define B_CMAC0_MGQ_NORMAL	BIT(2)
#define B_CMAC0_MGQ_NO_PWRSAV	BIT(3)
#define B_CMAC0_CPUMGQ		BIT(4)
#define B_CMAC1_MGQ_NORMAL	BIT(10)
#define B_CMAC1_MGQ_NO_PWRSAV	BIT(11)
#define B_CMAC1_CPUMGQ		BIT(12)

#define QEMP_ACQ_GRP_MACID_NUM	8
#define QEMP_ACQ_GRP_QSEL_SH	4
#define QEMP_ACQ_GRP_QSEL_MASK	0xF

#define SDIO_LOCAL_BASE_ADDR    0x80000000

#define	PWR_CMD_WRITE		0
@@ -1028,5 +1039,7 @@ u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd);
int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev,
			struct rtw89_cpuio_ctrl *ctrl_para, bool wd);
int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow);
int rtw89_mac_ptk_drop_by_band_and_wait(struct rtw89_dev *rtwdev,
					enum rtw89_mac_idx band);

#endif
Loading