@@ -21,6 +21,7 @@ enum rtw_debug_mask {
RTW_DBG_WOW = 0x00001000,
RTW_DBG_CFO = 0x00002000,
RTW_DBG_PATH_DIV = 0x00004000,
+ RTW_DBG_ADAPTIVITY = 0x00008000,
RTW_DBG_ALL = 0xffffffff
};
@@ -183,6 +183,28 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
dm_info->scan_density);
}
+static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
+ u8 length)
+{
+ struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
+ struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
+
+ rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
+ "Adaptivity: density %x igi %x l2h_th_init %x l2h %x h2l %x option %x\n",
+ result->density, result->igi, result->l2h_th_init, result->l2h,
+ result->h2l, result->option);
+
+ rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "Reg Setting: L2H %x H2L %x\n",
+ rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
+ edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask),
+ rtw_read32_mask(rtwdev, edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr,
+ edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask));
+
+ rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, "EDCCA Flag %s\n",
+ rtw_read32_mask(rtwdev, REG_EDCCA_REPORT, BIT_EDCCA_FLAG) ?
+ "Set" : "Unset");
+}
+
void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
{
struct rtw_c2h_cmd *c2h;
@@ -252,6 +274,10 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset,
rtw_fw_scan_result(rtwdev, c2h->payload, len);
dev_kfree_skb_any(skb);
break;
+ case C2H_ADAPTIVITY:
+ rtw_fw_adaptivity_result(rtwdev, c2h->payload, len);
+ dev_kfree_skb_any(skb);
+ break;
default:
/* pass offset for further operation */
*((u32 *)skb->cb) = pkt_offset;
@@ -1718,6 +1744,27 @@ void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable)
rtw_fw_send_h2c_packet(rtwdev, h2c_pkt);
}
+void rtw_fw_adaptivity(struct rtw_dev *rtwdev)
+{
+ struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+ u8 h2c_pkt[H2C_PKT_SIZE] = {0};
+
+ if (!rtw_edcca_enabled) {
+ dm_info->edcca_mode = RTW_EDCCA_NORMAL;
+ rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,
+ "EDCCA disabled by debugfs\n");
+ }
+
+ SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_ADAPTIVITY);
+ SET_ADAPTIVITY_MODE(h2c_pkt, dm_info->edcca_mode);
+ SET_ADAPTIVITY_OPTION(h2c_pkt, 2);
+ SET_ADAPTIVITY_IGI(h2c_pkt, dm_info->igi_history[0]);
+ SET_ADAPTIVITY_L2H(h2c_pkt, dm_info->l2h_th_ini);
+ SET_ADAPTIVITY_DENSITY(h2c_pkt, dm_info->scan_density);
+
+ rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
+}
+
void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start)
{
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
@@ -41,6 +41,7 @@ enum rtw_c2h_cmd_id {
C2H_WLAN_INFO = 0x27,
C2H_WLAN_RFON = 0x32,
C2H_BCN_FILTER_NOTIFY = 0x36,
+ C2H_ADAPTIVITY = 0x37,
C2H_SCAN_RESULT = 0x38,
C2H_HW_FEATURE_DUMP = 0xfd,
C2H_HALMAC = 0xff,
@@ -56,6 +57,15 @@ struct rtw_c2h_cmd {
u8 payload[];
} __packed;
+struct rtw_c2h_adaptivity {
+ u8 density;
+ u8 igi;
+ u8 l2h_th_init;
+ u8 l2h;
+ u8 h2l;
+ u8 option;
+} __packed;
+
enum rtw_rsvd_packet_type {
RSVD_BEACON,
RSVD_DUMMY,
@@ -90,6 +100,7 @@ enum rtw_fw_feature {
FW_FEATURE_PG = BIT(3),
FW_FEATURE_BCN_FILTER = BIT(5),
FW_FEATURE_NOTIFY_SCAN = BIT(6),
+ FW_FEATURE_ADAPTIVITY = BIT(7),
FW_FEATURE_MAX = BIT(31),
};
@@ -374,6 +385,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
#define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57
#define H2C_CMD_WL_PHY_INFO 0x58
#define H2C_CMD_SCAN 0x59
+#define H2C_CMD_ADAPTIVITY 0x5A
#define H2C_CMD_COEX_TDMA_TYPE 0x60
#define H2C_CMD_QUERY_BT_INFO 0x61
@@ -427,6 +439,17 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
#define SET_SCAN_START(h2c_pkt, value) \
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
+#define SET_ADAPTIVITY_MODE(h2c_pkt, value) \
+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(11, 8))
+#define SET_ADAPTIVITY_OPTION(h2c_pkt, value) \
+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 12))
+#define SET_ADAPTIVITY_IGI(h2c_pkt, value) \
+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
+#define SET_ADAPTIVITY_L2H(h2c_pkt, value) \
+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24))
+#define SET_ADAPTIVITY_DENSITY(h2c_pkt, value) \
+ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 0))
+
#define SET_PWR_MODE_SET_MODE(h2c_pkt, value) \
le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(14, 8))
#define SET_PWR_MODE_SET_RLBM(h2c_pkt, value) \
@@ -661,4 +684,5 @@ void rtw_fw_c2h_cmd_isr(struct rtw_dev *rtwdev);
int rtw_fw_dump_fifo(struct rtw_dev *rtwdev, u8 fifo_sel, u32 addr, u32 size,
u32 *buffer);
void rtw_fw_scan_notify(struct rtw_dev *rtwdev, bool start);
+void rtw_fw_adaptivity(struct rtw_dev *rtwdev);
#endif
@@ -770,7 +770,11 @@ void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
rtw_phy_cfo_track(rtwdev);
rtw_phy_dpk_track(rtwdev);
rtw_phy_pwr_track(rtwdev);
- rtw_phy_adaptivity(rtwdev);
+
+ if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_ADAPTIVITY))
+ rtw_fw_adaptivity(rtwdev);
+ else
+ rtw_phy_adaptivity(rtwdev);
}
#define FRAC_BITS 3
@@ -642,6 +642,9 @@
#define REG_HRCV_MSG 0x1cf
+#define REG_EDCCA_REPORT 0x2d38
+#define BIT_EDCCA_FLAG BIT(24)
+
#define REG_IGN_GNTBT4 0x4160
#define RF_MODE 0x00