Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
/*-
 * Copyright (c) 2001 Atsushi Onoe
 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */
#ifndef _NET80211_IEEE80211_VAR_H_
#define _NET80211_IEEE80211_VAR_H_

/*
 * Definitions for IEEE 802.11 drivers.
 */
/* NB: portability glue must go first */
#if defined(__NetBSD__)
#include <net80211/ieee80211_netbsd.h>
#elif defined(__FreeBSD__)
#include <net80211/ieee80211_freebsd.h>
#elif defined(__linux__)
#include <net80211/ieee80211_linux.h>
#else
#error	"No support for your operating system!"
#endif

#include <net80211/_ieee80211.h>
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_ageq.h>
#include <net80211/ieee80211_crypto.h>
#include <net80211/ieee80211_dfs.h>
#include <net80211/ieee80211_ioctl.h>		/* for ieee80211_stats */
#include <net80211/ieee80211_phy.h>
#include <net80211/ieee80211_power.h>
#include <net80211/ieee80211_node.h>
#include <net80211/ieee80211_proto.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_scan.h>

#define	IEEE80211_TXPOWER_MAX	100	/* .5 dBm (XXX units?) */
#define	IEEE80211_TXPOWER_MIN	0	/* kill radio */

#define	IEEE80211_DTIM_DEFAULT	1	/* default DTIM period */
#define	IEEE80211_BINTVAL_DEFAULT 100	/* default beacon interval (TU's) */

#define	IEEE80211_BMISS_MAX	2	/* maximum consecutive bmiss allowed */
#define	IEEE80211_HWBMISS_DEFAULT 7	/* h/w bmiss threshold (beacons) */

#define	IEEE80211_BGSCAN_INTVAL_MIN	15	/* min bg scan intvl (secs) */
#define	IEEE80211_BGSCAN_INTVAL_DEFAULT	(5*60)	/* default bg scan intvl */

#define	IEEE80211_BGSCAN_IDLE_MIN	100	/* min idle time (ms) */
#define	IEEE80211_BGSCAN_IDLE_DEFAULT	250	/* default idle time (ms) */

#define	IEEE80211_SCAN_VALID_MIN	10	/* min scan valid time (secs) */
#define	IEEE80211_SCAN_VALID_DEFAULT	60	/* default scan valid time */

#define	IEEE80211_PS_SLEEP	0x1	/* STA is in power saving mode */
#define	IEEE80211_PS_MAX_QUEUE	50	/* maximum saved packets */

#define	IEEE80211_FIXED_RATE_NONE	0xff
#define	IEEE80211_TXMAX_DEFAULT		6	/* default ucast max retries */

#define	IEEE80211_RTS_DEFAULT		IEEE80211_RTS_MAX
#define	IEEE80211_FRAG_DEFAULT		IEEE80211_FRAG_MAX

#define	IEEE80211_MS_TO_TU(x)	(((x) * 1000) / 1024)
#define	IEEE80211_TU_TO_MS(x)	(((x) * 1024) / 1000)
/* XXX TODO: cap this at 1, in case hz is not 1000 */
#define	IEEE80211_TU_TO_TICKS(x)(((uint64_t)(x) * 1024 * hz) / (1000 * 1000))

/*
 * 802.11 control state is split into a common portion that maps
 * 1-1 to a physical device and one or more "Virtual AP's" (VAP)
 * that are bound to an ieee80211com instance and share a single
 * underlying device.  Each VAP has a corresponding OS device
 * entity through which traffic flows and that applications use
 * for issuing ioctls, etc.
 */

/*
 * Data common to one or more virtual AP's.  State shared by
 * the underlying device and the net80211 layer is exposed here;
 * e.g. device-specific callbacks.
 */
struct ieee80211vap;
typedef void (*ieee80211vap_attach)(struct ieee80211vap *);

struct ieee80211_appie {
	uint16_t		ie_len;		/* size of ie_data */
	uint8_t			ie_data[];	/* user-specified IE's */
};

struct ieee80211_tdma_param;
struct ieee80211_rate_table;
struct ieee80211_tx_ampdu;
struct ieee80211_rx_ampdu;
struct ieee80211_superg;
struct ieee80211_frame;

struct ieee80211com {
	void			*ic_softc;	/* driver softc */
	const char		*ic_name;	/* usually device name */
	ieee80211_com_lock_t	ic_comlock;	/* state update lock */
	ieee80211_tx_lock_t	ic_txlock;	/* ic/vap TX lock */
	ieee80211_ff_lock_t	ic_fflock;	/* stageq/ni_tx_superg lock */
	LIST_ENTRY(ieee80211com)   ic_next;	/* on global list */
	TAILQ_HEAD(, ieee80211vap) ic_vaps;	/* list of vap instances */
	int			ic_headroom;	/* driver tx headroom needs */
	enum ieee80211_phytype	ic_phytype;	/* XXX wrong for multi-mode */
	enum ieee80211_opmode	ic_opmode;	/* operation mode */
	struct callout		ic_inact;	/* inactivity processing */
	struct taskqueue	*ic_tq;		/* deferred state thread */
	struct task		ic_parent_task;	/* deferred parent processing */
	struct task		ic_promisc_task;/* deferred promisc update */
	struct task		ic_mcast_task;	/* deferred mcast update */
	struct task		ic_chan_task;	/* deferred channel change */
	struct task		ic_bmiss_task;	/* deferred beacon miss hndlr */
	struct task		ic_chw_task;	/* deferred HT CHW update */
	struct task		ic_wme_task;	/* deferred WME update */
	struct task		ic_restart_task; /* deferred device restart */

	counter_u64_t		ic_ierrors;	/* input errors */
	counter_u64_t		ic_oerrors;	/* output errors */

	uint32_t		ic_flags;	/* state flags */
	uint32_t		ic_flags_ext;	/* extended state flags */
	uint32_t		ic_flags_ht;	/* HT state flags */
	uint32_t		ic_flags_ven;	/* vendor state flags */
	uint32_t		ic_caps;	/* capabilities */
	uint32_t		ic_htcaps;	/* HT capabilities */
	uint32_t		ic_htextcaps;	/* HT extended capabilities */
	uint32_t		ic_cryptocaps;	/* crypto capabilities */
						/* set of mode capabilities */
	uint8_t			ic_modecaps[IEEE80211_MODE_BYTES];
	uint8_t			ic_promisc;	/* vap's needing promisc mode */
	uint8_t			ic_allmulti;	/* vap's needing all multicast*/
	uint8_t			ic_nrunning;	/* vap's marked running */
	uint8_t			ic_curmode;	/* current mode */
	uint8_t			ic_macaddr[IEEE80211_ADDR_LEN];
	uint16_t		ic_bintval;	/* beacon interval */
	uint16_t		ic_lintval;	/* listen interval */
	uint16_t		ic_holdover;	/* PM hold over duration */
	uint16_t		ic_txpowlimit;	/* global tx power limit */
	struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX];

	/*
	 * Channel state:
	 *
	 * ic_channels is the set of available channels for the device;
	 *    it is setup by the driver
	 * ic_nchans is the number of valid entries in ic_channels
	 * ic_chan_avail is a bit vector of these channels used to check
	 *    whether a channel is available w/o searching the channel table.
	 * ic_chan_active is a (potentially) constrained subset of
	 *    ic_chan_avail that reflects any mode setting or user-specified
	 *    limit on the set of channels to use/scan
	 * ic_curchan is the current channel the device is set to; it may
	 *    be different from ic_bsschan when we are off-channel scanning
	 *    or otherwise doing background work
	 * ic_bsschan is the channel selected for operation; it may
	 *    be undefined (IEEE80211_CHAN_ANYC)
	 * ic_prevchan is a cached ``previous channel'' used to optimize
	 *    lookups when switching back+forth between two channels
	 *    (e.g. for dynamic turbo)
	 */
	int			ic_nchans;	/* # entries in ic_channels */
	struct ieee80211_channel ic_channels[IEEE80211_CHAN_MAX];
	uint8_t			ic_chan_avail[IEEE80211_CHAN_BYTES];
	uint8_t			ic_chan_active[IEEE80211_CHAN_BYTES];
	uint8_t			ic_chan_scan[IEEE80211_CHAN_BYTES];
	struct ieee80211_channel *ic_curchan;	/* current channel */
	const struct ieee80211_rate_table *ic_rt; /* table for ic_curchan */
	struct ieee80211_channel *ic_bsschan;	/* bss channel */
	struct ieee80211_channel *ic_prevchan;	/* previous channel */
	struct ieee80211_regdomain ic_regdomain;/* regulatory data */
	struct ieee80211_appie	*ic_countryie;	/* calculated country ie */
	struct ieee80211_channel *ic_countryie_chan;

	/* 802.11h/DFS state */
	struct ieee80211_channel *ic_csa_newchan;/* channel for doing CSA */
	short			ic_csa_mode;	/* mode for doing CSA */
	short			ic_csa_count;	/* count for doing CSA */
	struct ieee80211_dfs_state ic_dfs;	/* DFS state */

	struct ieee80211_scan_state *ic_scan;	/* scan state */
	struct ieee80211_scan_methods *ic_scan_methods;	/* scan methods */
	int			ic_lastdata;	/* time of last data frame */
	int			ic_lastscan;	/* time last scan completed */

	/* NB: this is the union of all vap stations/neighbors */
	int			ic_max_keyix;	/* max h/w key index */
	struct ieee80211_node_table ic_sta;	/* stations/neighbors */
	struct ieee80211_ageq	ic_stageq;	/* frame staging queue */
	uint32_t		ic_hash_key;	/* random key for mac hash */

	/* XXX multi-bss: split out common/vap parts */
	struct ieee80211_wme_state ic_wme;	/* WME/WMM state */

	/* XXX multi-bss: can per-vap be done/make sense? */
	enum ieee80211_protmode	ic_protmode;	/* 802.11g protection mode */
	uint16_t		ic_nonerpsta;	/* # non-ERP stations */
	uint16_t		ic_longslotsta;	/* # long slot time stations */
	uint16_t		ic_sta_assoc;	/* stations associated */
	uint16_t		ic_ht_sta_assoc;/* HT stations associated */
	uint16_t		ic_ht40_sta_assoc;/* HT40 stations associated */
	uint8_t			ic_curhtprotmode;/* HTINFO bss state */
	enum ieee80211_protmode	ic_htprotmode;	/* HT protection mode */
	int			ic_lastnonerp;	/* last time non-ERP sta noted*/
	int			ic_lastnonht;	/* last time non-HT sta noted */
	uint8_t			ic_rxstream;    /* # RX streams */
	uint8_t			ic_txstream;    /* # TX streams */

	/* optional state for Atheros SuperG protocol extensions */
	struct ieee80211_superg	*ic_superg;

	/* radiotap handling */
	struct ieee80211_radiotap_header *ic_th;/* tx radiotap headers */
	void			*ic_txchan;	/* channel state in ic_th */
	struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */
	void			*ic_rxchan;	/* channel state in ic_rh */
	int			ic_montaps;	/* active monitor mode taps */

	/* virtual ap create/delete */
	struct ieee80211vap*	(*ic_vap_create)(struct ieee80211com *,
				    const char [IFNAMSIZ], int,
				    enum ieee80211_opmode, int,
				    const uint8_t [IEEE80211_ADDR_LEN],
				    const uint8_t [IEEE80211_ADDR_LEN]);
	void			(*ic_vap_delete)(struct ieee80211vap *);
	/* device specific ioctls */
	int			(*ic_ioctl)(struct ieee80211com *,
				    u_long, void *);
	/* start/stop device */
	void			(*ic_parent)(struct ieee80211com *);
	/* operating mode attachment */
	ieee80211vap_attach	ic_vattach[IEEE80211_OPMODE_MAX];
	/* return hardware/radio capabilities */
	void			(*ic_getradiocaps)(struct ieee80211com *,
				    int, int *, struct ieee80211_channel []);
	/* check and/or prepare regdomain state change */
	int			(*ic_setregdomain)(struct ieee80211com *,
				    struct ieee80211_regdomain *,
				    int, struct ieee80211_channel []);

	int			(*ic_set_quiet)(struct ieee80211_node *,
				    u_int8_t *quiet_elm);

	/* regular transmit */
	int			(*ic_transmit)(struct ieee80211com *,
				    struct mbuf *);
	/* send/recv 802.11 management frame */
	int			(*ic_send_mgmt)(struct ieee80211_node *,
				     int, int);
	/* send raw 802.11 frame */
	int			(*ic_raw_xmit)(struct ieee80211_node *,
				    struct mbuf *,
				    const struct ieee80211_bpf_params *);
	/* update device state for 802.11 slot time change */
	void			(*ic_updateslot)(struct ieee80211com *);
	/* handle multicast state changes */
	void			(*ic_update_mcast)(struct ieee80211com *);
	/* handle promiscuous mode changes */
	void			(*ic_update_promisc)(struct ieee80211com *);
	/* new station association callback/notification */
	void			(*ic_newassoc)(struct ieee80211_node *, int);
	/* TDMA update notification */
	void			(*ic_tdma_update)(struct ieee80211_node *,
				    const struct ieee80211_tdma_param *, int);
	/* node state management */
	struct ieee80211_node*	(*ic_node_alloc)(struct ieee80211vap *,
				    const uint8_t [IEEE80211_ADDR_LEN]);
	void			(*ic_node_free)(struct ieee80211_node *);
	void			(*ic_node_cleanup)(struct ieee80211_node *);
	void			(*ic_node_age)(struct ieee80211_node *);
	void			(*ic_node_drain)(struct ieee80211_node *);
	int8_t			(*ic_node_getrssi)(const struct ieee80211_node*);
	void			(*ic_node_getsignal)(const struct ieee80211_node*,
				    int8_t *, int8_t *);
	void			(*ic_node_getmimoinfo)(
				    const struct ieee80211_node*,
				    struct ieee80211_mimo_info *);
	/* scanning support */
	void			(*ic_scan_start)(struct ieee80211com *);
	void			(*ic_scan_end)(struct ieee80211com *);
	void			(*ic_set_channel)(struct ieee80211com *);
	void			(*ic_scan_curchan)(struct ieee80211_scan_state *,
				    unsigned long);
	void			(*ic_scan_mindwell)(struct ieee80211_scan_state *);

	/*
	 * 802.11n ADDBA support.  A simple/generic implementation
	 * of A-MPDU tx aggregation is provided; the driver may
	 * override these methods to provide their own support.
	 * A-MPDU rx re-ordering happens automatically if the
	 * driver passes out-of-order frames to ieee80211_input
	 * from an assocated HT station.
	 */
	int			(*ic_recv_action)(struct ieee80211_node *,
				    const struct ieee80211_frame *,
				    const uint8_t *frm, const uint8_t *efrm);
	int			(*ic_send_action)(struct ieee80211_node *,
				    int category, int action, void *);
	/* check if A-MPDU should be enabled this station+ac */
	int			(*ic_ampdu_enable)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *);
	/* start/stop doing A-MPDU tx aggregation for a station */
	int			(*ic_addba_request)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *,
				    int dialogtoken, int baparamset,
				    int batimeout);
	int			(*ic_addba_response)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *,
				    int status, int baparamset, int batimeout);
	void			(*ic_addba_stop)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *);
	void			(*ic_addba_response_timeout)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *);
	/* BAR response received */
	void			(*ic_bar_response)(struct ieee80211_node *,
				    struct ieee80211_tx_ampdu *, int status);
	/* start/stop doing A-MPDU rx processing for a station */
	int			(*ic_ampdu_rx_start)(struct ieee80211_node *,
				    struct ieee80211_rx_ampdu *, int baparamset,
				    int batimeout, int baseqctl);
	void			(*ic_ampdu_rx_stop)(struct ieee80211_node *,
				    struct ieee80211_rx_ampdu *);

	/* The channel width has changed (20<->2040) */
	void			(*ic_update_chw)(struct ieee80211com *);

	uint64_t		ic_spare[7];
};

struct ieee80211_aclator;
struct ieee80211_tdma_state;
struct ieee80211_mesh_state;
struct ieee80211_hwmp_state;

struct ieee80211vap {
	struct ifmedia		iv_media;	/* interface media config */
	struct ifnet		*iv_ifp;	/* associated device */
	struct bpf_if		*iv_rawbpf;	/* packet filter structure */
	struct sysctl_ctx_list	*iv_sysctl;	/* dynamic sysctl context */
	struct sysctl_oid	*iv_oid;	/* net.wlan.X sysctl oid */

	TAILQ_ENTRY(ieee80211vap) iv_next;	/* list of vap instances */
	struct ieee80211com	*iv_ic;		/* back ptr to common state */
	/* MAC address: ifp or ic */
	uint8_t			iv_myaddr[IEEE80211_ADDR_LEN];
	uint32_t		iv_debug;	/* debug msg flags */
	struct ieee80211_stats	iv_stats;	/* statistics */

	uint32_t		iv_flags;	/* state flags */
	uint32_t		iv_flags_ext;	/* extended state flags */
	uint32_t		iv_flags_ht;	/* HT state flags */
	uint32_t		iv_flags_ven;	/* vendor state flags */
	uint32_t		iv_ifflags;	/* ifnet flags */
	uint32_t		iv_caps;	/* capabilities */
	uint32_t		iv_htcaps;	/* HT capabilities */
	uint32_t		iv_htextcaps;	/* HT extended capabilities */
	enum ieee80211_opmode	iv_opmode;	/* operation mode */
	enum ieee80211_state	iv_state;	/* state machine state */
	enum ieee80211_state	iv_nstate;	/* pending state */
	int			iv_nstate_arg;	/* pending state arg */
	struct task		iv_nstate_task;	/* deferred state processing */
	struct task		iv_swbmiss_task;/* deferred iv_bmiss call */
	struct callout		iv_mgtsend;	/* mgmt frame response timer */
						/* inactivity timer settings */
	int			iv_inact_init;	/* setting for new station */
	int			iv_inact_auth;	/* auth but not assoc setting */
	int			iv_inact_run;	/* authorized setting */
	int			iv_inact_probe;	/* inactive probe time */

	int			iv_des_nssid;	/* # desired ssids */
	struct ieee80211_scan_ssid iv_des_ssid[1];/* desired ssid table */
	uint8_t			iv_des_bssid[IEEE80211_ADDR_LEN];
	struct ieee80211_channel *iv_des_chan;	/* desired channel */
	uint16_t		iv_des_mode;	/* desired mode */
	int			iv_nicknamelen;	/* XXX junk */
	uint8_t			iv_nickname[IEEE80211_NWID_LEN];
	u_int			iv_bgscanidle;	/* bg scan idle threshold */
	u_int			iv_bgscanintvl;	/* bg scan min interval */
	u_int			iv_scanvalid;	/* scan cache valid threshold */
	u_int			iv_scanreq_duration;
	u_int			iv_scanreq_mindwell;
	u_int			iv_scanreq_maxdwell;
	uint16_t		iv_scanreq_flags;/* held scan request params */
	uint8_t			iv_scanreq_nssid;
	struct ieee80211_scan_ssid iv_scanreq_ssid[IEEE80211_SCAN_MAX_SSID];
	/* sta-mode roaming state */
	enum ieee80211_roamingmode iv_roaming;	/* roaming mode */
	struct ieee80211_roamparam iv_roamparms[IEEE80211_MODE_MAX];

	uint8_t			iv_bmissthreshold;
	uint8_t			iv_bmiss_count;	/* current beacon miss count */
	int			iv_bmiss_max;	/* max bmiss before scan */
	uint16_t		iv_swbmiss_count;/* beacons in last period */
	uint16_t		iv_swbmiss_period;/* s/w bmiss period */
	struct callout		iv_swbmiss;	/* s/w beacon miss timer */

	int			iv_ampdu_rxmax;	/* A-MPDU rx limit (bytes) */
	int			iv_ampdu_density;/* A-MPDU density */
	int			iv_ampdu_limit;	/* A-MPDU tx limit (bytes) */
	int			iv_amsdu_limit;	/* A-MSDU tx limit (bytes) */
	u_int			iv_ampdu_mintraffic[WME_NUM_AC];

	struct ieee80211_beacon_offsets iv_bcn_off;
	uint32_t		*iv_aid_bitmap;	/* association id map */
	uint16_t		iv_max_aid;
	uint16_t		iv_sta_assoc;	/* stations associated */
	uint16_t		iv_ps_sta;	/* stations in power save */
	uint16_t		iv_ps_pending;	/* ps sta's w/ pending frames */
	uint16_t		iv_txseq;	/* mcast xmit seq# space */
	uint16_t		iv_tim_len;	/* ic_tim_bitmap size (bytes) */
	uint8_t			*iv_tim_bitmap;	/* power-save stations w/ data*/
	uint8_t			iv_dtim_period;	/* DTIM period */
	uint8_t			iv_dtim_count;	/* DTIM count from last bcn */
						/* set/unset aid pwrsav state */
	uint8_t			iv_quiet;	/* Quiet Element */
	uint8_t			iv_quiet_count;	/* constant count for Quiet Element */
	uint8_t			iv_quiet_count_value;	/* variable count for Quiet Element */
	uint8_t			iv_quiet_period;	/* period for Quiet Element */
	uint16_t		iv_quiet_duration;	/* duration for Quiet Element */
	uint16_t		iv_quiet_offset;	/* offset for Quiet Element */
	int			iv_csa_count;	/* count for doing CSA */

	struct ieee80211_node	*iv_bss;	/* information for this node */
	struct ieee80211_txparam iv_txparms[IEEE80211_MODE_MAX];
	uint16_t		iv_rtsthreshold;
	uint16_t		iv_fragthreshold;
	int			iv_inact_timer;	/* inactivity timer wait */
	/* application-specified IE's to attach to mgt frames */
	struct ieee80211_appie	*iv_appie_beacon;
	struct ieee80211_appie	*iv_appie_probereq;
	struct ieee80211_appie	*iv_appie_proberesp;
	struct ieee80211_appie	*iv_appie_assocreq;
	struct ieee80211_appie	*iv_appie_assocresp;
	struct ieee80211_appie	*iv_appie_wpa;
	uint8_t			*iv_wpa_ie;
	uint8_t			*iv_rsn_ie;
	uint16_t		iv_max_keyix;	/* max h/w key index */
	ieee80211_keyix		iv_def_txkey;	/* default/group tx key index */
	struct ieee80211_key	iv_nw_keys[IEEE80211_WEP_NKID];
	int			(*iv_key_alloc)(struct ieee80211vap *,
				    struct ieee80211_key *,
				    ieee80211_keyix *, ieee80211_keyix *);
	int			(*iv_key_delete)(struct ieee80211vap *, 
				    const struct ieee80211_key *);
	int			(*iv_key_set)(struct ieee80211vap *,
				    const struct ieee80211_key *);
	void			(*iv_key_update_begin)(struct ieee80211vap *);
	void			(*iv_key_update_end)(struct ieee80211vap *);

	const struct ieee80211_authenticator *iv_auth; /* authenticator glue */
	void			*iv_ec;		/* private auth state */

	const struct ieee80211_aclator *iv_acl;	/* acl glue */
	void			*iv_as;		/* private aclator state */

	const struct ieee80211_ratectl *iv_rate;
	void			*iv_rs;		/* private ratectl state */

	struct ieee80211_tdma_state *iv_tdma;	/* tdma state */
	struct ieee80211_mesh_state *iv_mesh;	/* MBSS state */
	struct ieee80211_hwmp_state *iv_hwmp;	/* HWMP state */

	/* operate-mode detach hook */
	void			(*iv_opdetach)(struct ieee80211vap *);
	/* receive processing */
	int			(*iv_input)(struct ieee80211_node *,
				    struct mbuf *,
				    const struct ieee80211_rx_stats *,
				    int, int);
	void			(*iv_recv_mgmt)(struct ieee80211_node *,
				    struct mbuf *, int,
				    const struct ieee80211_rx_stats *,
				    int, int);
	void			(*iv_recv_ctl)(struct ieee80211_node *,
				    struct mbuf *, int);
	void			(*iv_deliver_data)(struct ieee80211vap *,
				    struct ieee80211_node *, struct mbuf *);
#if 0
	/* send processing */
	int			(*iv_send_mgmt)(struct ieee80211_node *,
				     int, int);
#endif
	/* beacon miss processing */
	void			(*iv_bmiss)(struct ieee80211vap *);
	/* reset device state after 802.11 parameter/state change */
	int			(*iv_reset)(struct ieee80211vap *, u_long);
	/* [schedule] beacon frame update */
	void			(*iv_update_beacon)(struct ieee80211vap *, int);
	/* power save handling */
	void			(*iv_update_ps)(struct ieee80211vap *, int);
	int			(*iv_set_tim)(struct ieee80211_node *, int);
	void			(*iv_node_ps)(struct ieee80211_node *, int);
	void			(*iv_sta_ps)(struct ieee80211vap *, int);
	void			(*iv_recv_pspoll)(struct ieee80211_node *,
				    struct mbuf *);

	/* state machine processing */
	int			(*iv_newstate)(struct ieee80211vap *,
				    enum ieee80211_state, int);
	/* 802.3 output method for raw frame xmit */
	int			(*iv_output)(struct ifnet *, struct mbuf *,
				    const struct sockaddr *, struct route *);
	uint64_t		iv_spare[6];
};
MALLOC_DECLARE(M_80211_VAP);

#define	IEEE80211_ADDR_EQ(a1,a2)	(memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0)
#define	IEEE80211_ADDR_COPY(dst,src)	memcpy(dst,src,IEEE80211_ADDR_LEN)

/* ic_flags/iv_flags */
#define	IEEE80211_F_TURBOP	0x00000001	/* CONF: ATH Turbo enabled*/
#define	IEEE80211_F_COMP	0x00000002	/* CONF: ATH comp enabled */
#define	IEEE80211_F_FF		0x00000004	/* CONF: ATH FF enabled */
#define	IEEE80211_F_BURST	0x00000008	/* CONF: bursting enabled */
/* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */
#define	IEEE80211_F_PRIVACY	0x00000010	/* CONF: privacy enabled */
#define	IEEE80211_F_PUREG	0x00000020	/* CONF: 11g w/o 11b sta's */
#define	IEEE80211_F_SCAN	0x00000080	/* STATUS: scanning */
#define	IEEE80211_F_ASCAN	0x00000100	/* STATUS: active scan */
#define	IEEE80211_F_SIBSS	0x00000200	/* STATUS: start IBSS */
/* NB: this is intentionally setup to be IEEE80211_CAPINFO_SHORT_SLOTTIME */
#define	IEEE80211_F_SHSLOT	0x00000400	/* STATUS: use short slot time*/
#define	IEEE80211_F_PMGTON	0x00000800	/* CONF: Power mgmt enable */
#define	IEEE80211_F_DESBSSID	0x00001000	/* CONF: des_bssid is set */
#define	IEEE80211_F_WME		0x00002000	/* CONF: enable WME use */
#define	IEEE80211_F_BGSCAN	0x00004000	/* CONF: bg scan enabled (???)*/
#define	IEEE80211_F_SWRETRY	0x00008000	/* CONF: sw tx retry enabled */
#define IEEE80211_F_TXPOW_FIXED	0x00010000	/* TX Power: fixed rate */
#define	IEEE80211_F_IBSSON	0x00020000	/* CONF: IBSS creation enable */
#define	IEEE80211_F_SHPREAMBLE	0x00040000	/* STATUS: use short preamble */
#define	IEEE80211_F_DATAPAD	0x00080000	/* CONF: do alignment pad */
#define	IEEE80211_F_USEPROT	0x00100000	/* STATUS: protection enabled */
#define	IEEE80211_F_USEBARKER	0x00200000	/* STATUS: use barker preamble*/
#define	IEEE80211_F_CSAPENDING	0x00400000	/* STATUS: chan switch pending*/
#define	IEEE80211_F_WPA1	0x00800000	/* CONF: WPA enabled */
#define	IEEE80211_F_WPA2	0x01000000	/* CONF: WPA2 enabled */
#define	IEEE80211_F_WPA		0x01800000	/* CONF: WPA/WPA2 enabled */
#define	IEEE80211_F_DROPUNENC	0x02000000	/* CONF: drop unencrypted */
#define	IEEE80211_F_COUNTERM	0x04000000	/* CONF: TKIP countermeasures */
#define	IEEE80211_F_HIDESSID	0x08000000	/* CONF: hide SSID in beacon */
#define	IEEE80211_F_NOBRIDGE	0x10000000	/* CONF: dis. internal bridge */
#define	IEEE80211_F_PCF		0x20000000	/* CONF: PCF enabled */
#define	IEEE80211_F_DOTH	0x40000000	/* CONF: 11h enabled */
#define	IEEE80211_F_DWDS	0x80000000	/* CONF: Dynamic WDS enabled */

#define	IEEE80211_F_BITS \
	"\20\1TURBOP\2COMP\3FF\4BURST\5PRIVACY\6PUREG\10SCAN\11ASCAN\12SIBSS" \
	"\13SHSLOT\14PMGTON\15DESBSSID\16WME\17BGSCAN\20SWRETRY\21TXPOW_FIXED" \
	"\22IBSSON\23SHPREAMBLE\24DATAPAD\25USEPROT\26USERBARKER\27CSAPENDING" \
	"\30WPA1\31WPA2\32DROPUNENC\33COUNTERM\34HIDESSID\35NOBRIDG\36PCF" \
	"\37DOTH\40DWDS"

/* Atheros protocol-specific flags */
#define	IEEE80211_F_ATHEROS \
	(IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP)
/* Check if an Atheros capability was negotiated for use */
#define	IEEE80211_ATH_CAP(vap, ni, bit) \
	((vap)->iv_flags & (ni)->ni_ath_flags & (bit))

/* ic_flags_ext/iv_flags_ext */
#define	IEEE80211_FEXT_INACT	 0x00000002	/* CONF: sta inact handling */
#define	IEEE80211_FEXT_SCANWAIT	 0x00000004	/* STATUS: awaiting scan */
/* 0x00000006 reserved */
#define	IEEE80211_FEXT_BGSCAN	 0x00000008	/* STATUS: complete bgscan */
#define	IEEE80211_FEXT_WPS	 0x00000010	/* CONF: WPS enabled */
#define	IEEE80211_FEXT_TSN 	 0x00000020	/* CONF: TSN enabled */
#define	IEEE80211_FEXT_SCANREQ	 0x00000040	/* STATUS: scan req params */
#define	IEEE80211_FEXT_RESUME	 0x00000080	/* STATUS: start on resume */
#define	IEEE80211_FEXT_4ADDR	 0x00000100	/* CONF: apply 4-addr encap */
#define	IEEE80211_FEXT_NONERP_PR 0x00000200	/* STATUS: non-ERP sta present*/
#define	IEEE80211_FEXT_SWBMISS	 0x00000400	/* CONF: do bmiss in s/w */
#define	IEEE80211_FEXT_DFS	 0x00000800	/* CONF: DFS enabled */
#define	IEEE80211_FEXT_DOTD	 0x00001000	/* CONF: 11d enabled */
#define	IEEE80211_FEXT_STATEWAIT 0x00002000	/* STATUS: awaiting state chg */
#define	IEEE80211_FEXT_REINIT	 0x00004000	/* STATUS: INIT state first */
#define	IEEE80211_FEXT_BPF	 0x00008000	/* STATUS: BPF tap present */
/* NB: immutable: should be set only when creating a vap */
#define	IEEE80211_FEXT_WDSLEGACY 0x00010000	/* CONF: legacy WDS operation */
#define	IEEE80211_FEXT_PROBECHAN 0x00020000	/* CONF: probe passive channel*/
#define	IEEE80211_FEXT_UNIQMAC	 0x00040000	/* CONF: user or computed mac */
#define	IEEE80211_FEXT_SCAN_OFFLOAD	0x00080000	/* CONF: scan is fully offloaded */

#define	IEEE80211_FEXT_BITS \
	"\20\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
	"\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \
	"\20BPF\21WDSLEGACY\22PROBECHAN\23UNIQMAC\24SCAN_OFFLOAD"

/* ic_flags_ht/iv_flags_ht */
#define	IEEE80211_FHT_NONHT_PR	 0x00000001	/* STATUS: non-HT sta present */
#define	IEEE80211_FHT_GF  	 0x00040000	/* CONF: Greenfield enabled */
#define	IEEE80211_FHT_HT	 0x00080000	/* CONF: HT supported */
#define	IEEE80211_FHT_AMPDU_TX	 0x00100000	/* CONF: A-MPDU tx supported */
#define	IEEE80211_FHT_AMPDU_RX	 0x00200000	/* CONF: A-MPDU rx supported */
#define	IEEE80211_FHT_AMSDU_TX	 0x00400000	/* CONF: A-MSDU tx supported */
#define	IEEE80211_FHT_AMSDU_RX	 0x00800000	/* CONF: A-MSDU rx supported */
#define	IEEE80211_FHT_USEHT40	 0x01000000	/* CONF: 20/40 use enabled */
#define	IEEE80211_FHT_PUREN	 0x02000000	/* CONF: 11n w/o legacy sta's */
#define	IEEE80211_FHT_SHORTGI20	 0x04000000	/* CONF: short GI in HT20 */
#define	IEEE80211_FHT_SHORTGI40	 0x08000000	/* CONF: short GI in HT40 */
#define	IEEE80211_FHT_HTCOMPAT 	 0x10000000	/* CONF: HT vendor OUI's */
#define	IEEE80211_FHT_RIFS  	 0x20000000	/* CONF: RIFS enabled */
#define	IEEE80211_FHT_STBC_TX 	 0x40000000	/* CONF: STBC tx enabled */
#define	IEEE80211_FHT_STBC_RX 	 0x80000000	/* CONF: STBC rx enabled */

#define	IEEE80211_FHT_BITS \
	"\20\1NONHT_PR" \
	"\23GF\24HT\25AMPDU_TX\26AMPDU_TX" \
	"\27AMSDU_TX\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40" \
	"\35HTCOMPAT\36RIFS\37STBC_TX\40STBC_RX"

#define	IEEE80211_FVEN_BITS	"\20"

/* ic_caps/iv_caps: device driver capabilities */
/* 0x2e available */
#define	IEEE80211_C_STA		0x00000001	/* CAPABILITY: STA available */
#define	IEEE80211_C_8023ENCAP	0x00000002	/* CAPABILITY: 802.3 encap */
#define	IEEE80211_C_FF		0x00000040	/* CAPABILITY: ATH FF avail */
#define	IEEE80211_C_TURBOP	0x00000080	/* CAPABILITY: ATH Turbo avail*/
#define	IEEE80211_C_IBSS	0x00000100	/* CAPABILITY: IBSS available */
#define	IEEE80211_C_PMGT	0x00000200	/* CAPABILITY: Power mgmt */
#define	IEEE80211_C_HOSTAP	0x00000400	/* CAPABILITY: HOSTAP avail */
#define	IEEE80211_C_AHDEMO	0x00000800	/* CAPABILITY: Old Adhoc Demo */
#define	IEEE80211_C_SWRETRY	0x00001000	/* CAPABILITY: sw tx retry */
#define	IEEE80211_C_TXPMGT	0x00002000	/* CAPABILITY: tx power mgmt */
#define	IEEE80211_C_SHSLOT	0x00004000	/* CAPABILITY: short slottime */
#define	IEEE80211_C_SHPREAMBLE	0x00008000	/* CAPABILITY: short preamble */
#define	IEEE80211_C_MONITOR	0x00010000	/* CAPABILITY: monitor mode */
#define	IEEE80211_C_DFS		0x00020000	/* CAPABILITY: DFS/radar avail*/
#define	IEEE80211_C_MBSS	0x00040000	/* CAPABILITY: MBSS available */
#define	IEEE80211_C_SWSLEEP	0x00080000	/* CAPABILITY: do sleep here */
#define	IEEE80211_C_SWAMSDUTX	0x00100000	/* CAPABILITY: software A-MSDU TX */
/* 0x7c0000 available */
#define	IEEE80211_C_WPA1	0x00800000	/* CAPABILITY: WPA1 avail */
#define	IEEE80211_C_WPA2	0x01000000	/* CAPABILITY: WPA2 avail */
#define	IEEE80211_C_WPA		0x01800000	/* CAPABILITY: WPA1+WPA2 avail*/
#define	IEEE80211_C_BURST	0x02000000	/* CAPABILITY: frame bursting */
#define	IEEE80211_C_WME		0x04000000	/* CAPABILITY: WME avail */
#define	IEEE80211_C_WDS		0x08000000	/* CAPABILITY: 4-addr support */
/* 0x10000000 reserved */
#define	IEEE80211_C_BGSCAN	0x20000000	/* CAPABILITY: bg scanning */
#define	IEEE80211_C_TXFRAG	0x40000000	/* CAPABILITY: tx fragments */
#define	IEEE80211_C_TDMA	0x80000000	/* CAPABILITY: TDMA avail */
/* XXX protection/barker? */

#define	IEEE80211_C_OPMODE \
	(IEEE80211_C_STA | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | \
	 IEEE80211_C_AHDEMO | IEEE80211_C_MONITOR | IEEE80211_C_WDS | \
	 IEEE80211_C_TDMA | IEEE80211_C_MBSS)

#define	IEEE80211_C_BITS \
	"\20\1STA\002803ENCAP\7FF\10TURBOP\11IBSS\12PMGT" \
	"\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
	"\21MONITOR\22DFS\23MBSS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
	"\37TXFRAG\40TDMA"

/*
 * ic_htcaps/iv_htcaps: HT-specific device/driver capabilities
 *
 * NB: the low 16-bits are the 802.11 definitions, the upper
 *     16-bits are used to define s/w/driver capabilities.
 */
#define	IEEE80211_HTC_AMPDU	0x00010000	/* CAPABILITY: A-MPDU tx */
#define	IEEE80211_HTC_AMSDU	0x00020000	/* CAPABILITY: A-MSDU tx */
/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */
#define	IEEE80211_HTC_HT	0x00040000	/* CAPABILITY: HT operation */
#define	IEEE80211_HTC_SMPS	0x00080000	/* CAPABILITY: MIMO power save*/
#define	IEEE80211_HTC_RIFS	0x00100000	/* CAPABILITY: RIFS support */
#define	IEEE80211_HTC_RXUNEQUAL	0x00200000	/* CAPABILITY: RX unequal MCS */
#define	IEEE80211_HTC_RXMCS32	0x00400000	/* CAPABILITY: MCS32 support */
#define	IEEE80211_HTC_TXUNEQUAL	0x00800000	/* CAPABILITY: TX unequal MCS */
#define	IEEE80211_HTC_TXMCS32	0x01000000	/* CAPABILITY: MCS32 suport */

#define	IEEE80211_C_HTCAP_BITS \
	"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
	"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"

int	ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
void	ieee80211_ifattach(struct ieee80211com *);
void	ieee80211_ifdetach(struct ieee80211com *);
int	ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *,
		const char name[IFNAMSIZ], int unit,
		enum ieee80211_opmode opmode, int flags,
		const uint8_t bssid[IEEE80211_ADDR_LEN]);
int	ieee80211_vap_attach(struct ieee80211vap *,
		ifm_change_cb_t, ifm_stat_cb_t,
		const uint8_t macaddr[IEEE80211_ADDR_LEN]);
void	ieee80211_vap_detach(struct ieee80211vap *);
const struct ieee80211_rateset *ieee80211_get_suprates(struct ieee80211com *ic,
		const struct ieee80211_channel *);
void	ieee80211_announce(struct ieee80211com *);
void	ieee80211_announce_channels(struct ieee80211com *);
void	ieee80211_drain(struct ieee80211com *);
void	ieee80211_chan_init(struct ieee80211com *);
struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]);
struct ieee80211com *ieee80211_find_com(const char *name);
typedef void ieee80211_com_iter_func(void *, struct ieee80211com *);
void	ieee80211_iterate_coms(ieee80211_com_iter_func *, void *);
int	ieee80211_media_change(struct ifnet *);
void	ieee80211_media_status(struct ifnet *, struct ifmediareq *);
int	ieee80211_ioctl(struct ifnet *, u_long, caddr_t);
int	ieee80211_rate2media(struct ieee80211com *, int,
		enum ieee80211_phymode);
int	ieee80211_media2rate(int);
int	ieee80211_mhz2ieee(u_int, u_int);
int	ieee80211_chan2ieee(struct ieee80211com *,
		const struct ieee80211_channel *);
u_int	ieee80211_ieee2mhz(u_int, u_int);
int	ieee80211_add_channel(struct ieee80211_channel[], int, int *,
	    uint8_t, uint16_t, int8_t, uint32_t, const uint8_t[]);
int	ieee80211_add_channel_ht40(struct ieee80211_channel[], int, int *,
	    uint8_t, int8_t, uint32_t);
int	ieee80211_add_channel_list_2ghz(struct ieee80211_channel[], int, int *,
	    const uint8_t[], int, const uint8_t[], int);
int	ieee80211_add_channel_list_5ghz(struct ieee80211_channel[], int, int *,
	    const uint8_t[], int, const uint8_t[], int);
struct ieee80211_channel *ieee80211_find_channel(struct ieee80211com *,
		int freq, int flags);
struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *,
		int ieee, int flags);
struct ieee80211_channel *ieee80211_lookup_channel_rxstatus(struct ieee80211vap *,
		const struct ieee80211_rx_stats *);
int	ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *);
uint32_t ieee80211_mac_hash(const struct ieee80211com *,
		const uint8_t addr[IEEE80211_ADDR_LEN]);
char	ieee80211_channel_type_char(const struct ieee80211_channel *c);

void	ieee80211_radiotap_attach(struct ieee80211com *,
	    struct ieee80211_radiotap_header *th, int tlen,
		uint32_t tx_radiotap,
	    struct ieee80211_radiotap_header *rh, int rlen,
		uint32_t rx_radiotap);
void	ieee80211_radiotap_attachv(struct ieee80211com *,
	    struct ieee80211_radiotap_header *th,
	    int tlen, int n_tx_v, uint32_t tx_radiotap,
	    struct ieee80211_radiotap_header *rh,
	    int rlen, int n_rx_v, uint32_t rx_radiotap);
void	ieee80211_radiotap_detach(struct ieee80211com *);
void	ieee80211_radiotap_vattach(struct ieee80211vap *);
void	ieee80211_radiotap_vdetach(struct ieee80211vap *);
void	ieee80211_radiotap_chan_change(struct ieee80211com *);
void	ieee80211_radiotap_tx(struct ieee80211vap *, struct mbuf *);
void	ieee80211_radiotap_rx(struct ieee80211vap *, struct mbuf *);
void	ieee80211_radiotap_rx_all(struct ieee80211com *, struct mbuf *);

static __inline int
ieee80211_radiotap_active(const struct ieee80211com *ic)
{
	return (ic->ic_flags_ext & IEEE80211_FEXT_BPF) != 0;
}

static __inline int
ieee80211_radiotap_active_vap(const struct ieee80211vap *vap)
{
	return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) ||
	    vap->iv_ic->ic_montaps != 0;
}

/*
 * Enqueue a task on the state thread.
 */
static __inline void
ieee80211_runtask(struct ieee80211com *ic, struct task *task)
{
	taskqueue_enqueue(ic->ic_tq, task);
}

/*
 * Wait for a queued task to complete.
 */
static __inline void
ieee80211_draintask(struct ieee80211com *ic, struct task *task)
{
	taskqueue_drain(ic->ic_tq, task);
}

/* 
 * Key update synchronization methods.  XXX should not be visible.
 */
static __inline void
ieee80211_key_update_begin(struct ieee80211vap *vap)
{
	vap->iv_key_update_begin(vap);
}
static __inline void
ieee80211_key_update_end(struct ieee80211vap *vap)
{
	vap->iv_key_update_end(vap);
}

/*
 * XXX these need to be here for IEEE80211_F_DATAPAD
 */

/*
 * Return the space occupied by the 802.11 header and any
 * padding required by the driver.  This works for a
 * management or data frame.
 */
static __inline int
ieee80211_hdrspace(struct ieee80211com *ic, const void *data)
{
	int size = ieee80211_hdrsize(data);
	if (ic->ic_flags & IEEE80211_F_DATAPAD)
		size = roundup(size, sizeof(uint32_t));
	return size;
}

/*
 * Like ieee80211_hdrspace, but handles any type of frame.
 */
static __inline int
ieee80211_anyhdrspace(struct ieee80211com *ic, const void *data)
{
	int size = ieee80211_anyhdrsize(data);
	if (ic->ic_flags & IEEE80211_F_DATAPAD)
		size = roundup(size, sizeof(uint32_t));
	return size;
}

/*
 * Notify a vap that beacon state has been updated.
 */
static __inline void
ieee80211_beacon_notify(struct ieee80211vap *vap, int what)
{
	if (vap->iv_state == IEEE80211_S_RUN)
		vap->iv_update_beacon(vap, what);
}

/*
 * Calculate HT channel promotion flags for a channel.
 * XXX belongs in ieee80211_ht.h but needs IEEE80211_FHT_*
 */
static __inline int
ieee80211_htchanflags(const struct ieee80211_channel *c)
{
	return IEEE80211_IS_CHAN_HT40(c) ?
	    IEEE80211_FHT_HT | IEEE80211_FHT_USEHT40 :
	    IEEE80211_IS_CHAN_HT(c) ?  IEEE80211_FHT_HT : 0;
}

/*
 * Fetch the current TX power (cap) for the given node.
 *
 * This includes the node and ic/vap TX power limit as needed,
 * but it doesn't take into account any per-rate limit.
 */
static __inline uint16_t
ieee80211_get_node_txpower(struct ieee80211_node *ni)
{
	struct ieee80211com *ic = ni->ni_ic;
	uint16_t txpower;

	txpower = ni->ni_txpower;
	txpower = MIN(txpower, ic->ic_txpowlimit);
	if (ic->ic_curchan != NULL) {
		txpower = MIN(txpower, 2 * ic->ic_curchan->ic_maxregpower);
		txpower = MIN(txpower, ic->ic_curchan->ic_maxpower);
	}

	return (txpower);
}

/*
 * Debugging facilities compiled in when IEEE80211_DEBUG is defined.
 *
 * The intent is that any problem in the net80211 layer can be
 * diagnosed by inspecting the statistics (dumped by the wlanstats
 * program) and/or the msgs generated by net80211.  Messages are
 * broken into functional classes and can be controlled with the
 * wlandebug program.  Certain of these msg groups are for facilities
 * that are no longer part of net80211 (e.g. IEEE80211_MSG_DOT1XSM).
 */
#define	IEEE80211_MSG_11N	0x80000000	/* 11n mode debug */
#define	IEEE80211_MSG_DEBUG	0x40000000	/* IFF_DEBUG equivalent */
#define	IEEE80211_MSG_DUMPPKTS	0x20000000	/* IFF_LINK2 equivalant */
#define	IEEE80211_MSG_CRYPTO	0x10000000	/* crypto work */
#define	IEEE80211_MSG_INPUT	0x08000000	/* input handling */
#define	IEEE80211_MSG_XRATE	0x04000000	/* rate set handling */
#define	IEEE80211_MSG_ELEMID	0x02000000	/* element id parsing */
#define	IEEE80211_MSG_NODE	0x01000000	/* node handling */
#define	IEEE80211_MSG_ASSOC	0x00800000	/* association handling */
#define	IEEE80211_MSG_AUTH	0x00400000	/* authentication handling */
#define	IEEE80211_MSG_SCAN	0x00200000	/* scanning */
#define	IEEE80211_MSG_OUTPUT	0x00100000	/* output handling */
#define	IEEE80211_MSG_STATE	0x00080000	/* state machine */
#define	IEEE80211_MSG_POWER	0x00040000	/* power save handling */
#define	IEEE80211_MSG_HWMP	0x00020000	/* hybrid mesh protocol */
#define	IEEE80211_MSG_DOT1XSM	0x00010000	/* 802.1x state machine */
#define	IEEE80211_MSG_RADIUS	0x00008000	/* 802.1x radius client */
#define	IEEE80211_MSG_RADDUMP	0x00004000	/* dump 802.1x radius packets */
#define	IEEE80211_MSG_MESH	0x00002000	/* mesh networking */
#define	IEEE80211_MSG_WPA	0x00001000	/* WPA/RSN protocol */
#define	IEEE80211_MSG_ACL	0x00000800	/* ACL handling */
#define	IEEE80211_MSG_WME	0x00000400	/* WME protocol */
#define	IEEE80211_MSG_SUPERG	0x00000200	/* Atheros SuperG protocol */
#define	IEEE80211_MSG_DOTH	0x00000100	/* 802.11h support */
#define	IEEE80211_MSG_INACT	0x00000080	/* inactivity handling */
#define	IEEE80211_MSG_ROAM	0x00000040	/* sta-mode roaming */
#define	IEEE80211_MSG_RATECTL	0x00000020	/* tx rate control */
#define	IEEE80211_MSG_ACTION	0x00000010	/* action frame handling */
#define	IEEE80211_MSG_WDS	0x00000008	/* WDS handling */
#define	IEEE80211_MSG_IOCTL	0x00000004	/* ioctl handling */
#define	IEEE80211_MSG_TDMA	0x00000002	/* TDMA handling */

#define	IEEE80211_MSG_ANY	0xffffffff	/* anything */

#define	IEEE80211_MSG_BITS \
	"\20\2TDMA\3IOCTL\4WDS\5ACTION\6RATECTL\7ROAM\10INACT\11DOTH\12SUPERG" \
	"\13WME\14ACL\15WPA\16RADKEYS\17RADDUMP\20RADIUS\21DOT1XSM\22HWMP" \
	"\23POWER\24STATE\25OUTPUT\26SCAN\27AUTH\30ASSOC\31NODE\32ELEMID" \
	"\33XRATE\34INPUT\35CRYPTO\36DUPMPKTS\37DEBUG\04011N"

#ifdef IEEE80211_DEBUG
#define	ieee80211_msg(_vap, _m)	((_vap)->iv_debug & (_m))
#define	IEEE80211_DPRINTF(_vap, _m, _fmt, ...) do {			\
	if (ieee80211_msg(_vap, _m))					\
		ieee80211_note(_vap, _fmt, __VA_ARGS__);		\
} while (0)
#define	IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...) do {			\
	if (ieee80211_msg(_vap, _m))					\
		ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\
} while (0)
#define	IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...) do {		\
	if (ieee80211_msg(_vap, _m))					\
		ieee80211_note_mac(_vap, _mac, _fmt, __VA_ARGS__);	\
} while (0)
#define	IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...) do {		\
	if (ieee80211_msg(_vap, _m))					\
		ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__);	\
} while (0)
void	ieee80211_note(const struct ieee80211vap *, const char *, ...);
void	ieee80211_note_mac(const struct ieee80211vap *,
		const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...);
void	ieee80211_note_frame(const struct ieee80211vap *,
		const struct ieee80211_frame *, const char *, ...);
#define	ieee80211_msg_debug(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_DEBUG)
#define	ieee80211_msg_dumppkts(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_DUMPPKTS)
#define	ieee80211_msg_input(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_INPUT)
#define	ieee80211_msg_radius(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_RADIUS)
#define	ieee80211_msg_dumpradius(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_RADDUMP)
#define	ieee80211_msg_dumpradkeys(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_RADKEYS)
#define	ieee80211_msg_scan(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_SCAN)
#define	ieee80211_msg_assoc(_vap) \
	((_vap)->iv_debug & IEEE80211_MSG_ASSOC)

/*
 * Emit a debug message about discarding a frame or information
 * element.  One format is for extracting the mac address from
 * the frame header; the other is for when a header is not
 * available or otherwise appropriate.
 */
#define	IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt, ...) do {		\
	if ((_vap)->iv_debug & (_m))					\
		ieee80211_discard_frame(_vap, _wh, _type, _fmt, __VA_ARGS__);\
} while (0)
#define	IEEE80211_DISCARD_IE(_vap, _m, _wh, _type, _fmt, ...) do {	\
	if ((_vap)->iv_debug & (_m))					\
		ieee80211_discard_ie(_vap, _wh, _type, _fmt, __VA_ARGS__);\
} while (0)
#define	IEEE80211_DISCARD_MAC(_vap, _m, _mac, _type, _fmt, ...) do {	\
	if ((_vap)->iv_debug & (_m))					\
		ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\
} while (0)

void ieee80211_discard_frame(const struct ieee80211vap *,
	const struct ieee80211_frame *, const char *type, const char *fmt, ...);
void ieee80211_discard_ie(const struct ieee80211vap *,
	const struct ieee80211_frame *, const char *type, const char *fmt, ...);
void ieee80211_discard_mac(const struct ieee80211vap *,
	const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
	const char *fmt, ...);
#else
#define	IEEE80211_DPRINTF(_vap, _m, _fmt, ...)
#define	IEEE80211_NOTE(_vap, _m, _ni, _fmt, ...)
#define	IEEE80211_NOTE_FRAME(_vap, _m, _wh, _fmt, ...)
#define	IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt, ...)
#define	ieee80211_msg_dumppkts(_vap)	0
#define	ieee80211_msg(_vap, _m)		0

#define	IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt, ...)
#define	IEEE80211_DISCARD_IE(_vap, _m, _wh, _type, _fmt, ...)
#define	IEEE80211_DISCARD_MAC(_vap, _m, _mac, _type, _fmt, ...)
#endif

#endif /* _NET80211_IEEE80211_VAR_H_ */