140 lines
5.0 KiB
Diff
140 lines
5.0 KiB
Diff
From 28c11c29494f1b34e39641eead9c60a8bd26170d Mon Sep 17 00:00:00 2001
|
|
From: Po-Hao Huang <phhuang@realtek.com>
|
|
Date: Fri, 16 Jun 2023 20:55:40 +0800
|
|
Subject: [PATCH 8/8] wifi: rtw88: fix not entering PS mode after AP stops
|
|
|
|
Without this patch, firmware only track beacons for port 0 and since
|
|
we will always start AP on port 0, this results in misbehavior of
|
|
power saving mode on other ports after AP stops.
|
|
|
|
The "default port" H2C command is used to notify which port should
|
|
firmware track. Update the correct settings to firmware so power
|
|
saving mode can work properly.
|
|
|
|
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
|
|
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
|
Link: https://lore.kernel.org/r/20230616125540.36877-7-pkshih@realtek.com
|
|
---
|
|
drivers/net/wireless/realtek/rtw88/fw.c | 17 +++++++++++++++++
|
|
drivers/net/wireless/realtek/rtw88/fw.h | 8 ++++++++
|
|
drivers/net/wireless/realtek/rtw88/mac80211.c | 1 +
|
|
drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++++
|
|
drivers/net/wireless/realtek/rtw88/main.h | 1 +
|
|
5 files changed, 35 insertions(+)
|
|
|
|
--- a/drivers/net/wireless/realtek/rtw88/fw.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
|
|
@@ -519,6 +519,23 @@ void rtw_fw_query_bt_info(struct rtw_dev
|
|
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
|
|
}
|
|
|
|
+void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif)
|
|
+{
|
|
+ struct rtw_h2c_register h2c = {};
|
|
+
|
|
+ if (rtwvif->net_type != RTW_NET_MGD_LINKED)
|
|
+ return;
|
|
+
|
|
+ /* Leave LPS before default port H2C so FW timer is correct */
|
|
+ rtw_leave_lps(rtwdev);
|
|
+
|
|
+ h2c.w0 = u32_encode_bits(H2C_CMD_DEFAULT_PORT, RTW_H2C_W0_CMDID) |
|
|
+ u32_encode_bits(rtwvif->port, RTW_H2C_DEFAULT_PORT_W0_PORTID) |
|
|
+ u32_encode_bits(rtwvif->mac_id, RTW_H2C_DEFAULT_PORT_W0_MACID);
|
|
+
|
|
+ rtw_fw_send_h2c_command_register(rtwdev, &h2c);
|
|
+}
|
|
+
|
|
void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw)
|
|
{
|
|
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
|
|
--- a/drivers/net/wireless/realtek/rtw88/fw.h
|
|
+++ b/drivers/net/wireless/realtek/rtw88/fw.h
|
|
@@ -86,6 +86,12 @@ struct rtw_h2c_register {
|
|
u32 w1;
|
|
} __packed;
|
|
|
|
+#define RTW_H2C_W0_CMDID GENMASK(7, 0)
|
|
+
|
|
+/* H2C_CMD_DEFAULT_PORT command */
|
|
+#define RTW_H2C_DEFAULT_PORT_W0_PORTID GENMASK(15, 8)
|
|
+#define RTW_H2C_DEFAULT_PORT_W0_MACID GENMASK(23, 16)
|
|
+
|
|
struct rtw_h2c_cmd {
|
|
__le32 msg;
|
|
__le32 msg_ext;
|
|
@@ -535,6 +541,7 @@ static inline void rtw_h2c_pkt_set_heade
|
|
#define H2C_CMD_MEDIA_STATUS_RPT 0x01
|
|
#define H2C_CMD_SET_PWR_MODE 0x20
|
|
#define H2C_CMD_LPS_PG_INFO 0x2b
|
|
+#define H2C_CMD_DEFAULT_PORT 0x2c
|
|
#define H2C_CMD_RA_INFO 0x40
|
|
#define H2C_CMD_RSSI_MONITOR 0x42
|
|
#define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56
|
|
@@ -806,6 +813,7 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rt
|
|
void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb);
|
|
void rtw_fw_send_general_info(struct rtw_dev *rtwdev);
|
|
void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev);
|
|
+void rtw_fw_default_port(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif);
|
|
|
|
void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para);
|
|
void rtw_fw_inform_rfk_status(struct rtw_dev *rtwdev, bool start);
|
|
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
|
|
@@ -381,6 +381,7 @@ static void rtw_ops_bss_info_changed(str
|
|
|
|
rtw_fw_download_rsvd_page(rtwdev);
|
|
rtw_send_rsvd_page_h2c(rtwdev);
|
|
+ rtw_fw_default_port(rtwdev, rtwvif);
|
|
rtw_coex_media_status_notify(rtwdev, vif->cfg.assoc);
|
|
if (rtw_bf_support)
|
|
rtw_bf_assoc(rtwdev, vif, conf);
|
|
--- a/drivers/net/wireless/realtek/rtw88/main.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/main.c
|
|
@@ -334,12 +334,15 @@ int rtw_sta_add(struct rtw_dev *rtwdev,
|
|
struct ieee80211_vif *vif)
|
|
{
|
|
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
|
|
+ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
|
|
int i;
|
|
|
|
si->mac_id = rtw_acquire_macid(rtwdev);
|
|
if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
|
|
return -ENOSPC;
|
|
|
|
+ if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0)
|
|
+ rtwvif->mac_id = si->mac_id;
|
|
si->rtwdev = rtwdev;
|
|
si->sta = sta;
|
|
si->vif = vif;
|
|
@@ -2338,6 +2341,9 @@ static void rtw_port_switch_iter(void *d
|
|
rtw_dbg(rtwdev, RTW_DBG_STATE, "AP port switch from %d -> %d\n",
|
|
rtwvif_ap->port, rtwvif_target->port);
|
|
|
|
+ /* Leave LPS so the value swapped are not in PS mode */
|
|
+ rtw_leave_lps(rtwdev);
|
|
+
|
|
reg1 = &rtwvif_ap->conf->net_type;
|
|
reg2 = &rtwvif_target->conf->net_type;
|
|
rtw_swap_reg_mask(rtwdev, reg1, reg2);
|
|
@@ -2356,6 +2362,8 @@ static void rtw_port_switch_iter(void *d
|
|
|
|
swap(rtwvif_target->port, rtwvif_ap->port);
|
|
swap(rtwvif_target->conf, rtwvif_ap->conf);
|
|
+
|
|
+ rtw_fw_default_port(rtwdev, rtwvif_target);
|
|
}
|
|
|
|
void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
|
|
--- a/drivers/net/wireless/realtek/rtw88/main.h
|
|
+++ b/drivers/net/wireless/realtek/rtw88/main.h
|
|
@@ -803,6 +803,7 @@ struct rtw_bf_info {
|
|
struct rtw_vif {
|
|
enum rtw_net_type net_type;
|
|
u16 aid;
|
|
+ u8 mac_id; /* for STA mode only */
|
|
u8 mac_addr[ETH_ALEN];
|
|
u8 bssid[ETH_ALEN];
|
|
u8 port;
|