From patchwork Wed Apr 22 03:46:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Chuang X-Patchwork-Id: 215899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6071C38A30 for ; Wed, 22 Apr 2020 03:46:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 90F302070B for ; Wed, 22 Apr 2020 03:46:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726487AbgDVDqW (ORCPT ); Tue, 21 Apr 2020 23:46:22 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:37003 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726430AbgDVDqS (ORCPT ); Tue, 21 Apr 2020 23:46:18 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.69 with qID 03M3kAzC5004569, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb06.realtek.com.tw[172.21.6.99]) by rtits2.realtek.com.tw (8.15.2/2.66/5.86) with ESMTPS id 03M3kAzC5004569 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Apr 2020 11:46:10 +0800 Received: from RTEXMB04.realtek.com.tw (172.21.6.97) by RTEXMB06.realtek.com.tw (172.21.6.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 Received: from localhost.localdomain (172.21.68.128) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:09 +0800 From: To: CC: , Subject: [PATCH v2 1/8] rtw88: add legacy firmware download for 8723D devices Date: Wed, 22 Apr 2020 11:46:00 +0800 Message-ID: <20200422034607.28747-2-yhchuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200422034607.28747-1-yhchuang@realtek.com> References: <20200422034607.28747-1-yhchuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.68.128] X-ClientProxiedBy: RTEXMB02.realtek.com.tw (172.21.6.95) To RTEXMB04.realtek.com.tw (172.21.6.97) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ping-Ke Shih The WLAN CPU of 8723D device is different from others, add legacy firmware download function for it. A new variable wlan_cpu is used to decide which firmware download function we should use. Legacy firmware file contains 32 bytes header including version and subversion. When downloading to wlan cpu, header is excluded. Firmware is downloaded via beacon queue to reserved page that is a part of TX buffer. Since 11N WLAN CPU uses different control registers, this patch introduces related control registers. Signed-off-by: Ping-Ke Shih Signed-off-by: Yan-Hsuan Chuang --- drivers/net/wireless/realtek/rtw88/fw.c | 21 ++- drivers/net/wireless/realtek/rtw88/fw.h | 25 +++ drivers/net/wireless/realtek/rtw88/mac.c | 146 +++++++++++++++++- drivers/net/wireless/realtek/rtw88/main.c | 41 ++++- drivers/net/wireless/realtek/rtw88/main.h | 16 ++ drivers/net/wireless/realtek/rtw88/reg.h | 11 ++ drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + 9 files changed, 252 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 245da96dfddc..209853fdcb42 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1079,6 +1079,8 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, u8 bckp[2]; u8 val; u16 rsvd_pg_head; + u32 bcn_valid_addr; + u32 bcn_valid_mask; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -1086,8 +1088,13 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, if (!size) return -EINVAL; - pg_addr &= BIT_MASK_BCN_HEAD_1_V1; - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr | BIT_BCN_VALID_V1); + if (rtw_chip_wcpu_11n(rtwdev)) { + rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); + } else { + pg_addr &= BIT_MASK_BCN_HEAD_1_V1; + pg_addr |= BIT_BCN_VALID_V1; + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr); + } val = rtw_read8(rtwdev, REG_CR + 1); bckp[0] = val; @@ -1105,7 +1112,15 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, goto restore; } - if (!check_hw_ready(rtwdev, REG_FIFOPAGE_CTRL_2, BIT_BCN_VALID_V1, 1)) { + if (rtw_chip_wcpu_11n(rtwdev)) { + bcn_valid_addr = REG_DWBCN0_CTRL; + bcn_valid_mask = BIT_BCN_VALID; + } else { + bcn_valid_addr = REG_FIFOPAGE_CTRL_2; + bcn_valid_mask = BIT_BCN_VALID_V1; + } + + if (!check_hw_ready(rtwdev, bcn_valid_addr, bcn_valid_mask, 1)) { rtw_err(rtwdev, "error beacon valid\n"); ret = -EBUSY; } diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index cdd244857048..2933ef741e53 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -19,6 +19,12 @@ #define RSVD_PAGE_START_ADDR 0x780 #define FIFO_DUMP_ADDR 0x8000 +#define DLFW_PAGE_SIZE_SHIFT_LEGACY 12 +#define DLFW_PAGE_SIZE_LEGACY 0x1000 +#define DLFW_BLK_SIZE_SHIFT_LEGACY 2 +#define DLFW_BLK_SIZE_LEGACY 4 +#define FW_START_ADDR_LEGACY 0x1000 + enum rtw_c2h_cmd_id { C2H_BT_INFO = 0x09, C2H_BT_MP_INFO = 0x0b, @@ -192,6 +198,25 @@ struct rtw_fw_hdr { __le32 imem_addr; } __packed; +struct rtw_fw_hdr_legacy { + __le16 signature; + u8 category; + u8 function; + __le16 version; /* 0x04 */ + u8 subversion1; + u8 subversion2; + u8 month; /* 0x08 */ + u8 day; + u8 hour; + u8 minute; + __le16 size; + __le16 rsvd2; + __le32 idx; /* 0x10 */ + __le32 rsvd3; + __le32 rsvd4; /* 0x18 */ + __le32 rsvd5; +} __packed; + /* C2H */ #define GET_CCX_REPORT_SEQNUM(c2h_payload) (c2h_payload[8] & 0xfc) #define GET_CCX_REPORT_STATUS(c2h_payload) (c2h_payload[9] & 0xc0) diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 7b245779ff90..6092604abfb9 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -650,7 +650,7 @@ static void download_firmware_end_flow(struct rtw_dev *rtwdev) rtw_write16(rtwdev, REG_MCUFW_CTRL, fw_ctrl); } -int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +int __rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { struct rtw_backup_info bckp[DLFW_RESTORE_REG_NUM]; const u8 *data = fw->firmware->data; @@ -704,6 +704,150 @@ int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) return ret; } +static void en_download_firmware_legacy(struct rtw_dev *rtwdev, bool en) +{ + int try; + + if (en) { + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + + for (try = 0; try < 10; try++) { + if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_MCUFWDL_EN) + goto fwdl_ready; + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + msleep(20); + } + rtw_err(rtwdev, "failed to check fw download ready\n"); +fwdl_ready: + rtw_write32_clr(rtwdev, REG_MCUFW_CTRL, BIT_ROM_DLEN); + } else { + rtw_write8_clr(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + } +} + +static void +write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size) +{ + u32 val32; + u32 block_nr; + u32 remain_size; + u32 write_addr = FW_START_ADDR_LEGACY; + const __le32 *ptr = (const __le32 *)data; + u32 block; + __le32 remain_data = 0; + + block_nr = size >> DLFW_BLK_SIZE_SHIFT_LEGACY; + remain_size = size & (DLFW_BLK_SIZE_LEGACY - 1); + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 &= ~BIT_ROM_PGE; + val32 |= (page << BIT_SHIFT_ROM_PGE) & BIT_ROM_PGE; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + for (block = 0; block < block_nr; block++) { + rtw_write32(rtwdev, write_addr, le32_to_cpu(*ptr)); + + write_addr += DLFW_BLK_SIZE_LEGACY; + ptr++; + } + + if (remain_size) { + memcpy(&remain_data, ptr, remain_size); + rtw_write32(rtwdev, write_addr, le32_to_cpu(remain_data)); + } +} + +static int +download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size) +{ + u32 page; + u32 total_page; + u32 last_page_size; + + data += sizeof(struct rtw_fw_hdr_legacy); + size -= sizeof(struct rtw_fw_hdr_legacy); + + total_page = size >> DLFW_PAGE_SIZE_SHIFT_LEGACY; + last_page_size = size & (DLFW_PAGE_SIZE_LEGACY - 1); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT); + + for (page = 0; page < total_page; page++) { + write_firmware_page(rtwdev, page, data, DLFW_PAGE_SIZE_LEGACY); + data += DLFW_PAGE_SIZE_LEGACY; + } + if (last_page_size) + write_firmware_page(rtwdev, page, data, last_page_size); + + if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT, 1)) { + rtw_err(rtwdev, "failed to check download fimrware report\n"); + return -EINVAL; + } + + return 0; +} + +static int download_firmware_validate_legacy(struct rtw_dev *rtwdev) +{ + u32 val32; + int try; + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 |= BIT_MCUFWDL_RDY; + val32 &= ~BIT_WINTINI_RDY; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + for (try = 0; try < 10; try++) { + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + if ((val32 & FW_READY_LEGACY) == FW_READY_LEGACY) + return 0; + msleep(20); + } + + rtw_err(rtwdev, "failed to validate fimrware\n"); + return -EINVAL; +} + +int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + int ret = 0; + + en_download_firmware_legacy(rtwdev, true); + ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size); + en_download_firmware_legacy(rtwdev, false); + if (ret) + goto out; + + ret = download_firmware_validate_legacy(rtwdev); + if (ret) + goto out; + + /* reset desc and index */ + rtw_hci_setup(rtwdev); + + rtwdev->h2c.last_box_num = 0; + rtwdev->h2c.seq = 0; + + set_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + +out: + return ret; +} + +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + return __rtw_download_firmware_legacy(rtwdev, fw); + + return __rtw_download_firmware(rtwdev, fw); +} + static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) { const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn; diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index c851830132d0..b0dadff0dc7b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1042,11 +1042,43 @@ static void rtw_unset_supported_band(struct ieee80211_hw *hw, kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); } +static void __update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + const struct rtw_fw_hdr *fw_hdr = + (const struct rtw_fw_hdr *)fw->firmware->data; + + fw->h2c_version = le16_to_cpu(fw_hdr->h2c_fmt_ver); + fw->version = le16_to_cpu(fw_hdr->version); + fw->sub_version = fw_hdr->subversion; + fw->sub_index = fw_hdr->subindex; +} + +static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + struct rtw_fw_hdr_legacy *legacy = + (struct rtw_fw_hdr_legacy *)fw->firmware->data; + + fw->h2c_version = 0; + fw->version = le16_to_cpu(legacy->version); + fw->sub_version = legacy->subversion1; + fw->sub_index = legacy->subversion2; +} + +static void update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + __update_firmware_info_legacy(rtwdev, fw); + else + __update_firmware_info(rtwdev, fw); +} + static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) { struct rtw_fw_state *fw = context; struct rtw_dev *rtwdev = fw->rtwdev; - const struct rtw_fw_hdr *fw_hdr; if (!firmware || !firmware->data) { rtw_err(rtwdev, "failed to request firmware\n"); @@ -1054,13 +1086,8 @@ static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) return; } - fw_hdr = (const struct rtw_fw_hdr *)firmware->data; - fw->h2c_version = le16_to_cpu(fw_hdr->h2c_fmt_ver); - fw->version = le16_to_cpu(fw_hdr->version); - fw->sub_version = fw_hdr->subversion; - fw->sub_index = fw_hdr->subindex; - fw->firmware = firmware; + update_firmware_info(rtwdev, fw); complete_all(&fw->completion); rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n", diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 74302181da53..380a670eeeee 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1056,12 +1056,18 @@ struct rtw_pwr_track_tbl { const u8 *pwrtrk_2g_ccka_p; }; +enum rtw_wlan_cpu { + RTW_WCPU_11AC, + RTW_WCPU_11N, +}; + /* hardware configuration for each IC */ struct rtw_chip_info { struct rtw_chip_ops *ops; u8 id; const char *fw_name; + enum rtw_wlan_cpu wlan_cpu; u8 tx_pkt_desc_sz; u8 tx_buf_desc_sz; u8 rx_pkt_desc_sz; @@ -1725,6 +1731,16 @@ static inline void rtw_chip_efuse_grant_off(struct rtw_dev *rtwdev) rtwdev->chip->ops->efuse_grant(rtwdev, false); } +static inline bool rtw_chip_wcpu_11n(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_11N; +} + +static inline bool rtw_chip_wcpu_11ac(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_11AC; +} + void rtw_get_channel_params(struct cfg80211_chan_def *chandef, struct rtw_channel_params *ch_param); bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target); diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index 911d8e75db77..89868ac0748f 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -77,19 +77,28 @@ #define BIT_ANA_PORT_EN BIT(22) #define BIT_MAC_PORT_EN BIT(21) #define BIT_BOOT_FSPI_EN BIT(20) +#define BIT_ROM_DLEN BIT(19) +#define BIT_ROM_PGE GENMASK(18, 16) /* legacy only */ +#define BIT_SHIFT_ROM_PGE 16 #define BIT_FW_INIT_RDY BIT(15) #define BIT_FW_DW_RDY BIT(14) #define BIT_RPWM_TOGGLE BIT(7) +#define BIT_RAM_DL_SEL BIT(7) /* legacy only */ #define BIT_DMEM_CHKSUM_OK BIT(6) +#define BIT_WINTINI_RDY BIT(6) /* legacy only */ #define BIT_DMEM_DW_OK BIT(5) #define BIT_IMEM_CHKSUM_OK BIT(4) #define BIT_IMEM_DW_OK BIT(3) #define BIT_IMEM_BOOT_LOAD_CHECKSUM_OK BIT(2) +#define BIT_FWDL_CHK_RPT BIT(2) /* legacy only */ +#define BIT_MCUFWDL_RDY BIT(1) /* legacy only */ #define BIT_MCUFWDL_EN BIT(0) #define BIT_CHECK_SUM_OK (BIT(4) | BIT(6)) #define FW_READY (BIT_FW_INIT_RDY | BIT_FW_DW_RDY | \ BIT_IMEM_DW_OK | BIT_DMEM_DW_OK | \ BIT_CHECK_SUM_OK) +#define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ + BIT_WINTINI_RDY | BIT_RAM_DL_SEL) #define FW_READY_MASK 0xffff #define REG_EFUSE_ACCESS 0x00CF @@ -197,6 +206,8 @@ #define BIT_MASK_BCN_HEAD_1_V1 0xfff #define REG_AUTO_LLT_V1 0x0208 #define BIT_AUTO_INIT_LLT_V1 BIT(0) +#define REG_DWBCN0_CTRL 0x0208 +#define BIT_BCN_VALID BIT(16) #define REG_TXDMA_OFFSET_CHK 0x020C #define REG_TXDMA_STATUS 0x0210 #define BTI_PAGE_OVF BIT(2) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index c25cabbab64d..5e8e0dd6456e 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -511,6 +511,7 @@ struct rtw_chip_info rtw8723d_hw_spec = { .ops = &rtw8723d_ops, .id = RTW_CHIP_TYPE_8723D, .fw_name = "rtw88/rtw8723d_fw.bin", + .wlan_cpu = RTW_WCPU_11N, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c index 9a2e18e7624f..ffee8111d145 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -2408,6 +2408,7 @@ struct rtw_chip_info rtw8822b_hw_spec = { .ops = &rtw8822b_ops, .id = RTW_CHIP_TYPE_8822B, .fw_name = "rtw88/rtw8822b_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index ee0d39135617..8dd92136145d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -4269,6 +4269,7 @@ struct rtw_chip_info rtw8822c_hw_spec = { .ops = &rtw8822c_ops, .id = RTW_CHIP_TYPE_8822C, .fw_name = "rtw88/rtw8822c_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, From patchwork Wed Apr 22 03:46:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Chuang X-Patchwork-Id: 215901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B67ECC55181 for ; Wed, 22 Apr 2020 03:46:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E9CB20747 for ; Wed, 22 Apr 2020 03:46:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726477AbgDVDqT (ORCPT ); Tue, 21 Apr 2020 23:46:19 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:37004 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726466AbgDVDqS (ORCPT ); Tue, 21 Apr 2020 23:46:18 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.69 with qID 03M3kAzF5004569, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb06.realtek.com.tw[172.21.6.99]) by rtits2.realtek.com.tw (8.15.2/2.66/5.86) with ESMTPS id 03M3kAzF5004569 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Apr 2020 11:46:10 +0800 Received: from RTEXMB04.realtek.com.tw (172.21.6.97) by RTEXMB06.realtek.com.tw (172.21.6.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 Received: from localhost.localdomain (172.21.68.128) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 From: To: CC: , Subject: [PATCH v2 4/8] rtw88: decompose while(1) loop of power sequence polling command Date: Wed, 22 Apr 2020 11:46:03 +0800 Message-ID: <20200422034607.28747-5-yhchuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200422034607.28747-1-yhchuang@realtek.com> References: <20200422034607.28747-1-yhchuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.68.128] X-ClientProxiedBy: RTEXMB02.realtek.com.tw (172.21.6.95) To RTEXMB04.realtek.com.tw (172.21.6.97) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ping-Ke Shih The power polling command is one kind of power sequence commands. It's used to check hardware situation, and subsequent comamnds will be executed if hardware is ready. A special case is PCIE must toggle BIT_PFM_WOWL and try again if first try is failed. In order to reduce indentation to understand the code easier, move polling part to a separate function. Then, the 'while (1)...loop' is replaced by two statements to do first try and retry. Signed-off-by: Ping-Ke Shih Signed-off-by: Yan-Hsuan Chuang --- drivers/net/wireless/realtek/rtw88/mac.c | 72 +++++++++++++----------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 21b5c7173f0f..ac5d35153c8a 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -108,51 +108,55 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) return 0; } +static bool do_pwr_poll_cmd(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target) +{ + u32 cnt; + + target &= mask; + + for (cnt = 0; cnt < RTW_PWR_POLLING_CNT; cnt++) { + if ((rtw_read8(rtwdev, addr) & mask) == target) + return true; + + udelay(50); + } + + return false; +} + static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev, const struct rtw_pwr_seq_cmd *cmd) { u8 value; - u8 flag = 0; u32 offset; - u32 cnt = RTW_PWR_POLLING_CNT; if (cmd->base == RTW_PWR_ADDR_SDIO) offset = cmd->offset | SDIO_LOCAL_OFFSET; else offset = cmd->offset; - do { - cnt--; - value = rtw_read8(rtwdev, offset); - value &= cmd->mask; - if (value == (cmd->value & cmd->mask)) - return 0; - if (cnt == 0) { - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && - flag == 0) { - value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); - if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) { - value &= ~BIT_PFM_WOWL; - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - } - value |= BIT_PFM_WOWL; - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - value &= ~BIT_PFM_WOWL; - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) { - value |= BIT_PFM_WOWL; - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - } - - cnt = RTW_PWR_POLLING_CNT; - flag = 1; - } else { - return -EBUSY; - } - } else { - udelay(50); - } - } while (1); + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + + if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_PCIE) + goto err; + + /* if PCIE, toggle BIT_PFM_WOWL and try again */ + value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + +err: + rtw_err(rtwdev, "failed to poll offset=0x%x mask=0x%x value=0x%x\n", + offset, cmd->mask, cmd->value); + return -EBUSY; } static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, From patchwork Wed Apr 22 03:46:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Chuang X-Patchwork-Id: 215902 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C187C54FCB for ; Wed, 22 Apr 2020 03:46:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4506B20747 for ; Wed, 22 Apr 2020 03:46:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726475AbgDVDqT (ORCPT ); Tue, 21 Apr 2020 23:46:19 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:37002 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726465AbgDVDqS (ORCPT ); Tue, 21 Apr 2020 23:46:18 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.69 with qID 03M3kBzA5004569, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb06.realtek.com.tw[172.21.6.99]) by rtits2.realtek.com.tw (8.15.2/2.66/5.86) with ESMTPS id 03M3kBzA5004569 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Apr 2020 11:46:11 +0800 Received: from RTEXMB04.realtek.com.tw (172.21.6.97) by RTEXMB06.realtek.com.tw (172.21.6.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 Received: from localhost.localdomain (172.21.68.128) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 From: To: CC: , Subject: [PATCH v2 5/8] rtw88: 8723d: 11N chips don't support H2C queue Date: Wed, 22 Apr 2020 11:46:04 +0800 Message-ID: <20200422034607.28747-6-yhchuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200422034607.28747-1-yhchuang@realtek.com> References: <20200422034607.28747-1-yhchuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.68.128] X-ClientProxiedBy: RTEXMB02.realtek.com.tw (172.21.6.95) To RTEXMB04.realtek.com.tw (172.21.6.97) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ping-Ke Shih H2C queue is used to send command to firmware. Since 8723D doesn't support this queue, this commit check wlan_cpu flag to avoid to set H2C related registers. Signed-off-by: Ping-Ke Shih Signed-off-by: Yan-Hsuan Chuang --- drivers/net/wireless/realtek/rtw88/mac.c | 6 +++- drivers/net/wireless/realtek/rtw88/pci.c | 35 ++++++++++++++++-------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index ac5d35153c8a..f4a504b350cf 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -1016,7 +1016,8 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev) rtw_write8(rtwdev, REG_CR, 0); rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE); - rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); return 0; } @@ -1135,6 +1136,9 @@ static int init_h2c(struct rtw_dev *rtwdev) u32 h2cq_free; u32 wp, rp; + if (rtw_chip_wcpu_11n(rtwdev)) + return 0; + h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT; h2cq_size = RSVD_PG_H2CQ_NUM << TX_PAGE_SIZE_SHIFT; diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index b3e76b579af9..8a8d746d3349 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -411,12 +411,14 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma; rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma); - len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; - dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; - rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; - rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.wp = 0; - rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_H2CQ, len & TRX_BD_IDX_MASK); - rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_H2CQ, dma); + if (!rtw_chip_wcpu_11n(rtwdev)) { + len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_H2CQ, len & TRX_BD_IDX_MASK); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_H2CQ, dma); + } len = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.len; dma = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.dma; @@ -471,8 +473,9 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff); /* reset H2C Queue index in a single write */ - rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, - BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, + BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); } static void rtw_pci_reset_trx_ring(struct rtw_dev *rtwdev) @@ -489,7 +492,9 @@ static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev, rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0]); rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]); - rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); + rtwpci->irq_enabled = true; spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); @@ -507,7 +512,9 @@ static void rtw_pci_disable_interrupt(struct rtw_dev *rtwdev, rtw_write32(rtwdev, RTK_PCI_HIMR0, 0); rtw_write32(rtwdev, RTK_PCI_HIMR1, 0); - rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); + rtwpci->irq_enabled = false; out: @@ -1012,13 +1019,17 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev, irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0); irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1); - irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); + if (rtw_chip_wcpu_11ac(rtwdev)) + irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); + else + irq_status[3] = 0; irq_status[0] &= rtwpci->irq_mask[0]; irq_status[1] &= rtwpci->irq_mask[1]; irq_status[3] &= rtwpci->irq_mask[3]; rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]); rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]); - rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); } From patchwork Wed Apr 22 03:46:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Chuang X-Patchwork-Id: 215898 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45380C55181 for ; Wed, 22 Apr 2020 03:46:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2517F20747 for ; Wed, 22 Apr 2020 03:46:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726493AbgDVDqZ (ORCPT ); Tue, 21 Apr 2020 23:46:25 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:37001 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726463AbgDVDqS (ORCPT ); Tue, 21 Apr 2020 23:46:18 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.69 with qID 03M3kBPA1004597, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb06.realtek.com.tw[172.21.6.99]) by rtits2.realtek.com.tw (8.15.2/2.66/5.86) with ESMTPS id 03M3kBPA1004597 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Apr 2020 11:46:11 +0800 Received: from RTEXMB04.realtek.com.tw (172.21.6.97) by RTEXMB06.realtek.com.tw (172.21.6.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:11 +0800 Received: from localhost.localdomain (172.21.68.128) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1779.2; Wed, 22 Apr 2020 11:46:10 +0800 From: To: CC: , Subject: [PATCH v2 8/8] rtw88: 8723d: initialize mac/bb/rf basic functions Date: Wed, 22 Apr 2020 11:46:07 +0800 Message-ID: <20200422034607.28747-9-yhchuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200422034607.28747-1-yhchuang@realtek.com> References: <20200422034607.28747-1-yhchuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.68.128] X-ClientProxiedBy: RTEXMB02.realtek.com.tw (172.21.6.95) To RTEXMB04.realtek.com.tw (172.21.6.97) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ping-Ke Shih Implement rtw_chip_ops::phy_set_param and ::mac_init to initialize mac/bb/rf, and they are used during interface up. The procedure contains power on sequence registers, download firmware, load predefined parameters, mac/bb/rf specific register and etc. Signed-off-by: Ping-Ke Shih Signed-off-by: Yan-Hsuan Chuang --- drivers/net/wireless/realtek/rtw88/main.h | 1 + drivers/net/wireless/realtek/rtw88/reg.h | 34 +++++ drivers/net/wireless/realtek/rtw88/rtw8723d.c | 124 ++++++++++++++++++ drivers/net/wireless/realtek/rtw88/rtw8723d.h | 3 + 4 files changed, 162 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 380a670eeeee..157aca641f6d 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1475,6 +1475,7 @@ struct rtw_efuse { u8 ant_div_cfg; u8 ant_div_type; u8 regd; + u8 afe; u8 lna_type_2g; u8 lna_type_5g; diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index 00eb6b6a1f5b..9fdfcdc5c5cf 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -6,6 +6,7 @@ #define __RTW_REG_DEF_H__ #define REG_SYS_FUNC_EN 0x0002 +#define BIT_FEN_EN_25_1 BIT(13) #define BIT_FEN_ELDR BIT(12) #define BIT_FEN_CPUEN BIT(2) #define BIT_FEN_BB_GLB_RST BIT(1) @@ -40,6 +41,11 @@ #define BIT_MASK_EF_ADDR 0x3ff #define BIT_MASK_EF_DATA 0xff #define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR) +#define BITS_PLL 0xf0 + +#define REG_AFE_CTRL3 0x2c +#define BIT_MASK_XTAL 0x00FFF000 +#define BIT_XTAL_GMP_BIT4 BIT(28) #define REG_LDO_EFUSE_CTRL 0x0034 #define BIT_MASK_EFUSE_BANK_SEL (BIT(8) | BIT(9)) @@ -61,6 +67,7 @@ #define BIT_PAPE_SEL_EN BIT(25) #define BIT_DPDT_WL_SEL BIT(24) #define BIT_DPDT_SEL_EN BIT(23) +#define REG_LEDCFG2 0x004E #define REG_PAD_CTRL1 0x0064 #define BIT_PAPE_WLBT_SEL BIT(29) #define BIT_LNAON_WLBT_SEL BIT(28) @@ -76,9 +83,15 @@ #define BIT_LTE_MUX_CTRL_PATH BIT(26) #define REG_HCI_OPT_CTRL 0x0074 +#define REG_AFE_CTRL_4 0x0078 +#define BIT_CK320M_AFE_EN BIT(4) +#define BIT_EN_SYN BIT(15) + #define REG_LDO_SWR_CTRL 0x007C #define LDO_SEL 0xC3 #define SPS_SEL 0x83 +#define BIT_XTA1 BIT(29) +#define BIT_XTA0 BIT(28) #define REG_MCUFW_CTRL 0x0080 #define BIT_ANA_PORT_EN BIT(22) @@ -197,6 +210,7 @@ #define BIT_FS_RXDONE BIT(16) #define REG_PKTBUF_DBG_CTRL 0x0140 #define REG_C2HEVT 0x01A0 +#define REG_MCUTST_1 0x01C0 #define REG_MCUTST_II 0x01C4 #define REG_WOWLAN_WAKE_REASON 0x01C7 #define REG_HMETFR 0x01CC @@ -230,6 +244,7 @@ #define REG_DWBCN0_CTRL 0x0208 #define BIT_BCN_VALID BIT(16) #define REG_TXDMA_OFFSET_CHK 0x020C +#define BIT_DROP_DATA_EN BIT(9) #define REG_TXDMA_STATUS 0x0210 #define BTI_PAGE_OVF BIT(2) @@ -291,6 +306,7 @@ #define BIT_CHECK_CCK_EN BIT(7) #define REG_AMPDU_MAX_TIME_V1 0x0455 #define REG_BCNQ1_BDNY_V1 0x0456 +#define REG_AMPDU_MAX_TIME 0x0456 #define REG_WMAC_LBK_BF_HD 0x045D #define REG_TX_HANG_CTRL 0x045E #define BIT_EN_GNT_BT_AWAKE BIT(3) @@ -306,7 +322,10 @@ #define REG_QUEUE_CTRL 0x04C6 #define BIT_PTA_WL_TX_EN BIT(4) #define BIT_PTA_EDCCA_EN BIT(5) +#define REG_SINGLE_AMPDU_CTRL 0x04C7 +#define BIT_EN_SINGLE_APMDU BIT(7) #define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA #define REG_BAR_MODE_CTRL 0x04CC #define REG_PRECNT_CTRL 0x04E5 #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) @@ -326,6 +345,7 @@ #define BIT_SHIFT_SIFS_OFDM_CTX 8 #define BIT_SHIFT_SIFS_CCK_TRX 16 #define BIT_SHIFT_SIFS_OFDM_TRX 24 +#define REG_AGGR_BREAK_TIME 0x051A #define REG_SLOT 0x051B #define REG_TX_PTCL_CTRL 0x0520 #define BIT_SIFS_BK_EN BIT(12) @@ -337,18 +357,23 @@ #define REG_TBTT_PROHIBIT 0x0540 #define BIT_SHIFT_TBTT_HOLD_TIME_AP 8 #define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 #define REG_BCN_CTRL 0x0550 #define BIT_DIS_TSF_UDT BIT(4) #define BIT_EN_BCN_FUNCTION BIT(3) +#define BIT_EN_TXBCN_RPT BIT(2) #define REG_BCN_CTRL_CLINT0 0x0551 #define REG_DRVERLYINT 0x0558 #define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A #define REG_USTIME_TSF 0x055C #define REG_BCN_MAX_ERR 0x055D #define REG_RXTSF_OFFSET_CCK 0x055E #define REG_MISC_CTRL 0x0577 #define BIT_EN_FREE_CNT BIT(3) #define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1)) +#define REG_HIQ_NO_LMT_EN 0x5A7 +#define BIT_HIQ_NO_LMT_EN_ROOT BIT(0) #define REG_TIMER0_SRC_SEL 0x05B4 #define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) @@ -374,6 +399,7 @@ #define BIT_HTC_LOC_CTRL BIT(14) #define BIT_RPFM_CAM_ENABLE BIT(12) #define BIT_TA_BCN BIT(11) +#define BIT_RCR_ADF BIT(11) #define BIT_DISDECMYPKT BIT(10) #define BIT_AICV BIT(9) #define BIT_ACRC32 BIT(8) @@ -391,6 +417,7 @@ #define REG_MAR 0x0620 #define REG_USTIME_EDCA 0x0638 #define REG_ACKTO_CCK 0x0639 +#define REG_MAC_SPEC_SIFS 0x063A #define REG_RESP_SIFS_CCK 0x063C #define REG_RESP_SIFS_OFDM 0x063E #define REG_ACKTO 0x0640 @@ -433,12 +460,19 @@ #define BIT_LTE_COEX_EN BIT(7) #define REG_BT_STAT_CTRL 0x0778 #define REG_BT_TDMA_TIME 0x0790 +#define REG_LTR_IDLE_LATENCY 0x0798 +#define REG_LTR_ACTIVE_LATENCY 0x079C +#define REG_LTR_CTRL_BASIC 0x07A4 #define REG_WMAC_OPTION_FUNCTION 0x07D0 #define REG_WMAC_OPTION_FUNCTION_1 0x07D4 +#define REG_FPGA0_RFMOD 0x0800 +#define BIT_CCKEN BIT(24) +#define BIT_OFDMEN BIT(25) #define REG_RX_GAIN_EN 0x081c #define REG_RFE_CTRL_E 0x0974 +#define REG_2ND_CCA_CTRL 0x0976 #define REG_DIS_DPD 0x0a70 #define DIS_DPD_MASK GENMASK(9, 0) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index c03ed91349e5..8ca4d5794434 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -37,6 +37,98 @@ static const struct rtw_hw_reg rtw8723d_txagc[] = { [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, }; +#define WLAN_TXQ_RPT_EN 0x1F +#define WLAN_SLOT_TIME 0x09 +#define WLAN_RL_VAL 0x3030 +#define WLAN_BAR_VAL 0x0201ffff +#define BIT_MASK_TBTT_HOLD 0x00000fff +#define BIT_SHIFT_TBTT_HOLD 8 +#define BIT_MASK_TBTT_SETUP 0x000000ff +#define BIT_SHIFT_TBTT_SETUP 0 +#define BIT_MASK_TBTT_MASK ((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \ + (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP)) +#define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\ + (((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD)) +#define WLAN_TBTT_TIME_NORMAL TBTT_TIME(0x04, 0x80) +#define WLAN_TBTT_TIME_STOP_BCN TBTT_TIME(0x04, 0x64) +#define WLAN_PIFS_VAL 0 +#define WLAN_AGG_BRK_TIME 0x16 +#define WLAN_NAV_PROT_LEN 0x0040 +#define WLAN_SPEC_SIFS 0x100a +#define WLAN_RX_PKT_LIMIT 0x17 +#define WLAN_MAX_AGG_NR 0x0A +#define WLAN_AMPDU_MAX_TIME 0x1C +#define WLAN_ANT_SEL 0x82 +#define WLAN_LTR_IDLE_LAT 0x883C883C +#define WLAN_LTR_ACT_LAT 0x880B880B +#define WLAN_LTR_CTRL1 0xCB004010 +#define WLAN_LTR_CTRL2 0x01233425 + +static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +{ + u8 xtal_cap; + u32 val32; + + /* power on BB/RF domain */ + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); + + rtw_phy_load_tables(rtwdev); + + /* post init after header files config */ + rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); + rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT); + rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); + + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); + if ((rtwdev->efuse.afe >> 4) == 14) { + rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4); + rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL); + rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1); + rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0); + } + + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); + rtw_write8(rtwdev, REG_ATIMWND, 0x2); + rtw_write8(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); + val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT); + val32 &= ~BIT_MASK_TBTT_MASK; + val32 |= WLAN_TBTT_TIME_STOP_BCN; + rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val32); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); + rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME); + rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); + rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); + rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL); + + rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT); + rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2); + + rtw_phy_init(rtwdev); + + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); +} + static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, struct rtw8723d_efuse *map) { @@ -63,6 +155,7 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) efuse->regd = map->rf_board_option & 0x7; efuse->thermal_meter[0] = map->thermal_meter; efuse->thermal_meter_k = map->thermal_meter; + efuse->afe = map->afe; for (i = 0; i < 4; i++) efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; @@ -79,6 +172,35 @@ static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) return 0; } +#define BIT_CFENDFORM BIT(9) +#define BIT_WMAC_TCR_ERR0 BIT(12) +#define BIT_WMAC_TCR_ERR1 BIT(13) +#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ + BIT_WMAC_TCR_ERR1) +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0x400 +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0x700060CE + +static int rtw8723d_mac_init(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); + + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + + rtw_write32(rtwdev, REG_INT_MIG, 0); + rtw_write32(rtwdev, REG_MCUTST_1, 0x0); + + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); + rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); + + return 0; +} + static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { u8 ldo_pwr; @@ -143,7 +265,9 @@ static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on) } static struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, .read_efuse = rtw8723d_read_efuse, + .mac_init = rtw8723d_mac_init, .read_rf = rtw_phy_read_rf_sipi, .write_rf = rtw_phy_write_rf_reg_sipi, .set_tx_power_index = rtw8723d_set_tx_power_index, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h index 1939d9897a26..6321dea83519 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h @@ -44,4 +44,7 @@ struct rtw8723d_efuse { struct rtw8723de_efuse e; }; +#define REG_OFDM0_XAAGC1 0x0c50 +#define REG_OFDM0_XBAGC1 0x0c58 + #endif