diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-03 16:27:18 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-03 16:27:18 -0700 |
| commit | cb8e59cc87201af93dfbb6c3dccc8fcad72a09c2 (patch) | |
| tree | a334db9022f89654b777bbce8c4c6632e65b9031 /drivers/net/wireless/realtek/rtw88/mac.c | |
| parent | 2e63f6ce7ed2c4ff83ba30ad9ccad422289a6c63 (diff) | |
| parent | 065fcfd49763ec71ae345bb5c5a74f961031e70e (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from David Miller:
1) Allow setting bluetooth L2CAP modes via socket option, from Luiz
Augusto von Dentz.
2) Add GSO partial support to igc, from Sasha Neftin.
3) Several cleanups and improvements to r8169 from Heiner Kallweit.
4) Add IF_OPER_TESTING link state and use it when ethtool triggers a
device self-test. From Andrew Lunn.
5) Start moving away from custom driver versions, use the globally
defined kernel version instead, from Leon Romanovsky.
6) Support GRO vis gro_cells in DSA layer, from Alexander Lobakin.
7) Allow hard IRQ deferral during NAPI, from Eric Dumazet.
8) Add sriov and vf support to hinic, from Luo bin.
9) Support Media Redundancy Protocol (MRP) in the bridging code, from
Horatiu Vultur.
10) Support netmap in the nft_nat code, from Pablo Neira Ayuso.
11) Allow UDPv6 encapsulation of ESP in the ipsec code, from Sabrina
Dubroca. Also add ipv6 support for espintcp.
12) Lots of ReST conversions of the networking documentation, from Mauro
Carvalho Chehab.
13) Support configuration of ethtool rxnfc flows in bcmgenet driver,
from Doug Berger.
14) Allow to dump cgroup id and filter by it in inet_diag code, from
Dmitry Yakunin.
15) Add infrastructure to export netlink attribute policies to
userspace, from Johannes Berg.
16) Several optimizations to sch_fq scheduler, from Eric Dumazet.
17) Fallback to the default qdisc if qdisc init fails because otherwise
a packet scheduler init failure will make a device inoperative. From
Jesper Dangaard Brouer.
18) Several RISCV bpf jit optimizations, from Luke Nelson.
19) Correct the return type of the ->ndo_start_xmit() method in several
drivers, it's netdev_tx_t but many drivers were using
'int'. From Yunjian Wang.
20) Add an ethtool interface for PHY master/slave config, from Oleksij
Rempel.
21) Add BPF iterators, from Yonghang Song.
22) Add cable test infrastructure, including ethool interfaces, from
Andrew Lunn. Marvell PHY driver is the first to support this
facility.
23) Remove zero-length arrays all over, from Gustavo A. R. Silva.
24) Calculate and maintain an explicit frame size in XDP, from Jesper
Dangaard Brouer.
25) Add CAP_BPF, from Alexei Starovoitov.
26) Support terse dumps in the packet scheduler, from Vlad Buslov.
27) Support XDP_TX bulking in dpaa2 driver, from Ioana Ciornei.
28) Add devm_register_netdev(), from Bartosz Golaszewski.
29) Minimize qdisc resets, from Cong Wang.
30) Get rid of kernel_getsockopt and kernel_setsockopt in order to
eliminate set_fs/get_fs calls. From Christoph Hellwig.
* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2517 commits)
selftests: net: ip_defrag: ignore EPERM
net_failover: fixed rollback in net_failover_open()
Revert "tipc: Fix potential tipc_aead refcnt leak in tipc_crypto_rcv"
Revert "tipc: Fix potential tipc_node refcnt leak in tipc_rcv"
vmxnet3: allow rx flow hash ops only when rss is enabled
hinic: add set_channels ethtool_ops support
selftests/bpf: Add a default $(CXX) value
tools/bpf: Don't use $(COMPILE.c)
bpf, selftests: Use bpf_probe_read_kernel
s390/bpf: Use bcr 0,%0 as tail call nop filler
s390/bpf: Maintain 8-byte stack alignment
selftests/bpf: Fix verifier test
selftests/bpf: Fix sample_cnt shared between two threads
bpf, selftests: Adapt cls_redirect to call csum_level helper
bpf: Add csum_level helper for fixing up csum levels
bpf: Fix up bpf_skb_adjust_room helper's skb csum setting
sfc: add missing annotation for efx_ef10_try_update_nic_stats_vf()
crypto/chtls: IPv6 support for inline TLS
Crypto/chcr: Fixes a coccinile check error
Crypto/chcr: Fixes compilations warnings
...
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/mac.c')
| -rw-r--r-- | drivers/net/wireless/realtek/rtw88/mac.c | 437 |
1 files changed, 339 insertions, 98 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 7b245779ff90..19b9b7ab016b 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -40,6 +40,9 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, } rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32); + if (rtw_chip_wcpu_11n(rtwdev)) + return; + value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL); value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL); rtw_write32(rtwdev, REG_AFE_CTRL1, value32); @@ -53,6 +56,7 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, value8 |= BIT_CHECK_CCK_EN; rtw_write8(rtwdev, REG_CCK_CHECK, value8); } +EXPORT_SYMBOL(rtw_set_channel_mac); static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) { @@ -61,6 +65,14 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) rtw_write8(rtwdev, REG_RSV_CTRL, 0); + if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO) + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL); + else + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, SPS_SEL); + return 0; + } + switch (rtw_hci_type(rtwdev)) { case RTW_HCI_TYPE_PCIE: rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN); @@ -100,42 +112,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); - value |= BIT(3); - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - value &= ~BIT(3); - 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, @@ -228,12 +253,14 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) u8 rpwm; bool cur_pwr; - rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + if (rtw_chip_wcpu_11ac(rtwdev)) { + rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); - /* Check FW still exist or not */ - if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) { - rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE; - rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm); + /* Check FW still exist or not */ + if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) { + rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE; + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm); + } } if (rtw_read8(rtwdev, REG_CR) == 0xea) @@ -244,7 +271,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) else cur_pwr = true; - if (pwr_on && cur_pwr) + if (pwr_on == cur_pwr) return -EALREADY; pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; @@ -254,7 +281,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) return 0; } -static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) { u8 sys_func_en = rtwdev->chip->sys_func_en; u8 value8; @@ -279,6 +306,29 @@ static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) return 0; } +static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_CR, 0xff); + mdelay(2); + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0x7f); + mdelay(2); + + rtw_write8_set(rtwdev, REG_SYS_CLKR, BIT_WAKEPAD_EN); + rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); + + rtw_write16(rtwdev, REG_CR, 0x2ff); + + return 0; +} + +static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + return __rtw_mac_init_system_cfg_legacy(rtwdev); + + return __rtw_mac_init_system_cfg(rtwdev); +} + int rtw_mac_power_on(struct rtw_dev *rtwdev) { int ret = 0; @@ -650,7 +700,8 @@ 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) +static 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 +755,151 @@ dlfw_fail: 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 firmware 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 firmware\n"); + return -EINVAL; +} + +static 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; @@ -724,31 +920,24 @@ static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) static void __rtw_mac_flush_prio_queue(struct rtw_dev *rtwdev, u32 prio_queue, bool drop) { - u32 addr; + struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_prioq_addr *addr; + bool wsize; u16 avail_page, rsvd_page; int i; - switch (prio_queue) { - case RTW_DMA_MAPPING_EXTRA: - addr = REG_FIFOPAGE_INFO_4; - break; - case RTW_DMA_MAPPING_LOW: - addr = REG_FIFOPAGE_INFO_2; - break; - case RTW_DMA_MAPPING_NORMAL: - addr = REG_FIFOPAGE_INFO_3; - break; - case RTW_DMA_MAPPING_HIGH: - addr = REG_FIFOPAGE_INFO_1; - break; - default: + if (prio_queue >= RTW_DMA_MAPPING_MAX) return; - } + + addr = &chip->prioq_addrs->prio[prio_queue]; + wsize = chip->prioq_addrs->wsize; /* check if all of the reserved pages are available for 100 msecs */ for (i = 0; i < 5; i++) { - rsvd_page = rtw_read16(rtwdev, addr); - avail_page = rtw_read16(rtwdev, addr + 2); + rsvd_page = wsize ? rtw_read16(rtwdev, addr->rsvd) : + rtw_read8(rtwdev, addr->rsvd); + avail_page = wsize ? rtw_read16(rtwdev, addr->avail) : + rtw_read8(rtwdev, addr->avail); if (rsvd_page == avail_page) return; @@ -826,7 +1015,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; } @@ -841,13 +1031,16 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev) /* config rsvd page num */ fifo->rsvd_drv_pg_num = 8; fifo->txff_pg_num = chip->txff_size >> 7; - fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + - RSVD_PG_H2C_EXTRAINFO_NUM + - RSVD_PG_H2C_STATICINFO_NUM + - RSVD_PG_H2CQ_NUM + - RSVD_PG_CPU_INSTRUCTION_NUM + - RSVD_PG_FW_TXBUF_NUM + - csi_buf_pg_num; + if (rtw_chip_wcpu_11n(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + + RSVD_PG_H2C_EXTRAINFO_NUM + + RSVD_PG_H2C_STATICINFO_NUM + + RSVD_PG_H2CQ_NUM + + RSVD_PG_CPU_INSTRUCTION_NUM + + RSVD_PG_FW_TXBUF_NUM + + csi_buf_pg_num; if (fifo->rsvd_pg_num > fifo->txff_pg_num) return -ENOMEM; @@ -856,18 +1049,20 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev) fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num; cur_pg_addr = fifo->txff_pg_num; - cur_pg_addr -= csi_buf_pg_num; - fifo->rsvd_csibuf_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; - fifo->rsvd_fw_txbuf_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM; - fifo->rsvd_cpu_instr_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2CQ_NUM; - fifo->rsvd_h2cq_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM; - fifo->rsvd_h2c_sta_info_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM; - fifo->rsvd_h2c_info_addr = cur_pg_addr; + if (rtw_chip_wcpu_11ac(rtwdev)) { + cur_pg_addr -= csi_buf_pg_num; + fifo->rsvd_csibuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; + fifo->rsvd_fw_txbuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM; + fifo->rsvd_cpu_instr_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2CQ_NUM; + fifo->rsvd_h2cq_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM; + fifo->rsvd_h2c_sta_info_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM; + fifo->rsvd_h2c_info_addr = cur_pg_addr; + } cur_pg_addr -= fifo->rsvd_drv_pg_num; fifo->rsvd_drv_addr = cur_pg_addr; @@ -879,6 +1074,65 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev) return 0; } +static int __priority_queue_cfg(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, + u16 pubq_num) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + struct rtw_chip_info *chip = rtwdev->chip; + + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, pg_tbl->hq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_2, pg_tbl->lq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_3, pg_tbl->nq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_4, pg_tbl->exq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_5, pubq_num); + rtw_write32_set(rtwdev, REG_RQPN_CTRL_2, BIT_LD_RQPN); + + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, fifo->rsvd_boundary); + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL + 2, BIT_EN_WR_FREE_TAIL >> 16); + + rtw_write16(rtwdev, REG_BCNQ_BDNY_V1, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); + rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); + rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) + return -EBUSY; + + rtw_write8(rtwdev, REG_CR + 3, 0); + + return 0; +} + +static int __priority_queue_cfg_legacy(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, + u16 pubq_num) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + struct rtw_chip_info *chip = rtwdev->chip; + u32 val32; + + val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); + rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); + rtw_write32(rtwdev, REG_RQPN, val32); + + rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, chip->rxff_size - REPORT_BUF - 1); + rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); + + rtw_write32_set(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT, 0)) + return -EBUSY; + + return 0; +} + static int priority_queue_cfg(struct rtw_dev *rtwdev) { struct rtw_fifo_conf *fifo = &rtwdev->fifo; @@ -911,28 +1165,10 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev) pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, pg_tbl->hq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_2, pg_tbl->lq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_3, pg_tbl->nq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_4, pg_tbl->exq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_5, pubq_num); - rtw_write32_set(rtwdev, REG_RQPN_CTRL_2, BIT_LD_RQPN); - - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, fifo->rsvd_boundary); - rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL + 2, BIT_EN_WR_FREE_TAIL >> 16); - - rtw_write16(rtwdev, REG_BCNQ_BDNY_V1, fifo->rsvd_boundary); - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); - rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); - rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); - rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); - - if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) - return -EBUSY; - - rtw_write8(rtwdev, REG_CR + 3, 0); - - return 0; + if (rtw_chip_wcpu_11n(rtwdev)) + return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num); + else + return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num); } static int init_h2c(struct rtw_dev *rtwdev) @@ -945,6 +1181,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; @@ -1009,11 +1248,13 @@ static int rtw_drv_info_cfg(struct rtw_dev *rtwdev) u8 value8; rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); - value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); - value8 &= 0xF0; - /* For rxdesc len = 0 issue */ - value8 |= 0xF; - rtw_write8(rtwdev, REG_TRXFF_BNDY + 1, value8); + if (rtw_chip_wcpu_11ac(rtwdev)) { + value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); + value8 &= 0xF0; + /* For rxdesc len = 0 issue */ + value8 |= 0xF; + rtw_write8(rtwdev, REG_TRXFF_BNDY + 1, value8); + } rtw_write32_set(rtwdev, REG_RCR, BIT_APP_PHYSTS); rtw_write32_clr(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, BIT(8) | BIT(9)); |
