wifi: rtw89: refine packet offload flow
For upcoming firmware, driver needs to do packet offload to firmware to ensure LPS protocol work properly, so we update current connection and disconnect flow to maintain packet offload flow, and integrate with current WoWLAN flow which also needs packet offload. Signed-off-by: Chin-Yen Lee <timlee@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/20230123065401.14174-3-pkshih@realtek.com
This commit is contained in:
parent
b8e8ff842b
commit
5c12bb66b7
@ -2495,8 +2495,10 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
|
||||
if (sta->tdls)
|
||||
rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
|
||||
rtw89_vif_type_mapping(vif, false);
|
||||
rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true);
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
|
||||
if (ret) {
|
||||
@ -2584,12 +2586,6 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtwdev->total_sta_assoc++;
|
||||
if (sta->tdls)
|
||||
rtwvif->tdls_peer++;
|
||||
@ -2608,6 +2604,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
|
||||
BTC_ROLE_MSTS_STA_CONN_END);
|
||||
rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template);
|
||||
rtw89_phy_ul_tb_assoc(rtwdev, rtwvif);
|
||||
|
||||
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -3132,7 +3134,6 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
|
||||
continue;
|
||||
INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]);
|
||||
}
|
||||
INIT_LIST_HEAD(&rtwdev->wow.pkt_list);
|
||||
INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work);
|
||||
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
|
||||
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
|
||||
|
@ -2461,6 +2461,7 @@ struct rtw89_vif {
|
||||
struct rtw89_phy_rate_pattern rate_pattern;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
struct ieee80211_scan_ies *scan_ies;
|
||||
struct list_head general_pkt_list;
|
||||
};
|
||||
|
||||
enum rtw89_lv1_rcvy_step {
|
||||
@ -3724,7 +3725,6 @@ struct rtw89_wow_param {
|
||||
DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
|
||||
struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
|
||||
u8 pattern_cnt;
|
||||
struct list_head pkt_list;
|
||||
};
|
||||
|
||||
struct rtw89_mcc_info {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mac.h"
|
||||
#include "phy.h"
|
||||
#include "reg.h"
|
||||
#include "util.h"
|
||||
|
||||
static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
|
||||
struct sk_buff *skb);
|
||||
@ -913,13 +914,12 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev,
|
||||
static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif,
|
||||
enum rtw89_fw_pkt_ofld_type type,
|
||||
u8 *id)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct rtw89_pktofld_info *info;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
@ -954,7 +954,7 @@ static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
list_add_tail(&info->list, &rtw_wow->pkt_list);
|
||||
list_add_tail(&info->list, &rtwvif->general_pkt_list);
|
||||
*id = info->id;
|
||||
return 0;
|
||||
|
||||
@ -963,13 +963,48 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool notify_fw)
|
||||
{
|
||||
struct list_head *pkt_list = &rtwvif->general_pkt_list;
|
||||
struct rtw89_pktofld_info *info, *tmp;
|
||||
|
||||
list_for_each_entry_safe(info, tmp, pkt_list, list) {
|
||||
if (notify_fw)
|
||||
rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
|
||||
rtw89_core_release_bit_map(rtwdev->pkt_offload,
|
||||
info->id);
|
||||
list_del(&info->list);
|
||||
kfree(info);
|
||||
}
|
||||
}
|
||||
|
||||
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw)
|
||||
{
|
||||
struct rtw89_vif *rtwvif;
|
||||
|
||||
rtw89_for_each_rtwvif(rtwdev, rtwvif)
|
||||
rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, notify_fw);
|
||||
}
|
||||
|
||||
#define H2C_GENERAL_PKT_LEN 6
|
||||
#define H2C_GENERAL_PKT_ID_UND 0xff
|
||||
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid)
|
||||
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, u8 macid)
|
||||
{
|
||||
u8 pkt_id_ps_poll = H2C_GENERAL_PKT_ID_UND;
|
||||
u8 pkt_id_null = H2C_GENERAL_PKT_ID_UND;
|
||||
u8 pkt_id_qos_null = H2C_GENERAL_PKT_ID_UND;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll);
|
||||
rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null);
|
||||
rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_QOS_NULL, &pkt_id_qos_null);
|
||||
|
||||
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_GENERAL_PKT_LEN);
|
||||
if (!skb) {
|
||||
rtw89_err(rtwdev, "failed to alloc skb for fw dl\n");
|
||||
@ -978,9 +1013,9 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid)
|
||||
skb_put(skb, H2C_GENERAL_PKT_LEN);
|
||||
SET_GENERAL_PKT_MACID(skb->data, macid);
|
||||
SET_GENERAL_PKT_PROBRSP_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
|
||||
SET_GENERAL_PKT_PSPOLL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
|
||||
SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
|
||||
SET_GENERAL_PKT_QOS_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
|
||||
SET_GENERAL_PKT_PSPOLL_ID(skb->data, pkt_id_ps_poll);
|
||||
SET_GENERAL_PKT_NULL_ID(skb->data, pkt_id_null);
|
||||
SET_GENERAL_PKT_QOS_NULL_ID(skb->data, pkt_id_qos_null);
|
||||
SET_GENERAL_PKT_CTS2SELF_ID(skb->data, H2C_GENERAL_PKT_ID_UND);
|
||||
|
||||
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
@ -3099,8 +3134,9 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id);
|
||||
ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif,
|
||||
RTW89_PKT_OFLD_TYPE_NULL_DATA,
|
||||
&pkt_id);
|
||||
if (ret)
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -3518,7 +3518,11 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
|
||||
int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len);
|
||||
void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev);
|
||||
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
|
||||
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid);
|
||||
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
|
||||
u8 macid);
|
||||
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
|
||||
struct rtw89_vif *rtwvif, bool notify_fw);
|
||||
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw);
|
||||
int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
|
||||
bool valid, struct ieee80211_ampdu_params *params);
|
||||
void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev);
|
||||
|
@ -135,6 +135,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
|
||||
rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
|
||||
rtwvif->hit_rule = 0;
|
||||
ether_addr_copy(rtwvif->mac_addr, vif->addr);
|
||||
INIT_LIST_HEAD(&rtwvif->general_pkt_list);
|
||||
|
||||
ret = rtw89_mac_add_vif(rtwdev, rtwvif);
|
||||
if (ret) {
|
||||
|
@ -611,6 +611,7 @@ bottom:
|
||||
ser_reset_mac_binding(rtwdev);
|
||||
rtw89_core_stop(rtwdev);
|
||||
rtw89_entity_init(rtwdev);
|
||||
rtw89_fw_release_general_pkt_list(rtwdev, false);
|
||||
INIT_LIST_HEAD(&rtwdev->rtwvifs_list);
|
||||
}
|
||||
|
||||
|
@ -490,21 +490,6 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
|
||||
struct list_head *pkt_list = &rtw_wow->pkt_list;
|
||||
struct rtw89_pktofld_info *info, *tmp;
|
||||
|
||||
list_for_each_entry_safe(info, tmp, pkt_list, list) {
|
||||
rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id);
|
||||
rtw89_core_release_bit_map(rtwdev->pkt_offload,
|
||||
info->id);
|
||||
list_del(&info->list);
|
||||
kfree(info);
|
||||
}
|
||||
}
|
||||
|
||||
static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
{
|
||||
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
|
||||
@ -561,6 +546,11 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
|
||||
}
|
||||
|
||||
if (is_conn) {
|
||||
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
|
||||
if (ret) {
|
||||
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
|
||||
return ret;
|
||||
}
|
||||
rtw89_phy_ra_assoc(rtwdev, wow_sta);
|
||||
rtw89_phy_set_bss_color(rtwdev, wow_vif);
|
||||
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
|
||||
@ -708,8 +698,6 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtw89_wow_release_pkt_list(rtwdev);
|
||||
|
||||
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
|
||||
@ -744,6 +732,8 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtw89_fw_release_general_pkt_list(rtwdev, true);
|
||||
|
||||
ret = rtw89_wow_swap_fw(rtwdev, true);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to swap to wow fw\n");
|
||||
@ -789,6 +779,8 @@ static int rtw89_wow_disable(struct rtw89_dev *rtwdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rtw89_fw_release_general_pkt_list(rtwdev, true);
|
||||
|
||||
ret = rtw89_wow_swap_fw(rtwdev, false);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "wow: failed to disable trx_post\n");
|
||||
|
Loading…
Reference in New Issue
Block a user