Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b40b15e1 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Kalle Valo
Browse files

mt76: add usb support to mt76 layer



This will be used by drivers for MT76x2u based devices

Tested-by: default avatar <cug_yangyuancong@hotmail.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 03780400
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
config MT76_CORE
	tristate

config MT76_USB
	tristate
	depends on MT76_CORE

config MT76x2_COMMON
	tristate
	depends on MT76_CORE
+4 −0
Original line number Diff line number Diff line
obj-$(CONFIG_MT76_CORE) += mt76.o
obj-$(CONFIG_MT76_USB) += mt76-usb.o
obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o
obj-$(CONFIG_MT76x2E) += mt76x2e.o

mt76-y := \
	mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o agg-rx.o

mt76-usb-y := usb.o usb_trace.o usb_mcu.o

CFLAGS_trace.o := -I$(src)
CFLAGS_usb_trace.o := -I$(src)

mt76x2-common-y := \
	mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \
+5 −0
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@
#define MT_MCU_MSG_TYPE			GENMASK(31, 30)
#define MT_MCU_MSG_TYPE_CMD		BIT(30)

#define MT_DMA_HDR_LEN			4
#define MT_RX_INFO_LEN			4
#define MT_FCE_INFO_LEN			4
#define MT_RX_RXWI_LEN			32

struct mt76_desc {
	__le32 buf0;
	__le32 ctrl;
+142 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/leds.h>
#include <linux/usb.h>
#include <net/mac80211.h>
#include "util.h"

@@ -63,12 +64,22 @@ struct mt76_queue_buf {
	int len;
};

struct mt76u_buf {
	struct mt76_dev *dev;
	struct urb *urb;
	size_t len;
	bool done;
};

struct mt76_queue_entry {
	union {
		void *buf;
		struct sk_buff *skb;
	};
	union {
		struct mt76_txwi_cache *txwi;
		struct mt76u_buf ubuf;
	};
	bool schedule;
};

@@ -89,6 +100,7 @@ struct mt76_queue {
	struct list_head swq;
	int swq_queued;

	u16 first;
	u16 head;
	u16 tail;
	int ndesc;
@@ -195,6 +207,8 @@ enum {
	MT76_SCANNING,
	MT76_RESET,
	MT76_OFFCHANNEL,
	MT76_REMOVED,
	MT76_READING_STATS,
};

struct mt76_hw_cap {
@@ -215,6 +229,8 @@ struct mt76_driver_ops {
	void (*tx_complete_skb)(struct mt76_dev *dev, struct mt76_queue *q,
				struct mt76_queue_entry *e, bool flush);

	bool (*tx_status_data)(struct mt76_dev *dev, u8 *update);

	void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
		       struct sk_buff *skb);

@@ -234,6 +250,64 @@ struct mt76_sband {
	struct mt76_channel_state *chan;
};

/* addr req mask */
#define MT_VEND_TYPE_EEPROM	BIT(31)
#define MT_VEND_TYPE_CFG	BIT(30)
#define MT_VEND_TYPE_MASK	(MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG)

#define MT_VEND_ADDR(type, n)	(MT_VEND_TYPE_##type | (n))
enum mt_vendor_req {
	MT_VEND_DEV_MODE =	0x1,
	MT_VEND_WRITE =		0x2,
	MT_VEND_MULTI_WRITE =	0x6,
	MT_VEND_MULTI_READ =	0x7,
	MT_VEND_READ_EEPROM =	0x9,
	MT_VEND_WRITE_FCE =	0x42,
	MT_VEND_WRITE_CFG =	0x46,
	MT_VEND_READ_CFG =	0x47,
};

enum mt76u_in_ep {
	MT_EP_IN_PKT_RX,
	MT_EP_IN_CMD_RESP,
	__MT_EP_IN_MAX,
};

enum mt76u_out_ep {
	MT_EP_OUT_INBAND_CMD,
	MT_EP_OUT_AC_BK,
	MT_EP_OUT_AC_BE,
	MT_EP_OUT_AC_VI,
	MT_EP_OUT_AC_VO,
	MT_EP_OUT_HCCA,
	__MT_EP_OUT_MAX,
};

#define MT_SG_MAX_SIZE		8
#define MT_NUM_TX_ENTRIES	256
#define MT_NUM_RX_ENTRIES	128
#define MCU_RESP_URB_SIZE	1024
struct mt76_usb {
	struct mutex usb_ctrl_mtx;
	u8 data[32];

	struct tasklet_struct rx_tasklet;
	struct tasklet_struct tx_tasklet;
	struct delayed_work stat_work;

	u8 out_ep[__MT_EP_OUT_MAX];
	u16 out_max_packet;
	u8 in_ep[__MT_EP_IN_MAX];
	u16 in_max_packet;

	struct mt76u_mcu {
		struct mutex mutex;
		struct completion cmpl;
		struct mt76u_buf res;
		u32 msg_seq;
	} mcu;
};

struct mt76_dev {
	struct ieee80211_hw *hw;
	struct cfg80211_chan_def chandef;
@@ -276,6 +350,8 @@ struct mt76_dev {
	char led_name[32];
	bool led_al;
	u8 led_pin;

	struct mt76_usb usb;
};

enum mt76_phy_type {
@@ -407,6 +483,14 @@ static inline int mt76_decr(int val, int size)
	return (val - 1) & (size - 1);
}

/* Hardware uses mirrored order of queues with Q3
 * having the highest priority
 */
static inline u8 q2hwq(u8 q)
{
	return q ^ 0x3;
}

static inline struct ieee80211_txq *
mtxq_to_txq(struct mt76_txq *mtxq)
{
@@ -467,4 +551,61 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
			   struct napi_struct *napi);
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames);

/* usb */
static inline bool mt76u_urb_error(struct urb *urb)
{
	return urb->status &&
	       urb->status != -ECONNRESET &&
	       urb->status != -ESHUTDOWN &&
	       urb->status != -ENOENT;
}

/* Map hardware queues to usb endpoints */
static inline u8 q2ep(u8 qid)
{
	/* TODO: take management packets to queue 5 */
	return qid + 1;
}

static inline bool mt76u_check_sg(struct mt76_dev *dev)
{
	struct usb_interface *intf = to_usb_interface(dev->dev);
	struct usb_device *udev = interface_to_usbdev(intf);

	return (udev->bus->sg_tablesize > 0 &&
		(udev->bus->no_sg_constraint ||
		 udev->speed == USB_SPEED_WIRELESS));
}

int mt76u_vendor_request(struct mt76_dev *dev, u8 req,
			 u8 req_type, u16 val, u16 offset,
			 void *buf, size_t len);
void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
		     const u16 offset, const u32 val);
u32 mt76u_rr(struct mt76_dev *dev, u32 addr);
void mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
void mt76u_deinit(struct mt76_dev *dev);
int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
		    int nsgs, int len, int sglen, gfp_t gfp);
void mt76u_buf_free(struct mt76u_buf *buf);
int mt76u_submit_buf(struct mt76_dev *dev, int dir, int index,
		     struct mt76u_buf *buf, gfp_t gfp,
		     usb_complete_t complete_fn, void *context);
int mt76u_submit_rx_buffers(struct mt76_dev *dev);
int mt76u_alloc_queues(struct mt76_dev *dev);
void mt76u_stop_queues(struct mt76_dev *dev);
void mt76u_stop_stat_wk(struct mt76_dev *dev);
void mt76u_queues_deinit(struct mt76_dev *dev);
int mt76u_skb_dma_info(struct sk_buff *skb, int port, u32 flags);

int mt76u_mcu_fw_send_data(struct mt76_dev *dev, const void *data,
			   int data_len, u32 max_payload, u32 offset);
void mt76u_mcu_complete_urb(struct urb *urb);
struct sk_buff *mt76u_mcu_msg_alloc(const void *data, int len);
int mt76u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
		       int cmd, bool wait_resp);
void mt76u_mcu_fw_reset(struct mt76_dev *dev);
int mt76u_mcu_init_rx(struct mt76_dev *dev);

#endif
+845 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading