| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2009 Sam Leffler, Errno Consulting |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | #ifndef _NET80211_IEEE80211_SUPERG_H_ |
| 28 | #define _NET80211_IEEE80211_SUPERG_H_ |
| 29 | |
| 30 | /* |
| 31 | * Atheros' 802.11 SuperG protocol support. |
| 32 | */ |
| 33 | |
| 34 | /* |
| 35 | * Atheros advanced capability information element. |
| 36 | */ |
| 37 | struct ieee80211_ath_ie { |
| 38 | 	uint8_t		ath_id;			/* IEEE80211_ELEMID_VENDOR */ |
| 39 | 	uint8_t		ath_len;		/* length in bytes */ |
| 40 | 	uint8_t		ath_oui[3];		/* ATH_OUI */ |
| 41 | 	uint8_t		ath_oui_type;		/* ATH_OUI_TYPE */ |
| 42 | 	uint8_t		ath_oui_subtype;	/* ATH_OUI_SUBTYPE */ |
| 43 | 	uint8_t		ath_version;		/* spec revision */ |
| 44 | 	uint8_t		ath_capability;		/* capability info */ |
| 45 | #define	ATHEROS_CAP_TURBO_PRIME		0x01	/* dynamic turbo--aka Turbo' */ |
| 46 | #define	ATHEROS_CAP_COMPRESSION		0x02	/* data compression */ |
| 47 | #define	ATHEROS_CAP_FAST_FRAME		0x04	/* fast (jumbo) frames */ |
| 48 | #define	ATHEROS_CAP_XR			0x08	/* Xtended Range support */ |
| 49 | #define	ATHEROS_CAP_AR			0x10	/* Advanded Radar support */ |
| 50 | #define	ATHEROS_CAP_BURST		0x20	/* Bursting - not negotiated */ |
| 51 | #define	ATHEROS_CAP_WME			0x40	/* CWMin tuning */ |
| 52 | #define	ATHEROS_CAP_BOOST		0x80	/* use turbo/!turbo mode */ |
| 53 | 	uint8_t		ath_defkeyix[2]; |
| 54 | } __packed; |
| 55 | |
| 56 | #define	ATH_OUI_VERSION		0x00 |
| 57 | #define	ATH_OUI_SUBTYPE		0x01 |
| 58 | |
| 59 | #ifdef _KERNEL |
| 60 | struct ieee80211_stageq { |
| 61 | 	struct mbuf		*head;		/* frames linked w/ m_nextpkt */ |
| 62 | 	struct mbuf		*tail;		/* last frame in queue */ |
| 63 | 	int			depth;		/* # items on head */ |
| 64 | }; |
| 65 | |
| 66 | struct ieee80211_superg { |
| 67 | 	/* fast-frames staging q */ |
| 68 | 	struct ieee80211_stageq	ff_stageq[WME_NUM_AC]; |
| 69 | 	/* flush queues automatically */ |
| 70 | 	struct timeout_task	ff_qtimer; |
| 71 | }; |
| 72 | |
| 73 | void	ieee80211_superg_attach(struct ieee80211com *); |
| 74 | void	ieee80211_superg_detach(struct ieee80211com *); |
| 75 | void	ieee80211_superg_vattach(struct ieee80211vap *); |
| 76 | void	ieee80211_superg_vdetach(struct ieee80211vap *); |
| 77 | |
| 78 | uint8_t *ieee80211_add_ath(uint8_t *, uint8_t, ieee80211_keyix); |
| 79 | uint8_t *ieee80211_add_athcaps(uint8_t *, const struct ieee80211_node *); |
| 80 | void	ieee80211_parse_ath(struct ieee80211_node *, uint8_t *); |
| 81 | int	ieee80211_parse_athparams(struct ieee80211_node *, uint8_t *, |
| 82 | 	 const struct ieee80211_frame *); |
| 83 | |
| 84 | void	ieee80211_ff_node_init(struct ieee80211_node *); |
| 85 | void	ieee80211_ff_node_cleanup(struct ieee80211_node *); |
| 86 | |
| 87 | static inline int |
| 88 | ieee80211_amsdu_tx_ok(struct ieee80211_node *ni) |
| 89 | { |
| 90 | |
| 91 | 	/* First: software A-MSDU transmit? */ |
| 92 | 	if ((ni->ni_ic->ic_caps & IEEE80211_C_SWAMSDUTX) == 0) |
| 93 | 		return (0); |
| 94 | |
| 95 | 	/* Next: does the VAP have AMSDU TX enabled? */ |
| 96 | 	if ((ni->ni_vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX) == 0) |
| 97 | 		return (0); |
| 98 | |
| 99 | 	/* Next: 11n node? (assumed that A-MSDU TX to HT nodes is ok */ |
| 100 | 	if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) |
| 101 | 		return (0); |
| 102 | |
| 103 | 	/* ok, we can at least /do/ AMSDU to this node */ |
| 104 | 	return (1); |
| 105 | } |
| 106 | |
| 107 | struct mbuf * ieee80211_amsdu_check(struct ieee80211_node *ni, struct mbuf *m); |
| 108 | struct mbuf *ieee80211_ff_check(struct ieee80211_node *, struct mbuf *); |
| 109 | void	ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *, |
| 110 | 	 int quanta); |
| 111 | |
| 112 | static __inline void |
| 113 | ieee80211_ff_age_all(struct ieee80211com *ic, int quanta) |
| 114 | { |
| 115 | 	struct ieee80211_superg *sg = ic->ic_superg; |
| 116 | |
| 117 | 	if (sg != NULL) { |
| 118 | 		ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta); |
| 119 | 		ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VI], quanta); |
| 120 | 		ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BE], quanta); |
| 121 | 		ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BK], quanta); |
| 122 | 	} |
| 123 | } |
| 124 | |
| 125 | static __inline void |
| 126 | ieee80211_ff_flush(struct ieee80211com *ic, int ac) |
| 127 | { |
| 128 | 	struct ieee80211_superg *sg = ic->ic_superg; |
| 129 | |
| 130 | 	if (sg != NULL) |
| 131 | 		ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff); |
| 132 | } |
| 133 | |
| 134 | static __inline void |
| 135 | ieee80211_ff_flush_all(struct ieee80211com *ic) |
| 136 | { |
| 137 | 	ieee80211_ff_age_all(ic, 0x7fffffff); |
| 138 | } |
| 139 | |
| 140 | struct mbuf *ieee80211_ff_encap(struct ieee80211vap *, struct mbuf *, |
| 141 | 	 int, struct ieee80211_key *); |
| 142 | struct mbuf * ieee80211_amsdu_encap(struct ieee80211vap *vap, struct mbuf *m1, |
| 143 | 	 int hdrspace, struct ieee80211_key *key); |
| 144 | |
| 145 | struct mbuf *ieee80211_ff_decap(struct ieee80211_node *, struct mbuf *); |
| 146 | |
| 147 | static __inline struct mbuf * |
| 148 | ieee80211_decap_fastframe(struct ieee80211vap *vap, struct ieee80211_node *ni, |
| 149 | struct mbuf *m) |
| 150 | { |
| 151 | 	return IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? |
| 152 | 	 ieee80211_ff_decap(ni, m) : m; |
| 153 | } |
| 154 | #endif /* _KERNEL */ |
| 155 | #endif /* _NET80211_IEEE80211_SUPERG_H_ */ |