Edit

IABSD.fr/src/sys/dev/usb/if_athn_usb.h

Branch :

  • Show log

    Commit

  • Author : krw
    Date : 2020-11-30 16:09:33
    Hash : 4fac4e76
    Message : Fix deferred key tasks along the same lines as urtwn(4) and run(4). athn(4) tested by stsp@, who points out that otus(4) and rsu(4) don't yet invoke the code path to do their own key setting. ok stsp@

  • sys/dev/usb/if_athn_usb.h
  • /*	$OpenBSD: if_athn_usb.h,v 1.12 2020/11/30 16:09:33 krw Exp $	*/
    
    /*-
     * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
     * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
     *
     * Permission to use, copy, modify, and distribute this software for any
     * purpose with or without fee is hereby granted, provided that the above
     * copyright notice and this permission notice appear in all copies.
     *
     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     */
    
    /* Maximum number of STAs firmware can handle. */
    #define AR_USB_MAX_STA	8
    
    #define AR_USB_DEFAULT_NF	(-95)
    
    /* USB requests. */
    #define AR_FW_DOWNLOAD		0x30
    #define AR_FW_DOWNLOAD_COMP	0x31
    
    /* USB endpoints addresses. */
    #define AR_PIPE_TX_DATA	(UE_DIR_OUT | 1)
    #define AR_PIPE_RX_DATA	(UE_DIR_IN  | 2)
    #define AR_PIPE_RX_INTR	(UE_DIR_IN  | 3)
    #define AR_PIPE_TX_INTR	(UE_DIR_OUT | 4)
    
    /* Wireless module interface commands. */
    #define AR_WMI_CMD_ECHO			0x001
    #define AR_WMI_CMD_ACCESS_MEMORY	0x002
    #define AR_WMI_GET_FW_VERSION		0x003
    #define AR_WMI_CMD_DISABLE_INTR		0x004
    #define AR_WMI_CMD_ENABLE_INTR		0x005
    #define AR_WMI_CMD_ATH_INIT		0x006
    #define AR_WMI_CMD_ABORT_TXQ		0x007
    #define AR_WMI_CMD_STOP_TX_DMA		0x008
    #define AR_WMI_CMD_ABORT_TX_DMA		0x009
    #define AR_WMI_CMD_DRAIN_TXQ		0x00a
    #define AR_WMI_CMD_DRAIN_TXQ_ALL	0x00b
    #define AR_WMI_CMD_START_RECV		0x00c
    #define AR_WMI_CMD_STOP_RECV		0x00d
    #define AR_WMI_CMD_FLUSH_RECV		0x00e
    #define AR_WMI_CMD_SET_MODE		0x00f
    #define AR_WMI_CMD_NODE_CREATE		0x010
    #define AR_WMI_CMD_NODE_REMOVE		0x011
    #define AR_WMI_CMD_VAP_REMOVE		0x012
    #define AR_WMI_CMD_VAP_CREATE		0x013
    #define AR_WMI_CMD_REG_READ		0x014
    #define AR_WMI_CMD_REG_WRITE		0x015
    #define AR_WMI_CMD_RC_STATE_CHANGE	0x016
    #define AR_WMI_CMD_RC_RATE_UPDATE	0x017
    #define AR_WMI_CMD_TARGET_IC_UPDATE	0x018
    #define AR_WMI_CMD_TX_AGGR_ENABLE	0x019
    #define AR_WMI_CMD_TGT_DETACH		0x020
    #define AR_WMI_CMD_NODE_UPDATE		0x021
    #define AR_WMI_CMD_INT_STATS		0x022
    #define AR_WMI_CMD_TX_STATS		0x023
    #define AR_WMI_CMD_RX_STATS		0x024
    #define AR_WMI_CMD_BITRATE_MASK		0x025
    #define AR_WMI_CMD_REG_RMW		0x026
    
    /* Wireless module interface events. */
    #define AR_WMI_EVT_TGT_RDY		0x001
    #define AR_WMI_EVT_SWBA			0x002
    #define AR_WMI_EVT_FATAL		0x003
    #define AR_WMI_EVT_TXTO			0x004
    #define AR_WMI_EVT_BMISS		0x005
    #define AR_WMI_EVT_DELBA		0x006
    #define AR_WMI_EVT_TXSTATUS		0x007
    
    /* Structure for service AR_SVC_WMI_CONTROL. */
    struct ar_wmi_cmd_hdr {
    	uint16_t	cmd_id;
    #define AR_WMI_EVT_FLAG	0x1000
    
    	uint16_t	seq_no;
    } __packed;
    
    /* Values for AR_WMI_CMD_SET_MODE. */
    #define AR_HTC_MODE_11NA	0
    #define AR_HTC_MODE_11NG	1
    
    #define AR_MAX_WRITE_COUNT	32
    /* Structure for command AR_WMI_CMD_REG_WRITE. */
    struct ar_wmi_cmd_reg_write {
    	uint32_t	addr;
    	uint32_t	val;
    } __packed;
    
    /* Structure for command AR_WMI_CMD_NODE_{CREATE,REMOVE}. */
    struct ar_htc_target_sta {
    	uint8_t		macaddr[IEEE80211_ADDR_LEN];
    	uint8_t		bssid[IEEE80211_ADDR_LEN];
    	uint8_t		sta_index;
    	uint8_t		vif_index;
    	uint8_t		is_vif_sta;
    	uint16_t	flags;
    #define AR_HTC_STA_AUTH	0x0001
    #define AR_HTC_STA_QOS	0x0002
    #define AR_HTC_STA_ERP	0x0004
    #define AR_HTC_STA_HT	0x0008
    
    	uint16_t	htcap;
    	uint16_t	maxampdu;
    	uint8_t		pad;
    
    	/* Internal state. */
    	uint16_t	txseqmgmt;
    	uint16_t	iv16;
    	uint32_t	iv32;
    	void		*ni_vap;
    } __packed;
    
    /* Structures for command AR_WMI_CMD_RC_RATE_UPDATE. */
    #define AR_HTC_RATE_MAX	30
    struct ar_htc_rateset {
    	uint8_t		rs_nrates;
    	uint8_t		rs_rates[AR_HTC_RATE_MAX];
    } __packed;
    
    struct ar_htc_target_rate {
    	uint8_t			sta_index;
    	uint8_t			isnew;
    	uint8_t			pad[2];
    	uint32_t		capflags;
    #define AR_RC_DS_FLAG		0x00000001
    #define AR_RC_40_FLAG		0x00000002
    #define AR_RC_SGI_FLAG		0x00000004
    #define AR_RC_HT_FLAG		0x00000008
    #define AR_RC_STBC_FLAG		0x00000030 /* 2 bits */
    #define AR_RC_WEP_TKIP_FLAG	0x00000100 
    
    	struct ar_htc_rateset	lg_rates;
    	struct ar_htc_rateset	ht_rates;
    } __packed;
    
    /* Structure for command AR_WMI_CMD_TX_AGGR_ENABLE. */
    struct ar_htc_target_aggr {
    	uint8_t		sta_index;
    	uint8_t		tidno;
    	uint8_t		aggr_enable;
    	uint8_t		padding;
    } __packed;
    
    /* Structure for command AR_WMI_CMD_VAP_CREATE. */
    struct ar_htc_target_vif {
    	uint8_t		index;
    	uint32_t	opmode;
    #define AR_HTC_M_IBSS		0
    #define AR_HTC_M_STA		1
    #define AR_HTC_M_WDS		2
    #define AR_HTC_M_AHDEMO		3
    #define AR_HTC_M_HOSTAP		6
    #define AR_HTC_M_MONITOR	8
    	uint8_t		myaddr[IEEE80211_ADDR_LEN];
    	uint8_t		ath_cap;
    	uint16_t	rtsthreshold;
    	uint8_t		pad;
    
    	/* Internal state. */
    	int8_t		nodeindex;
    	void		*iv_bss;
    } __packed;
    
    /* Structure for command AM_WMI_CMD_TARGET_IC_UPDATE. */
    struct ar_htc_cap_target {
    	uint32_t	ampdu_limit;
    	uint8_t		ampdu_subframes;
    	uint8_t		enable_coex;
    	uint8_t		txchainmask;
    	uint8_t		pad;
    } __packed;
    
    struct ar_wmi_evt_txstatus {
    	uint8_t		cookie;
    
    	/* 
    	 * Legacy rates are indicated as rate array indices.
    	 * HT rates are indicated as MCS indices.
    	 */
    	uint8_t		rate;
    #define AR_HTC_TXSTAT_RATE		0x0f
    #define AR_HTC_TXSTAT_EPID		0xf0
    #define AR_HTC_TXSTAT_EPID_SHIFT	4
    
    	uint8_t		flags;
    #define AR_HTC_TXSTAT_ACK	0x01
    #define AR_HTC_TXSTAT_FILT	0x02
    #define AR_HTC_TXSTAT_RTC_CTS	0x04
    #define AR_HTC_TXSTAT_MCS	0x08
    #define AR_HTC_TXSTAT_CW40	0x10
    #define AR_HTC_TXSTAT_SGI	0x20
    } __packed;
    
    /* Structure for event AR_WMI_EVT_TXSTATUS. */
    #define AR_HTC_MAX_TX_STATUS 12
    struct ar_wmi_evt_txstatus_list {
    	uint8_t			count;
    	struct ar_wmi_evt_txstatus ts[AR_HTC_MAX_TX_STATUS];
    } __packed;
    
    /* HTC header. */
    struct ar_htc_frame_hdr {
    	uint8_t		endpoint_id;
    	uint8_t		flags;
    #define AR_HTC_FLAG_NEED_CREDIT_UPDATE		0x01
    #define AR_HTC_FLAG_TRAILER			0x02
    #define AR_HTC_FLAG_CREDIT_REDISTRIBUTION	0x03
    
    	uint16_t	payload_len;
    	uint8_t		control[4];
    } __packed;
    
    /* Structure for HTC enpoint id 0. */
    struct ar_htc_msg_hdr {
    	uint16_t	msg_id;
    #define AR_HTC_MSG_READY		0x0001
    #define AR_HTC_MSG_CONN_SVC		0x0002
    #define AR_HTC_MSG_CONN_SVC_RSP		0x0003
    #define AR_HTC_MSG_SETUP_COMPLETE	0x0004
    #define AR_HTC_MSG_CONF_PIPE		0x0005
    #define AR_HTC_MSG_CONF_PIPE_RSP	0x0006
    } __packed;
    
    /* Structure for services AR_SVC_WMI_DATA_{VO,VI,BE,BK}. */
    struct ar_tx_frame {
    	uint8_t		data_type;
    #define AR_HTC_AMPDU	1
    #define AR_HTC_NORMAL	2
    
    	uint8_t		node_idx;
    	uint8_t		vif_idx;
    	uint8_t		tid;
    	uint32_t	flags;
    #define AR_HTC_TX_CTSONLY	0x00000001
    #define AR_HTC_TX_RTSCTS	0x00000002
    #define AR_HTC_TX_USE_MIN_RATE	0x00000100
    
    	uint8_t		key_type;
    	uint8_t		key_idx;
    	uint8_t		cookie;
    	uint8_t		pad;
    } __packed;
    
    /* Structure for service AR_SVC_WMI_MGMT. */
    struct ar_tx_mgmt {
    	uint8_t		node_idx;
    	uint8_t		vif_idx;
    	uint8_t		tid;
    	uint8_t		flags;
    	uint8_t		key_type;
    	uint8_t		key_idx;
    	uint8_t		cookie;
    	uint8_t		pad;
    } __packed;
    
    /* Structure for service AR_SVC_WMI_BEACON. */
    struct ar_tx_bcn {
    	uint8_t		len_changed;
    	uint8_t		vif_idx;
    	uint16_t	rev;
    } __packed;
    
    /* Structure for message AR_HTC_MSG_READY. */
    struct ar_htc_msg_ready {
    	uint16_t	credits;
    	uint16_t	credits_size;
    	uint8_t		max_endpoints;
    	uint8_t		reserved;
    } __packed;
    
    /* Structure for message AR_HTC_MSG_CONF_PIPE. */
    struct ar_htc_msg_config_pipe {
    	uint8_t		pipe_id;
    	uint8_t		credits;
    } __packed;
    
    /* Structure for message AR_HTC_MSG_CONN_SVC. */
    struct ar_htc_msg_conn_svc {
    	uint16_t	svc_id;
    	uint16_t	conn_flags;
    	uint8_t		dl_pipeid;
    	uint8_t		ul_pipeid;
    	uint8_t		svc_meta_len;
    	uint8_t		reserved;
    } __packed;
    
    /* Structure for message AR_HTC_MSG_CONN_SVC_RSP. */
    struct ar_htc_msg_conn_svc_rsp {
    	uint16_t	svc_id;
    	uint8_t		status;
    #define AR_HTC_SVC_SUCCESS	0
    #define AR_HTC_SVC_NOT_FOUND	1
    #define AR_HTC_SVC_FAILED	2
    #define AR_HTC_SVC_NO_RESOURCES	3
    #define AR_HTC_SVC_NO_MORE_EP	4
    
    	uint8_t		endpoint_id;
    	uint16_t	max_msg_len;
    	uint8_t		svc_meta_len;
    	uint8_t		reserved;
    } __packed;
    
    #define AR_SVC(grp, idx)	((grp) << 8 | (idx))
    #define AR_SVC_IDX(svc)		((svc) & 0xff)
    /* Service groups. */
    #define AR_SVC_GRP_RSVD		0
    #define AR_SVC_GRP_WMI		1
    /* Service identifiers for WMI group. */
    #define AR_SVC_WMI_CONTROL	AR_SVC(AR_SVC_GRP_WMI, 0)
    #define AR_SVC_WMI_BEACON	AR_SVC(AR_SVC_GRP_WMI, 1)
    #define AR_SVC_WMI_CAB		AR_SVC(AR_SVC_GRP_WMI, 2)
    #define AR_SVC_WMI_UAPSD	AR_SVC(AR_SVC_GRP_WMI, 3)
    #define AR_SVC_WMI_MGMT		AR_SVC(AR_SVC_GRP_WMI, 4)
    #define AR_SVC_WMI_DATA_VO	AR_SVC(AR_SVC_GRP_WMI, 5)
    #define AR_SVC_WMI_DATA_VI	AR_SVC(AR_SVC_GRP_WMI, 6)
    #define AR_SVC_WMI_DATA_BE	AR_SVC(AR_SVC_GRP_WMI, 7)
    #define AR_SVC_WMI_DATA_BK	AR_SVC(AR_SVC_GRP_WMI, 8)
    
    struct ar_stream_hdr {
    	uint16_t	len;
    	uint16_t	tag;
    #define AR_USB_RX_STREAM_TAG	0x4e00
    #define AR_USB_TX_STREAM_TAG	0x697e
    } __packed __attribute__((aligned(4)));
    
    #define AR_MAX_CHAINS	3
    
    /* Rx descriptor. */
    struct ar_rx_status {
    	uint64_t	rs_tstamp;
    	uint16_t	rs_datalen;
    	uint8_t		rs_status;
    #define AR_RXS_RXERR_CRC               0x01
    #define AR_RXS_RXERR_PHY               0x02
    #define AR_RXS_RXERR_FIFO              0x04
    #define AR_RXS_RXERR_DECRYPT           0x08
    #define AR_RXS_RXERR_MIC               0x10
    	uint8_t		rs_phyerr;
    	int8_t		rs_rssi;
    	int8_t		rs_rssi_ctl[AR_MAX_CHAINS];
    	int8_t		rs_rssi_ext[AR_MAX_CHAINS];
    	uint8_t		rs_keyix;
    	uint8_t		rs_rate;
    	uint8_t		rs_antenna;
    	uint8_t		rs_more;
    	uint8_t		rs_isaggr;
    	uint8_t		rs_moreaggr;
    	uint8_t		rs_num_delims;
    	uint8_t		rs_flags;
    #define AR_RXS_FLAG_GI		0x04
    #define AR_RXS_FLAG_2040	0x08
    
    	uint8_t		rs_dummy;
    	uint32_t	rs_evm[AR_MAX_CHAINS];
    } __packed __attribute__((aligned(4)));
    
    
    /*
     * Driver definitions.
     */
    #define ATHN_USB_RX_LIST_COUNT	1
    #define ATHN_USB_TX_LIST_COUNT	(8 + 1)		/* NB: +1 for beacons. */
    
    #define ATHN_USB_HOST_CMD_RING_COUNT	32
    
    #define ATHN_USB_RXBUFSZ	(8 * 1024)	/* XXX Linux 16K */
    #define ATHN_USB_TXBUFSZ			\
    	((sizeof(struct ar_stream_hdr) +	\
    	  sizeof(struct ar_htc_frame_hdr) +	\
    	  sizeof(struct ar_tx_frame) +		\
    	  IEEE80211_MAX_LEN + 3) & ~3)
    #define ATHN_USB_TXCMDSZ	512
    
    #define ATHN_USB_TX_TIMEOUT	5000	/* ms */
    #define ATHN_USB_CMD_TIMEOUT	1000	/* ms */
    
    struct athn_usb_softc;
    
    struct athn_usb_rx_stream {
    	struct mbuf	*m;
    	int		moff;
    	int		left;
    };
    
    struct athn_usb_rx_data {
    	struct athn_usb_softc	*sc;
    	struct usbd_xfer	*xfer;
    	uint8_t			*buf;
    };
    
    struct athn_usb_tx_data {
    	struct athn_usb_softc		*sc;
    	struct usbd_xfer		*xfer;
    	uint8_t				*buf;
    	TAILQ_ENTRY(athn_usb_tx_data)	next;
    };
    
    struct athn_usb_host_cmd {
    	void	(*cb)(struct athn_usb_softc *, void *);
    	uint8_t	data[256];
    };
    
    struct athn_usb_cmd_newstate {
    	enum ieee80211_state	state;
    	int			arg;
    };
    
    struct athn_usb_cmd_key {
    	struct ieee80211_node	*ni;
    	struct ieee80211_key	*key;
    };
    
    struct athn_usb_aggr_cmd {
    	uint8_t	sta_index;
    	uint8_t	tid;
    };
    
    struct athn_usb_host_cmd_ring {
    	struct athn_usb_host_cmd	cmd[ATHN_USB_HOST_CMD_RING_COUNT];
    	int				cur;
    	int				next;
    	int				queued;
    };
    
    struct athn_usb_softc {
    	struct athn_softc		sc_sc;
    #define usb_dev	sc_sc.sc_dev
    	int				sc_athn_attached;
    
    	/* USB specific goo. */
    	struct usbd_device		*sc_udev;
    	struct usbd_interface		*sc_iface;
    	struct usb_task			sc_task;
    
    	u_int				flags;
    #define ATHN_USB_FLAG_AR7010	0x01
    
    	struct athn_usb_rx_stream	rx_stream;
    
    	struct usbd_pipe		*tx_data_pipe;
    	struct usbd_pipe		*rx_data_pipe;
    	struct usbd_pipe		*rx_intr_pipe;
    	struct usbd_pipe		*tx_intr_pipe;
    	uint8_t 			*ibuf;
    	size_t				ibuflen;
    
    	struct ar_wmi_cmd_reg_write	wbuf[AR_MAX_WRITE_COUNT];
    	int				wcount;
    
    	uint16_t			wmi_seq_no;
    	uint16_t			wait_cmd_id;
    	uint16_t			wait_msg_id;
    	void				*obuf;
    	struct ar_htc_msg_conn_svc_rsp	*msg_conn_svc_rsp;
    
    	struct athn_usb_host_cmd_ring	cmdq;
    	struct athn_usb_rx_data		rx_data[ATHN_USB_RX_LIST_COUNT];
    	struct athn_usb_tx_data		tx_data[ATHN_USB_TX_LIST_COUNT];
    	TAILQ_HEAD(, athn_usb_tx_data)	tx_free_list;
    	struct athn_usb_tx_data		tx_cmd;
    	struct athn_usb_tx_data		*tx_bcn;
    
    	uint8_t				ep_ctrl;
    	uint8_t				ep_bcn;
    	uint8_t				ep_cab;
    	uint8_t				ep_uapsd;
    	uint8_t				ep_mgmt;
    	uint8_t				ep_data[EDCA_NUM_AC];
    
    	/* 
    	 * Firmware cannot handle more than 8 STAs.
    	 * We use a bitmask to keep track of available slots in the firmware's
    	 * node array. A 1 bit at index N, as determined by ffs(3), means the
    	 * slot at this index is available.
    	 */
    	uint8_t				free_node_slots;
    
    	void				(*sc_node_free)(struct ieee80211com *,
    					    struct ieee80211_node *);
    	int				sc_key_tasks;
    };