#ifndef _GPXE_NET80211_H #define _GPXE_NET80211_H #include #include #include #include #include /** @file * * The gPXE 802.11 MAC layer. */ /* * Major things NOT YET supported: * - any type of security * - 802.11n * * Major things that probably will NEVER be supported, barring a * compelling use case and/or corporate sponsorship: * - QoS * - 802.1X authentication ("WPA Enterprise") * - Contention-free periods * - "ad-hoc" networks (IBSS), monitor mode, host AP mode * - hidden networks on the 5GHz band due to regulatory issues * - spectrum management on the 5GHz band (TPC and DFS), as required * in some non-US regulatory domains * - Clause 14 PHYs (Frequency-Hopping Spread Spectrum on 2.4GHz) * and Clause 16 PHYs (infrared) - I'm not aware of any real-world * use of these. */ FILE_LICENCE ( GPL2_OR_LATER ); /* All 802.11 devices are handled using a generic "802.11 device" net_device, with a link in its `priv' field to a net80211_device which we use to handle 802.11-specific details. */ /** @defgroup net80211_band RF bands on which an 802.11 device can transmit */ /** @{ */ /** The 2.4 GHz ISM band, unlicensed in most countries */ #define NET80211_BAND_2GHZ 0 /** The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted */ #define NET80211_BAND_5GHZ 1 /** Number of RF bands */ #define NET80211_NR_BANDS 2 /** Bitmask for the 2GHz band */ #define NET80211_BAND_BIT_2GHZ (1 << 0) /** Bitmask for the 5GHz band */ #define NET80211_BAND_BIT_5GHZ (1 << 1) /** @} */ /** @defgroup net80211_mode 802.11 operation modes supported by hardware */ /** @{ */ /** 802.11a: 54 Mbps operation using OFDM signaling on the 5GHz band */ #define NET80211_MODE_A (1 << 0) /** 802.11b: 1-11 Mbps operation using DSSS/CCK signaling on the 2.4GHz band */ #define NET80211_MODE_B (1 << 1) /** 802.11g: 54 Mbps operation using ERP/OFDM signaling on the 2.4GHz band */ #define NET80211_MODE_G (1 << 2) /** 802.11n: High-rate operation using MIMO technology on 2.4GHz or 5GHz */ #define NET80211_MODE_N (1 << 3) /** @} */ /** @defgroup net80211_cfg Constants for the net80211 config callback */ /** @{ */ /** Channel choice (@c dev->channel) or regulatory parameters have changed */ #define NET80211_CFG_CHANNEL (1 << 0) /** Requested transmission rate (@c dev->rate) has changed */ #define NET80211_CFG_RATE (1 << 1) /** Association has been established with a new BSS (@c dev->bssid) */ #define NET80211_CFG_ASSOC (1 << 2) /** Low-level link parameters (short preamble, protection, etc) have changed */ #define NET80211_CFG_PHY_PARAMS (1 << 3) /** @} */ /** An 802.11 security handshaking protocol */ enum net80211_security_proto { /** No security handshaking * * This might be used with an open network or with WEP, as * WEP does not have a cryptographic handshaking phase. */ NET80211_SECPROT_NONE = 0, /** Pre-shared key handshaking * * This implements the "WPA Personal" handshake. 802.1X * authentication is not performed -- the user supplies a * pre-shared key directly -- but there is a 4-way handshake * between client and AP to verify that both have the same key * without revealing the contents of that key. */ NET80211_SECPROT_PSK = 1, /** Full EAP 802.1X handshaking * * This implements the "WPA Enterprise" handshake, connecting * to an 802.1X authentication server to provide credentials * and receive a pairwise master key (PMK), which is then used * in the same 4-way handshake as the PSK method. */ NET80211_SECPROT_EAP = 2, }; /** An 802.11 data encryption algorithm */ enum net80211_crypto_alg { /** No security, an "Open" network */ NET80211_CRYPT_NONE = 0, /** Network protected with WEP (awful RC4-based system) * * WEP uses a naive application of RC4, with a monotonically * increasing initialization vector that is prepended to the * key to initialize the RC4 keystream. It is highly insecure * and can be completely cracked or subverted using automated, * robust, freely available tools (aircrack-ng) in minutes. * * 40-bit and 104-bit WEP are differentiated only by the size * of the key. They may be advertised as 64-bit and 128-bit, * counting the non-random IV as part of the key bits. */ NET80211_CRYPT_WEP = 1, /** Network protected with TKIP (better RC4-based system) * * Usually known by its trade name of WPA (Wi-Fi Protected * Access), TKIP implements a message integrity code (MIC) * called Michael, a timestamp counter for replay prevention, * and a key mixing function that together remove almost all * the security problems with WEP. Countermeasures are * implemented to prevent high data-rate attacks. * * There exists one known attack on TKIP, that allows one to * send between 7 and 15 arbitrary short data packets on a * QoS-enabled network given about an hour of data * gathering. Since gPXE does not support QoS for 802.11 * networks, this is not a threat to us. The only other method * is a brute-force passphrase attack. */ NET80211_CRYPT_TKIP = 2, /** Network protected with CCMP (AES-based system) * * Often called WPA2 in commerce, or RSNA (Robust Security * Network Architecture) in the 802.11 standard, CCMP is * highly secure and does not have any known attack vectors. * Since it is based on a block cipher, the statistical * correlation and "chopchop" attacks used with great success * against WEP and minor success against TKIP fail. */ NET80211_CRYPT_CCMP = 3, }; /** @defgroup net80211_state Bits for the 802.11 association state field */ /** @{ */ /** An error code indicating the failure mode, or 0 if successful */ #define NET80211_STATUS_MASK 0x7F /** Whether the error code provided is a "reason" code, not a "status" code */ #define NET80211_IS_REASON 0x80 /** Whether we have found the network we will be associating with */ #define NET80211_PROBED (1 << 8) /** Whether we have successfully authenticated with the network * * This usually has nothing to do with actual security; it is a * holdover from older 802.11 implementation ideas. */ #define NET80211_AUTHENTICATED (1 << 9) /** Whether we have successfully associated with the network */ #define NET80211_ASSOCIATED (1 << 10) /** Whether we have completed security handshaking with the network * * Once this is set, we can send data packets. For that reason this * bit is set even in cases where no security handshaking is * required. */ #define NET80211_CRYPTO_SYNCED (1 << 11) /** Whether the auto-association task is running */ #define NET80211_WORKING (1 << 12) /** Whether the auto-association task is waiting for a reply from the AP */ #define NET80211_WAITING (1 << 13) /** Whether the auto-association task should be suppressed * * This is set by the `iwlist' command so that it can open the device * without starting another probe process that will interfere with its * own. */ #define NET80211_NO_ASSOC (1 << 14) /** Whether this association was performed using a broadcast SSID * * If the user opened this device without netX/ssid set, the device's * SSID will be set to that of the network it chooses to associate * with, but the netX/ssid setting will remain blank. If we don't * remember that we started from no specified SSID, it will appear * every time settings are updated (e.g. after DHCP) that we need to * reassociate due to the difference between the set SSID and our own. */ #define NET80211_AUTO_SSID (1 << 15) /** @} */ /** @defgroup net80211_phy 802.11 physical layer flags */ /** @{ */ /** Whether to use RTS/CTS or CTS-to-self protection for transmissions * * Since the RTS or CTS is transmitted using 802.11b signaling, and * includes a field indicating the amount of time that will be used by * transmission of the following packet, this serves as an effective * protection mechanism to avoid 802.11b clients interfering with * 802.11g clients on mixed networks. */ #define NET80211_PHY_USE_PROTECTION (1 << 1) /** Whether to use 802.11b short preamble operation * * Short-preamble operation can moderately increase throughput on * 802.11b networks operating between 2Mbps and 11Mbps. It is * irrelevant for 802.11g data rates, since they use a different * modulation scheme. */ #define NET80211_PHY_USE_SHORT_PREAMBLE (1 << 2) /** Whether to use 802.11g short slot operation * * This affects a low-level timing parameter of 802.11g transmissions. */ #define NET80211_PHY_USE_SHORT_SLOT (1 << 3) /** @} */ /** The maximum number of TX rates we allow to be configured simultaneously */ #define NET80211_MAX_RATES 16 /** The maximum number of channels we allow to be configured simultaneously */ #define NET80211_MAX_CHANNELS 32 /** Seconds we'll wait to get all fragments of a packet */ #define NET80211_FRAG_TIMEOUT 2 /** The number of fragments we can receive at once * * The 802.11 standard requires that this be at least 3. */ #define NET80211_NR_CONCURRENT_FRAGS 3 /** Maximum TX power to allow (dBm), if we don't get a regulatory hint */ #define NET80211_REG_TXPOWER 20 struct net80211_device; /** Operations that must be implemented by an 802.11 driver */ struct net80211_device_operations { /** Open 802.11 device * * @v dev 802.11 device * @ret rc Return status code * * This method should allocate RX I/O buffers and enable the * hardware to start transmitting and receiving packets on the * channels its net80211_register() call indicated it could * handle. It does not need to tune the antenna to receive * packets on any particular channel. */ int ( * open ) ( struct net80211_device *dev ); /** Close 802.11 network device * * @v dev 802.11 device * * This method should stop the flow of packets, and call * net80211_tx_complete() for any packets remaining in the * device's TX queue. */ void ( * close ) ( struct net80211_device *dev ); /** Transmit packet on 802.11 network device * * @v dev 802.11 device * @v iobuf I/O buffer * @ret rc Return status code * * This method should cause the hardware to initiate * transmission of the I/O buffer, using the channel and rate * most recently indicated by an appropriate call to the * @c config callback. The 802.11 layer guarantees that said * channel and rate will be the same as those currently * reflected in the fields of @a dev. * * If this method returns success, the I/O buffer remains * owned by the network layer's TX queue, and the driver must * eventually call net80211_tx_complete() to free the buffer * whether transmission succeeded or not. If this method * returns failure, it will be interpreted as "failure to * enqueue buffer" and the I/O buffer will be immediately * released. * * This method is guaranteed to be called only when the device * is open. */ int ( * transmit ) ( struct net80211_device *dev, struct io_buffer *iobuf ); /** Poll for completed and received packets * * @v dev 802.11 device * * This method should cause the hardware to check for * completed transmissions and received packets. Any received * packets should be delivered via net80211_rx(), and * completed transmissions should be indicated using * net80211_tx_complete(). * * This method is guaranteed to be called only when the device * is open. */ void ( * poll ) ( struct net80211_device *dev ); /** Enable or disable interrupts * * @v dev 802.11 device * @v enable If TRUE, interrupts should be enabled */ void ( * irq ) ( struct net80211_device *dev, int enable ); /** Update hardware state to match 802.11 layer state * * @v dev 802.11 device * @v changed Set of flags indicating what may have changed * @ret rc Return status code * * This method should cause the hardware state to be * reinitialized from the state indicated in fields of * net80211_device, in the areas indicated by bits set in * @a changed. If the hardware is unable to do so, this method * may return an appropriate error indication. * * This method is guaranteed to be called only when the device * is open. */ int ( * config ) ( struct net80211_device *dev, int changed ); }; /** An 802.11 RF channel. */ struct net80211_channel { /** The band with which this channel is associated */ u8 band; /** A channel number interpreted according to the band * * The 2.4GHz band uses channel numbers from 1-13 at 5MHz * intervals such that channel 1 is 2407 MHz; channel 14, * legal for use only in Japan, is defined separately as 2484 * MHz. Adjacent channels will overlap, since 802.11 * transmissions use a 20 MHz (4-channel) bandwidth. Most * commonly, channels 1, 6, and 11 are used. * * The 5GHz band uses channel numbers derived directly from * the frequency; channel 0 is 5000 MHz, and channels are * always spaced 5 MHz apart. Channel numbers over 180 are * relative to 4GHz instead of 5GHz, but these are rarely * seen. Most channels are not legal for use. */ u8 channel_nr; /** The center frequency for this channel * * Currently a bandwidth of 20 MHz is assumed. */ u16 center_freq; /** Hardware channel value */ u16 hw_value; /** Maximum allowable transmit power, in dBm * * This should be interpreted as EIRP, the power supplied to * an ideal isotropic antenna in order to achieve the same * average signal intensity as the real hardware at a * particular distance. * * Currently no provision is made for directional antennas. */ u8 maxpower; }; /** Information on the capabilities of an 802.11 hardware device * * In its probe callback, an 802.11 driver must read hardware * registers to determine the appropriate contents of this structure, * fill it, and pass it to net80211_register() so that the 802.11 * layer knows how to treat the hardware and what to advertise as * supported to access points. */ struct net80211_hw_info { /** Default hardware MAC address. * * The user may change this by setting the @c netX/mac setting * before the driver's open function is called; in that case * the driver must set the hardware MAC address to the address * contained in the wrapping net_device's ll_addr field, or if * that is impossible, set that ll_addr field back to the * unchangeable hardware MAC address. */ u8 hwaddr[ETH_ALEN]; /** A bitwise OR of the 802.11x modes supported by this device */ int modes; /** A bitwise OR of the bands on which this device can communicate */ int bands; /** A set of flags indicating peculiarities of this device. */ enum { /** Received frames include a frame check sequence. */ NET80211_HW_RX_HAS_FCS = (1 << 1), /** Hardware doesn't support 2.4GHz short preambles * * This is only relevant for 802.11b operation above * 2Mbps. All 802.11g devices support short preambles. */ NET80211_HW_NO_SHORT_PREAMBLE = (1 << 2), /** Hardware doesn't support 802.11g short slot operation */ NET80211_HW_NO_SHORT_SLOT = (1 << 3), } flags; /** Signal strength information that can be provided by the device * * Signal strength is passed to net80211_rx(), primarily to * allow determination of the closest access point for a * multi-AP network. The units are provided for completeness * of status displays. */ enum { /** No signal strength information supported */ NET80211_SIGNAL_NONE = 0, /** Signal strength in arbitrary units */ NET80211_SIGNAL_ARBITRARY, /** Signal strength in decibels relative to arbitrary base */ NET80211_SIGNAL_DB, /** Signal strength in decibels relative to 1mW */ NET80211_SIGNAL_DBM, } signal_type; /** Maximum signal in arbitrary cases * * If signal_type is NET80211_SIGNAL_ARBITRARY or * NET80211_SIGNAL_DB, the driver should report it on a scale * from 0 to signal_max. */ unsigned signal_max; /** List of RF channels supported by the card */ struct net80211_channel channels[NET80211_MAX_CHANNELS]; /** Number of supported channels */ int nr_channels; /** List of transmission rates supported by the card, indexed by band * * Rates should be in 100kbps increments (e.g. 11 Mbps would * be represented as the number 110). */ u16 rates[NET80211_NR_BANDS][NET80211_MAX_RATES]; /** Number of supported rates, indexed by band */ int nr_rates[NET80211_NR_BANDS]; /** Estimate of the time required to change channels, in microseconds * * If this is not known, a guess on the order of a few * milliseconds (value of 1000-5000) is reasonable. */ unsigned channel_change_time; }; /** Structure tracking received fragments for a packet * * We set up a fragment cache entry when we receive a packet marked as * fragment 0 with the "more fragments" bit set in its frame control * header. We are required by the 802.11 standard to track 3 * fragmented packets arriving simultaneously; if we receive more we * may drop some. Upon receipt of a new fragment-0 packet, if no entry * is available or expired, we take over the most @e recent entry for * the new packet, since we don't want to starve old entries from ever * finishing at all. If we get a fragment after the zeroth with no * cache entry for its packet, we drop it. */ struct net80211_frag_cache { /** Whether this cache entry is in use */ u8 in_use; /** Sequence number of this MSDU (packet) */ u16 seqnr; /** Timestamp from point at which first fragment was collected */ u32 start_ticks; /** Buffers for each fragment */ struct io_buffer *iob[16]; }; /** Interface to an 802.11 cryptographic algorithm * * Cryptographic algorithms define a net80211_crypto structure * statically, using a gPXE linker table to make it available to the * 802.11 layer. When the algorithm needs to be used, the 802.11 code * will allocate a copy of the static definition plus whatever space * the algorithm has requested for private state, and point * net80211_device::crypto at it. */ struct net80211_crypto { /** The cryptographic algorithm implemented */ enum net80211_crypto_alg algorithm; /** Initialize cryptographic algorithm using a given key * * @v crypto 802.11 cryptographic algorithm * @v key Pointer to key bytes * @v keylen Number of key bytes * @ret rc Return status code * * This method is passed the communication key provided by the * security handshake handler, which will already be in the * low-level form required. */ int ( * initialize ) ( struct net80211_crypto *crypto, u8 *key, int keylen ); /** Encrypt a frame using the cryptographic algorithm * * @v crypto 802.11 cryptographic algorithm * @v iob I/O buffer * @ret eiob Newly allocated I/O buffer with encrypted packet * * This method is called to encrypt a single frame. It is * guaranteed that initialize() will have completed * successfully before this method is called. * * The frame passed already has an 802.11 header prepended, * but the PROTECTED bit in the frame control field will not * be set; this method is responsible for setting it. The * returned I/O buffer should contain a complete copy of @a * iob, including the 802.11 header, but with the PROTECTED * bit set, the data encrypted, and whatever encryption * headers/trailers are necessary added. * * This method should never free the passed I/O buffer. * * Return NULL if the packet could not be encrypted, due to * memory limitations or otherwise. */ struct io_buffer * ( * encrypt ) ( struct net80211_crypto *crypto, struct io_buffer *iob ); /** Decrypt a frame using the cryptographic algorithm * * @v crypto 802.11 cryptographic algorithm * @v eiob Encrypted I/O buffer * @ret iob Newly allocated I/O buffer with decrypted packet * * This method is called to decrypt a single frame. It is * guaranteed that initialize() will have completed * successfully before this method is called. * * Decryption follows the reverse of the pattern used for * encryption: this method must copy the 802.11 header into * the returned packet, decrypt the data stream, remove any * encryption header or trailer, and clear the PROTECTED bit * in the frame control header. * * This method should never free the passed I/O buffer. * * Return NULL if memory was not available for decryption, if * a consistency or integrity check on the decrypted frame * failed, or if the decrypted frame should not be processed * by the network stack for any other reason. */ struct io_buffer * ( * decrypt ) ( struct net80211_crypto *crypto, struct io_buffer *iob ); /** Length of private data requested to be allocated */ int priv_len; /** Private data for the algorithm to store key and state info */ void *priv; }; struct net80211_probe_ctx; struct net80211_assoc_ctx; /** Structure encapsulating the complete state of an 802.11 device * * An 802.11 device is always wrapped by a network device, and this * network device is always pointed to by the @a netdev field. In * general, operations should never be performed by 802.11 code using * netdev functions directly. It is usually the case that the 802.11 * layer might need to do some processing or bookkeeping on top of * what the netdevice code will do. */ struct net80211_device { /** The net_device that wraps us. */ struct net_device *netdev; /** List of 802.11 devices. */ struct list_head list; /** 802.11 device operations */ struct net80211_device_operations *op; /** Driver private data */ void *priv; /** Information about the hardware, provided to net80211_register() */ struct net80211_hw_info *hw; /* ---------- Channel and rate fields ---------- */ /** A list of all possible channels we might use */ struct net80211_channel channels[NET80211_MAX_CHANNELS]; /** The number of channels in the channels array */ u8 nr_channels; /** The channel currently in use, as an index into the channels array */ u8 channel; /** A list of all possible TX rates we might use * * Rates are in units of 100 kbps. */ u16 rates[NET80211_MAX_RATES]; /** The number of transmission rates in the rates array */ u8 nr_rates; /** The rate currently in use, as an index into the rates array */ u8 rate; /** The rate to use for RTS/CTS transmissions * * This is always the fastest basic rate that is not faster * than the data rate in use. Also an index into the rates array. */ u8 rtscts_rate; /** Bitmask of basic rates * * If bit N is set in this value, with the LSB considered to * be bit 0, then rate N in the rates array is a "basic" rate. * * We don't decide which rates are "basic"; our AP does, and * we respect its wishes. We need to be able to identify basic * rates in order to calculate the duration of a CTS packet * used for 802.11 g/b interoperability. */ u32 basic_rates; /* ---------- Association fields ---------- */ /** The asynchronous association process. * * When an 802.11 netdev is opened, or when the user changes * the SSID setting on an open 802.11 device, an * autoassociation task is started by net80211_autoassocate() * to associate with the new best network. The association is * asynchronous, but no packets can be transmitted until it is * complete. If it is successful, the wrapping net_device is * set as "link up". If it fails, @c assoc_rc will be set with * an error indication. */ struct process proc_assoc; /** Network with which we are associating * * This will be NULL when we are not actively in the process * of associating with a network we have already successfully * probed for. */ struct net80211_wlan *associating; /** Context for the association process * * This is a probe_ctx if the @c PROBED flag is not set in @c * state, and an assoc_ctx otherwise. */ union { struct net80211_probe_ctx *probe; struct net80211_assoc_ctx *assoc; } ctx; /** State of our association to the network * * Since the association process happens asynchronously, it's * necessary to have some channel of communication so the * driver can say "I got an association reply and we're OK" or * similar. This variable provides that link. It is a bitmask * of any of NET80211_PROBED, NET80211_AUTHENTICATED, * NET80211_ASSOCIATED, NET80211_CRYPTO_SYNCED to indicate how * far along in associating we are; NET80211_WORKING if the * association task is running; and NET80211_WAITING if a * packet has been sent that we're waiting for a reply to. We * can only be crypto-synced if we're associated, we can * only be associated if we're authenticated, we can only be * authenticated if we've probed. * * If an association process fails (that is, we receive a * packet with an error indication), the error code is copied * into bits 6-0 of this variable and bit 7 is set to specify * what type of error code it is. An AP can provide either a * "status code" (0-51 are defined) explaining why it refused * an association immediately, or a "reason code" (0-45 are * defined) explaining why it canceled an association after it * had originally OK'ed it. Status and reason codes serve * similar functions, but they use separate error message * tables. A gPXE-formatted return status code (negative) is * placed in @c assoc_rc. * * If the failure to associate is indicated by a status code, * the NET80211_IS_REASON bit will be clear; if it is * indicated by a reason code, the bit will be set. If we were * successful, both zero status and zero reason mean success, * so there is no ambiguity. * * To prevent association when opening the device, user code * can set the NET80211_NO_ASSOC bit. The final bit in this * variable, NET80211_AUTO_SSID, is used to remember whether * we picked our SSID through automated probing as opposed to * user specification; the distinction becomes relevant in the * settings applicator. */ u16 state; /** Return status code associated with @c state */ int assoc_rc; /* ---------- Parameters of currently associated network ---------- */ /** 802.11 cryptographic algorithm for our current network * * For an open network, this will be set to NULL. */ struct net80211_crypto *crypto; /** MAC address of the access point most recently associated */ u8 bssid[ETH_ALEN]; /** SSID of the access point we are or will be associated with * * Although the SSID field in 802.11 packets is generally not * NUL-terminated, here and in net80211_wlan we add a NUL for * convenience. */ char essid[IEEE80211_MAX_SSID_LEN+1]; /** Association ID given to us by the AP */ u16 aid; /** TSFT value for last beacon received, microseconds */ u64 last_beacon_timestamp; /** Time between AP sending beacons, microseconds */ u32 tx_beacon_interval; /** Smoothed average time between beacons, microseconds */ u32 rx_beacon_interval; /* ---------- Physical layer information ---------- */ /** Physical layer options * * These control the use of CTS protection, short preambles, * and short-slot operation. */ int phy_flags; /** Signal strength of last received packet */ int last_signal; /** Rate control state */ struct rc80211_ctx *rctl; /* ---------- Packet handling state ---------- */ /** Fragment reassembly state */ struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS]; /** The sequence number of the last packet we sent */ u16 last_tx_seqnr; /** Packet duplication elimination state * * We are only required to handle immediate duplicates for * each direct sender, and since we can only have one direct * sender (the AP), we need only keep the sequence control * field from the most recent packet we've received. Thus, * this field stores the last sequence control field we've * received for a packet from the AP. */ u16 last_rx_seq; /** RX management packet queue * * Sometimes we want to keep probe, beacon, and action packets * that we receive, such as when we're scanning for networks. * Ordinarily we drop them because they are sent at a large * volume (ten beacons per second per AP, broadcast) and we * have no need of them except when we're scanning. * * When keep_mgmt is TRUE, received probe, beacon, and action * management packets will be stored in this queue. */ struct list_head mgmt_queue; /** RX management packet info queue * * We need to keep track of the signal strength for management * packets we're keeping, because that provides the only way * to distinguish between multiple APs for the same network. * Since we can't extend io_buffer to store signal, this field * heads a linked list of "RX packet info" structures that * contain that signal strength field. Its entries always * parallel the entries in mgmt_queue, because the two queues * are always added to or removed from in parallel. */ struct list_head mgmt_info_queue; /** Whether to store management packets * * Received beacon, probe, and action packets will be added to * mgmt_queue (and their signal strengths added to * mgmt_info_queue) only when this variable is TRUE. It should * be set by net80211_keep_mgmt() (which returns the old * value) only when calling code is prepared to poll the * management queue frequently, because packets will otherwise * pile up and exhaust memory. */ int keep_mgmt; }; /** Structure representing a probed network. * * This is returned from the net80211_probe_finish functions and * passed to the low-level association functions. At least essid, * bssid, channel, beacon, and security must be filled in if you want * to build this structure manually. */ struct net80211_wlan { /** The human-readable ESSID (network name) * * Although the 802.11 SSID field is generally not * NUL-terminated, the gPXE code adds an extra NUL (and * expects one in this structure) for convenience. */ char essid[IEEE80211_MAX_SSID_LEN+1]; /** MAC address of the strongest-signal access point for this ESSID */ u8 bssid[ETH_ALEN]; /** Signal strength of beacon frame from that access point */ int signal; /** The channel on which that access point communicates * * This is a raw channel number (net80211_channel::channel_nr), * so that it will not be affected by reconfiguration of the * device channels array. */ int channel; /** The complete beacon or probe-response frame received */ struct io_buffer *beacon; /** Security handshaking method used on the network */ enum net80211_security_proto handshaking; /** Cryptographic algorithm used on the network */ enum net80211_crypto_alg crypto; /** Link to allow chaining multiple structures into a list to be returned from net80211_probe_finish_all(). */ struct list_head list; }; /** * @defgroup net80211_probe 802.11 network location API * @{ */ int net80211_prepare_probe ( struct net80211_device *dev, int band, int active ); struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev, const char *essid, int active ); int net80211_probe_step ( struct net80211_probe_ctx *ctx ); struct net80211_wlan * net80211_probe_finish_best ( struct net80211_probe_ctx *ctx ); struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx ); void net80211_free_wlan ( struct net80211_wlan *wlan ); void net80211_free_wlanlist ( struct list_head *list ); /** @} */ /** * @defgroup net80211_mgmt 802.11 network management API * @{ */ struct net80211_device * net80211_get ( struct net_device *netdev ); void net80211_autoassociate ( struct net80211_device *dev ); int net80211_change_channel ( struct net80211_device *dev, int channel ); void net80211_set_rate_idx ( struct net80211_device *dev, int rate ); int net80211_keep_mgmt ( struct net80211_device *dev, int enable ); struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev, int *signal ); int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, u8 bssid[ETH_ALEN], struct io_buffer *iob ); /** @} */ /** * @defgroup net80211_assoc 802.11 network association API * @{ */ int net80211_prepare_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ); int net80211_send_auth ( struct net80211_device *dev, struct net80211_wlan *wlan, int method ); int net80211_send_assoc ( struct net80211_device *dev, struct net80211_wlan *wlan ); /** @} */ /** * @defgroup net80211_driver 802.11 driver interface API * @{ */ struct net80211_device *net80211_alloc ( size_t priv_size ); int net80211_register ( struct net80211_device *dev, struct net80211_device_operations *ops, struct net80211_hw_info *hw ); u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate ); void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob, int signal, u16 rate ); void net80211_rx_err ( struct net80211_device *dev, struct io_buffer *iob, int rc ); void net80211_tx_complete ( struct net80211_device *dev, struct io_buffer *iob, int retries, int rc ); void net80211_unregister ( struct net80211_device *dev ); void net80211_free ( struct net80211_device *dev ); /** @} */ /** * Calculate duration field for a CTS control frame * * @v dev 802.11 device * @v size Size of the packet being cleared to send * * A CTS control frame's duration field captures the frame being * protected and its 10-byte ACK. */ static inline u16 net80211_cts_duration ( struct net80211_device *dev, int size ) { return ( net80211_duration ( dev, 10, dev->rates[dev->rtscts_rate] ) + net80211_duration ( dev, size, dev->rates[dev->rate] ) ); } #endif