Commit a82dfd33 authored by Sascha Hauer's avatar Sascha Hauer Committed by Kalle Valo

wifi: rtw88: Add common USB chip support

Add the common bits and pieces to add USB support to the RTW88 driver.
This is based on https://github.com/ulli-kroll/rtw88-usb.git which
itself is first written by Neo Jou.
Signed-off-by: default avatarneo_jou <neo_jou@realtek.com>
Signed-off-by: default avatarHans Ulli Kroll <linux@ulli-kroll.de>
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221202081224.2779981-8-s.hauer@pengutronix.de
parent 78d5bf92
......@@ -16,6 +16,9 @@ config RTW88_CORE
config RTW88_PCI
tristate
config RTW88_USB
tristate
config RTW88_8822B
tristate
......
......@@ -46,3 +46,6 @@ rtw88_8821ce-objs := rtw8821ce.o
obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
rtw88_pci-objs := pci.o
obj-$(CONFIG_RTW88_USB) += rtw88_usb.o
rtw88_usb-objs := usb.o
......@@ -1048,6 +1048,9 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
if (rtw_chip_wcpu_11ac(rtwdev))
rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN);
return 0;
}
......
......@@ -1783,6 +1783,10 @@ static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev)
rtwdev->hci.rpwm_addr = 0x03d9;
rtwdev->hci.cpwm_addr = 0x03da;
break;
case RTW_HCI_TYPE_USB:
rtwdev->hci.rpwm_addr = 0xfe58;
rtwdev->hci.cpwm_addr = 0xfe57;
break;
default:
rtw_err(rtwdev, "unsupported hci type\n");
return -EINVAL;
......
......@@ -871,6 +871,10 @@ struct rtw_chip_ops {
bool is_tx2_path);
void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path,
u8 rx_path, bool is_tx2_path);
/* for USB/SDIO only */
void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *txdesc);
/* for coex */
void (*coex_set_init)(struct rtw_dev *rtwdev);
......
......@@ -184,6 +184,7 @@
#define BIT_TXDMA_VIQ_MAP(x) \
(((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
#define REG_TXDMA_PQ_MAP 0x010C
#define BIT_RXDMA_ARBBW_EN BIT(0)
#define BIT_SHIFT_TXDMA_BEQ_MAP 8
#define BIT_MASK_TXDMA_BEQ_MAP 0x3
#define BIT_TXDMA_BEQ_MAP(x) \
......
......@@ -71,6 +71,14 @@
le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15))
#define SET_TX_DESC_BT_NULL(txdesc, value) \
le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23))
#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \
le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0))
#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \
le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24))
#define GET_TX_DESC_PKT_OFFSET(txdesc) \
le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24))
#define GET_TX_DESC_QSEL(txdesc) \
le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8))
enum rtw_tx_desc_queue_select {
TX_DESC_QSEL_TID0 = 0,
......@@ -123,4 +131,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *buf, u32 size);
static inline
void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
{
__le16 chksum = 0;
__le16 *data = (__le16 *)(txdesc);
SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
while (words--)
chksum ^= *data++;
SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
}
static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info,
u8 *txdesc)
{
const struct rtw_chip_info *chip = rtwdev->chip;
chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
}
#endif
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2018-2019 Realtek Corporation
*/
#ifndef __RTW_USB_H_
#define __RTW_USB_H_
#define FW_8192C_START_ADDRESS 0x1000
#define FW_8192C_END_ADDRESS 0x5fff
#define RTW_USB_MAX_RXTX_COUNT 128
#define RTW_USB_VENQT_MAX_BUF_SIZE 254
#define MAX_USBCTRL_VENDORREQ_TIMES 10
#define RTW_USB_CMD_READ 0xc0
#define RTW_USB_CMD_WRITE 0x40
#define RTW_USB_CMD_REQ 0x05
#define RTW_USB_VENQT_CMD_IDX 0x00
#define RTW_USB_SUPER_SPEED_BULK_SIZE 1024
#define RTW_USB_HIGH_SPEED_BULK_SIZE 512
#define RTW_USB_FULL_SPEED_BULK_SIZE 64
#define RTW_USB_TX_SEL_HQ BIT(0)
#define RTW_USB_TX_SEL_LQ BIT(1)
#define RTW_USB_TX_SEL_NQ BIT(2)
#define RTW_USB_TX_SEL_EQ BIT(3)
#define RTW_USB_BULK_IN_ADDR 0x80
#define RTW_USB_INT_IN_ADDR 0x81
#define RTW_USB_HW_QUEUE_ENTRY 8
#define RTW_USB_PACKET_OFFSET_SZ 8
#define RTW_USB_MAX_XMITBUF_SZ (1024 * 20)
#define RTW_USB_MAX_RECVBUF_SZ 32768
#define RTW_USB_RECVBUFF_ALIGN_SZ 8
#define RTW_USB_RXAGG_SIZE 6
#define RTW_USB_RXAGG_TIMEOUT 10
#define RTW_USB_RXCB_NUM 4
#define RTW_USB_EP_MAX 4
#define TX_DESC_QSEL_MAX 20
#define RTW_USB_VENDOR_ID_REALTEK 0x0bda
static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev)
{
return (struct rtw_usb *)rtwdev->priv;
}
struct rx_usb_ctrl_block {
struct rtw_dev *rtwdev;
struct urb *rx_urb;
struct sk_buff *rx_skb;
int n;
};
struct rtw_usb_tx_data {
u8 sn;
};
struct rtw_usb {
struct rtw_dev *rtwdev;
struct usb_device *udev;
/* protects usb_data_index */
spinlock_t usb_lock;
__le32 *usb_data;
unsigned int usb_data_index;
u32 bulkout_size;
u8 pipe_interrupt;
u8 pipe_in;
u8 out_ep[RTW_USB_EP_MAX];
u8 qsel_to_ep[TX_DESC_QSEL_MAX];
u8 usb_txagg_num;
struct workqueue_struct *txwq, *rxwq;
struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
struct work_struct tx_work;
struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM];
struct sk_buff_head rx_queue;
struct work_struct rx_work;
};
static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
sizeof(info->status.status_driver_data));
return (struct rtw_usb_tx_data *)info->status.status_driver_data;
}
int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
void rtw_usb_disconnect(struct usb_interface *intf);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment