#ifndef _SYS_NET80211_IMPL_H
#define _SYS_NET80211_IMPL_H
#include <sys/sysmacros.h>
#include <sys/list.h>
#include <sys/note.h>
#include <sys/net80211_proto.h>
#include <sys/net80211.h>
#include <sys/mac_wifi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IEEE80211_TXPOWER_MAX 100
#define IEEE80211_TXPOWER_MIN 0
#define IEEE80211_DTIM_MAX 15
#define IEEE80211_DTIM_MIN 1
#define IEEE80211_DTIM_DEFAULT 1
#define IEEE80211_BINTVAL_MAX 1000
#define IEEE80211_BINTVAL_MIN 25
#define IEEE80211_BINTVAL_DEFAULT 100
#define IEEE80211_BMISS_MAX 2
#define IEEE80211_SWBMISS_THRESHOLD 50
#define IEEE80211_HWBMISS_DEFAULT 7
#define IEEE80211_PS_SLEEP 0x1
#define IEEE80211_PS_MAX_QUEUE 50
#define IEEE80211_RTS_DEFAULT IEEE80211_RTS_MAX
#define IEEE80211_FRAG_DEFAULT IEEE80211_FRAG_MAX
#define IEEE80211_RSSI_CMP_THRESHOLD 5
#define IEEE80211_INACT_WAIT 15
#define IEEE80211_INACT_INIT (30/IEEE80211_INACT_WAIT)
#define IEEE80211_INACT_ASSOC (180/IEEE80211_INACT_WAIT)
#define IEEE80211_INACT_RUN (300/IEEE80211_INACT_WAIT)
#define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT)
#define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT)
#define IEEE80211_TRANS_WAIT 5
#define IEEE80211_CHAN_FHSS \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
#define IEEE80211_CHAN_A \
(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
#define IEEE80211_CHAN_B \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
#define IEEE80211_CHAN_PUREG \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
#define IEEE80211_CHAN_G \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
#define IEEE80211_CHAN_T \
(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
#define IEEE80211_CHAN_108G \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
#define IEEE80211_CHAN_ST \
(IEEE80211_CHAN_T | IEEE80211_CHAN_STURBO)
#define IEEE80211_CHAN_ALL \
(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \
IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | \
IEEE80211_CHAN_HT)
#define IEEE80211_CHAN_ALLTURBO \
(IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)
#define IEEE80211_IS_CHAN_FHSS(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
#define IEEE80211_IS_CHAN_A(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
#define IEEE80211_IS_CHAN_B(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
#define IEEE80211_IS_CHAN_PUREG(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
#define IEEE80211_IS_CHAN_G(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
#define IEEE80211_IS_CHAN_ANYG(_c) \
(IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c))
#define IEEE80211_IS_CHAN_T(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_T) == IEEE80211_CHAN_T)
#define IEEE80211_IS_CHAN_108G(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G)
#define IEEE80211_IS_CHAN_ST(_c) \
(((_c)->ich_flags & IEEE80211_CHAN_ST) == IEEE80211_CHAN_ST)
#define IEEE80211_IS_CHAN_OFDM(_c) \
((_c)->ich_flags & IEEE80211_CHAN_OFDM)
#define IEEE80211_IS_CHAN_CCK(_c) \
((_c)->ich_flags & IEEE80211_CHAN_CCK)
#define IEEE80211_IS_CHAN_GFSK(_c) \
((_c)->ich_flags & IEEE80211_CHAN_GFSK)
#define IEEE80211_IS_CHAN_PASSIVE(_c) \
((_c)->ich_flags & IEEE80211_CHAN_PASSIVE)
#define IEEE80211_IS_CHAN_STURBO(_c) \
((_c)->ich_flags & IEEE80211_CHAN_STURBO)
#define IEEE80211_IS_CHAN_DTURBO(_c) \
(((_c)->ich_flags & \
(IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) == IEEE80211_CHAN_TURBO)
#define IEEE80211_IS_CHAN_HALF(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HALF)
#define IEEE80211_IS_CHAN_QUARTER(_c) \
((_c)->ich_flags & IEEE80211_CHAN_QUARTER)
#define IEEE80211_IS_CHAN_FULL(_c) \
((_c)->ich_flags & (IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HALF))
#define IEEE80211_IS_CHAN_GSM(_c) \
((_c)->ich_flags & IEEE80211_CHAN_GSM)
#define IEEE80211_IS_CHAN_HT(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HT)
#define IEEE80211_IS_CHAN_HT20(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HT20)
#define IEEE80211_IS_CHAN_HT40(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HT40)
#define IEEE80211_IS_CHAN_HT40U(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HT40U)
#define IEEE80211_IS_CHAN_HT40D(_c) \
((_c)->ich_flags & IEEE80211_CHAN_HT40D)
#define IEEE80211_IS_CHAN_HTA(_c) \
(IEEE80211_IS_CHAN_5GHZ(_c) && \
((_c)->ich_flags & IEEE80211_CHAN_HT))
#define IEEE80211_IS_CHAN_HTG(_c) \
(IEEE80211_IS_CHAN_2GHZ(_c) && \
((_c)->ich_flags & IEEE80211_CHAN_HT))
#define IEEE80211_IS_CHAN_DFS(_c) \
((_c)->ich_flags & IEEE80211_CHAN_DFS)
#define IEEE80211_IS_CHAN_NOADHOC(_c) \
((_c)->ich_flags & IEEE80211_CHAN_NOADHOC)
#define IEEE80211_IS_CHAN_NOHOSTAP(_c) \
((_c)->ich_flags & IEEE80211_CHAN_NOHOSTAP)
#define IEEE80211_IS_CHAN_11D(_c) \
((_c)->ich_flags & IEEE80211_CHAN_11D)
#define IEEE80211_FH_CHANMOD 80
#define IEEE80211_FH_CHAN(set, pat) \
(((set) - 1) * IEEE80211_FH_CHANMOD + (pat))
#define IEEE80211_FH_CHANSET(chan) \
((chan) / IEEE80211_FH_CHANMOD + 1)
#define IEEE80211_FH_CHANPAT(chan) \
((chan) % IEEE80211_FH_CHANMOD)
#define IEEE80211_NODE_AUTH 0x0001
#define IEEE80211_NODE_QOS 0x0002
#define IEEE80211_NODE_ERP 0x0004
#define IEEE80211_NODE_PWR_MGT 0x0010
#define IEEE80211_NODE_AREF 0x0020
#define IEEE80211_MAXRSSI 127
#define IEEE80211_MSG_BRUSSELS 0x80000000
#define IEEE80211_MSG_DEBUG 0x40000000
#define IEEE80211_MSG_DUMPPKTS 0x20000000
#define IEEE80211_MSG_CRYPTO 0x10000000
#define IEEE80211_MSG_INPUT 0x08000000
#define IEEE80211_MSG_XRATE 0x04000000
#define IEEE80211_MSG_ELEMID 0x02000000
#define IEEE80211_MSG_NODE 0x01000000
#define IEEE80211_MSG_ASSOC 0x00800000
#define IEEE80211_MSG_AUTH 0x00400000
#define IEEE80211_MSG_SCAN 0x00200000
#define IEEE80211_MSG_OUTPUT 0x00100000
#define IEEE80211_MSG_STATE 0x00080000
#define IEEE80211_MSG_POWER 0x00040000
#define IEEE80211_MSG_DOT1X 0x00020000
#define IEEE80211_MSG_DOT1XSM 0x00010000
#define IEEE80211_MSG_RADIUS 0x00008000
#define IEEE80211_MSG_RADDUMP 0x00004000
#define IEEE80211_MSG_RADKEYS 0x00002000
#define IEEE80211_MSG_WPA 0x00001000
#define IEEE80211_MSG_ACL 0x00000800
#define IEEE80211_MSG_WME 0x00000400
#define IEEE80211_MSG_SUPERG 0x00000200
#define IEEE80211_MSG_DOTH 0x00000100
#define IEEE80211_MSG_INACT 0x00000080
#define IEEE80211_MSG_ROAM 0x00000040
#define IEEE80211_MSG_CONFIG 0x00000020
#define IEEE80211_MSG_ACTION 0x00000010
#define IEEE80211_MSG_HT 0x00000008
#define IEEE80211_MSG_ANY 0xffffffff
#define IEEE80211_BADCHAN 0x01
#define IEEE80211_BADOPMODE 0x02
#define IEEE80211_BADPRIVACY 0x04
#define IEEE80211_BADRATE 0x08
#define IEEE80211_BADESSID 0x10
#define IEEE80211_BADBSSID 0x20
#define IEEE80211_NODEFAIL 0x40
typedef struct ieee80211_impl {
struct ieee80211com *ic;
uint8_t im_chan_avail[IEEE80211_CHAN_BYTES];
uint8_t im_chan_scan[IEEE80211_CHAN_BYTES];
uint8_t im_bmiss_count;
int32_t im_bmiss_max;
timeout_id_t im_swbmiss;
uint16_t im_swbmiss_count;
uint16_t im_swbmiss_period;
int32_t im_mgt_timer;
int32_t im_inact_timer;
int32_t im_inact_init;
int32_t im_inact_assoc;
int32_t im_inact_run;
int32_t im_inact_probe;
kcondvar_t im_scan_cv;
} ieee80211_impl_t;
struct ieee80211_scanparams {
uint16_t capinfo;
enum ieee80211_phytype phytype;
uint16_t fhdwell;
uint8_t chan;
uint8_t bchan;
uint8_t fhindex;
uint8_t erp;
uint16_t bintval;
uint8_t timoff;
uint8_t *tim;
uint8_t *tstamp;
uint8_t *country;
uint8_t *ssid;
uint8_t *rates;
uint8_t *xrates;
uint8_t *wpa;
uint8_t *wme;
uint8_t *htcap;
uint8_t *htinfo;
};
#define IEEE80211_SEND_MGMT(_ic, _in, _type, _arg) \
((*(_ic)->ic_send_mgmt)((_ic), (_in), (_type), (_arg)))
#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen, __func) do { \
_NOTE(CONSTCOND) \
if ((__elem) == NULL) { \
ieee80211_err("ieee80211: no #__elem \n"); \
__func; \
} \
if ((__elem)[1] > (__maxlen)) { \
ieee80211_err("ieee80211: bad "#__elem " len %d\n", \
(__elem)[1]); \
__func; \
} \
_NOTE(CONSTCOND) \
} while (0)
#define IEEE80211_VERIFY_LENGTH(_len, _minlen, _func) do { \
_NOTE(CONSTCOND) \
if ((_len) < (_minlen)) { \
ieee80211_dbg(IEEE80211_MSG_ELEMID, \
"ie of type %s too short", \
ieee80211_mgt_subtype_name[subtype >> \
IEEE80211_FC0_SUBTYPE_SHIFT]); \
_func; \
} \
_NOTE(CONSTCOND) \
} while (0)
#define IEEE80211_VERIFY_SSID(_in, _ssid, _func) do { \
_NOTE(CONSTCOND) \
ASSERT((_in) != NULL); \
if ((_ssid)[1] != 0 && \
((_ssid)[1] != (_in)->in_esslen || \
bcmp((_ssid) + 2, (_in)->in_essid, (_ssid)[1]) != 0)) { \
_func; \
} \
_NOTE(CONSTCOND) \
} while (0)
#define ieee80211_setbit(a, i) ((a)[(i)/NBBY] |= (1 << ((i)%NBBY)))
#define ieee80211_clrbit(a, i) ((a)[(i)/NBBY] &= ~(1 << ((i)%NBBY)))
#define ieee80211_isset(a, i) ((a)[(i)/NBBY] & (1 << ((i)%NBBY)))
#define ieee80211_isclr(a, i) (!((a)[(i)/NBBY] & (1 << ((i)%NBBY))))
#define IEEE80211_N(a) (sizeof (a) / sizeof (a[0]))
#define IEEE80211_LOCK(_ic) \
mutex_enter(&(_ic)->ic_genlock)
#define IEEE80211_UNLOCK(_ic) \
mutex_exit(&(_ic)->ic_genlock)
#define IEEE80211_IS_LOCKED(_ic) \
mutex_owned(&(_ic)->ic_genlock)
#define IEEE80211_LOCK_ASSERT(_ic) \
ASSERT(mutex_owned(&(_ic)->ic_genlock))
#define IEEE80211_NODE_LOCK(_nt) \
mutex_enter(&(_nt)->nt_nodelock)
#define IEEE80211_NODE_UNLOCK(_nt) \
mutex_exit(&(_nt)->nt_nodelock)
#define IEEE80211_NODE_IS_LOCKED(_nt) \
mutex_owned(&(_nt)->nt_nodelock)
#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
ASSERT(mutex_owned(&(_nt)->nt_nodelock))
#define ieee80211_node_hash(addr) \
(((uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % IEEE80211_NODE_HASHSIZE)
#define IEEE80211_SCAN_LOCK(_nt) mutex_enter(&(_nt)->nt_scanlock)
#define IEEE80211_SCAN_UNLOCK(_nt) mutex_exit(&(_nt)->nt_scanlock)
#define IEEE80211_RV(v) ((v) & IEEE80211_RATE_VAL)
#define IEEE80211_SUBTYPE_NAME(subtype) \
ieee80211_mgt_subtype_name[(subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT]
extern const char *ieee80211_mgt_subtype_name[];
extern const char *ieee80211_phymode_name[];
void ieee80211_err(const int8_t *, ...);
void ieee80211_dbg(uint32_t, const int8_t *, ...);
void ieee80211_notify(ieee80211com_t *, wpa_event_type);
void ieee80211_mac_update(ieee80211com_t *);
uint64_t ieee80211_read_6(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t);
void ieee80211_node_attach(ieee80211com_t *);
void ieee80211_node_lateattach(ieee80211com_t *);
void ieee80211_node_detach(ieee80211com_t *);
void ieee80211_reset_bss(ieee80211com_t *);
void ieee80211_cancel_scan(ieee80211com_t *);
void ieee80211_add_scan(ieee80211com_t *, const struct ieee80211_scanparams *,
const struct ieee80211_frame *, int, int, int);
void ieee80211_init_neighbor(ieee80211_node_t *, const struct ieee80211_frame *,
const struct ieee80211_scanparams *);
ieee80211_node_t *ieee80211_add_neighbor(ieee80211com_t *,
const struct ieee80211_frame *, const struct ieee80211_scanparams *);
void ieee80211_create_ibss(ieee80211com_t *, struct ieee80211_channel *);
ieee80211_node_t *ieee80211_fakeup_adhoc_node(ieee80211_node_table_t *,
const uint8_t *);
ieee80211_node_t *ieee80211_tmp_node(ieee80211com_t *, const uint8_t *);
void ieee80211_setcurchan(ieee80211com_t *, struct ieee80211_channel *);
void ieee80211_proto_attach(ieee80211com_t *);
int ieee80211_fix_rate(ieee80211_node_t *, struct ieee80211_rateset *, int);
void ieee80211_setbasicrates(struct ieee80211_rateset *,
enum ieee80211_phymode);
void ieee80211_reset_erp(ieee80211com_t *);
void ieee80211_set_shortslottime(ieee80211com_t *, boolean_t);
int ieee80211_setup_rates(ieee80211_node_t *, const uint8_t *,
const uint8_t *, int);
void ieee80211_recv_mgmt(ieee80211com_t *, mblk_t *, ieee80211_node_t *,
int, int, uint32_t);
int ieee80211_send_probereq(ieee80211_node_t *, const uint8_t *,
const uint8_t *, const uint8_t *, const uint8_t *, size_t, const void *,
size_t);
int ieee80211_send_mgmt(ieee80211com_t *, ieee80211_node_t *, int, int);
int ieee80211_send_nulldata(ieee80211_node_t *);
int ieee80211_mgmt_output(ieee80211com_t *, ieee80211_node_t *, mblk_t *,
int, int);
struct ieee80211_key *ieee80211_crypto_getkey(ieee80211com_t *);
uint8_t ieee80211_crypto_getciphertype(ieee80211com_t *);
mblk_t *ieee80211_getmgtframe(uint8_t **, int);
void ieee80211_notify_node_join(ieee80211com_t *, ieee80211_node_t *);
void ieee80211_notify_node_leave(ieee80211com_t *, ieee80211_node_t *);
void ieee80211_wme_initparams(struct ieee80211com *);
void ieee80211_wme_updateparams(struct ieee80211com *);
#ifdef __cplusplus
}
#endif
#endif