You should read and understand the information contained within this part of the book while implementing a mac80211 driver. In some chapters, advanced usage is noted, those may be skipped if this isn’t needed.
This part of the book only covers station and monitor mode functionality, additional information required to implement the other modes is covered in the second part of the book.
TBD
This chapter shall contain information on getting a hw struct allocated and registered with mac80211.
Since it is required to allocate rates/modes before registering a hw struct, this chapter shall also contain information on setting up the rate/mode structs.
Additionally, some discussion about the callbacks and the general programming model should be in here, including the definition of ieee80211_ops which will be referred to a lot.
Finally, a discussion of hardware capabilities should be done with references to other parts of the book.
hardware information and state
Definition
struct ieee80211_hw {
struct ieee80211_conf conf;
struct wiphy * wiphy;
const char * rate_control_algorithm;
void * priv;
unsigned long flags[BITS_TO_LONGS(NUM_IEEE80211_HW_FLAGS)];
unsigned int extra_tx_headroom;
unsigned int extra_beacon_tailroom;
int vif_data_size;
int sta_data_size;
int chanctx_data_size;
int txq_data_size;
u16 queues;
u16 max_listen_interval;
s8 max_signal;
u8 max_rates;
u8 max_report_rates;
u8 max_rate_tries;
u8 max_rx_aggregation_subframes;
u8 max_tx_aggregation_subframes;
u8 max_tx_fragments;
u8 offchannel_tx_hw_queue;
u8 radiotap_mcs_details;
u16 radiotap_vht_details;
struct radiotap_timestamp;
netdev_features_t netdev_features;
u8 uapsd_queues;
u8 uapsd_max_sp_len;
u8 n_cipher_schemes;
const struct ieee80211_cipher_scheme * cipher_schemes;
u8 max_nan_de_entries;
};
Members
Description
This structure contains the configuration and hardware information for an 802.11 PHY.
hardware flags
Constants
Description
These flags are used to indicate hardware capabilities to the stack. Generally, flags here should have their meaning done in a way that the simplest hardware doesn’t need setting any particular flags. There are some exceptions to this rule, however, so you are advised to review these flags carefully.
set device for 802.11 hardware
Parameters
set the permanent MAC address for 802.11 hardware
Parameters
callbacks from mac80211 to the driver
Definition
struct ieee80211_ops {
void (* tx) (struct ieee80211_hw *hw,struct ieee80211_tx_control *control,struct sk_buff *skb);
int (* start) (struct ieee80211_hw *hw);
void (* stop) (struct ieee80211_hw *hw);
#ifdef CONFIG_PM
int (* suspend) (struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
int (* resume) (struct ieee80211_hw *hw);
void (* set_wakeup) (struct ieee80211_hw *hw, bool enabled);
#endif
int (* add_interface) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* change_interface) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,enum nl80211_iftype new_type, bool p2p);
void (* remove_interface) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* config) (struct ieee80211_hw *hw, u32 changed);
void (* bss_info_changed) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *info,u32 changed);
int (* start_ap) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void (* stop_ap) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
u64 (* prepare_multicast) (struct ieee80211_hw *hw,struct netdev_hw_addr_list *mc_list);
void (* configure_filter) (struct ieee80211_hw *hw,unsigned int changed_flags,unsigned int *total_flags,u64 multicast);
void (* config_iface_filter) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,unsigned int filter_flags,unsigned int changed_flags);
int (* set_tim) (struct ieee80211_hw *hw, struct ieee80211_sta *sta,bool set);
int (* set_key) (struct ieee80211_hw *hw, enum set_key_cmd cmd,struct ieee80211_vif *vif, struct ieee80211_sta *sta,struct ieee80211_key_conf *key);
void (* update_tkip_key) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_key_conf *conf,struct ieee80211_sta *sta,u32 iv32, u16 *phase1key);
void (* set_rekey_data) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_gtk_rekey_data *data);
void (* set_default_unicast_key) (struct ieee80211_hw *hw,struct ieee80211_vif *vif, int idx);
int (* hw_scan) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct ieee80211_scan_request *req);
void (* cancel_hw_scan) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* sched_scan_start) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_sched_scan_request *req,struct ieee80211_scan_ies *ies);
int (* sched_scan_stop) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
void (* sw_scan_start) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,const u8 *mac_addr);
void (* sw_scan_complete) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* get_stats) (struct ieee80211_hw *hw,struct ieee80211_low_level_stats *stats);
void (* get_key_seq) (struct ieee80211_hw *hw,struct ieee80211_key_conf *key,struct ieee80211_key_seq *seq);
int (* set_frag_threshold) (struct ieee80211_hw *hw, u32 value);
int (* set_rts_threshold) (struct ieee80211_hw *hw, u32 value);
int (* sta_add) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct ieee80211_sta *sta);
int (* sta_remove) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct ieee80211_sta *sta);
#ifdef CONFIG_MAC80211_DEBUGFS
void (* sta_add_debugfs) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta,struct dentry *dir);
#endif
void (* sta_notify) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,enum sta_notify_cmd, struct ieee80211_sta *sta);
int (* sta_state) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct ieee80211_sta *sta,enum ieee80211_sta_state old_state,enum ieee80211_sta_state new_state);
void (* sta_pre_rcu_remove) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta);
void (* sta_rc_update) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta,u32 changed);
void (* sta_rate_tbl_update) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta);
void (* sta_statistics) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta,struct station_info *sinfo);
int (* conf_tx) (struct ieee80211_hw *hw,struct ieee80211_vif *vif, u16 ac,const struct ieee80211_tx_queue_params *params);
u64 (* get_tsf) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void (* set_tsf) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,u64 tsf);
void (* offset_tsf) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,s64 offset);
void (* reset_tsf) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int (* tx_last_beacon) (struct ieee80211_hw *hw);
int (* ampdu_action) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_ampdu_params *params);
int (* get_survey) (struct ieee80211_hw *hw, int idx,struct survey_info *survey);
void (* rfkill_poll) (struct ieee80211_hw *hw);
void (* set_coverage_class) (struct ieee80211_hw *hw, s16 coverage_class);
#ifdef CONFIG_NL80211_TESTMODE
int (* testmode_cmd) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,void *data, int len);
int (* testmode_dump) (struct ieee80211_hw *hw, struct sk_buff *skb,struct netlink_callback *cb,void *data, int len);
#endif
void (* flush) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,u32 queues, bool drop);
void (* channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_channel_switch *ch_switch);
int (* set_antenna) (struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
int (* get_antenna) (struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
int (* remain_on_channel) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_channel *chan,int duration,enum ieee80211_roc_type type);
int (* cancel_remain_on_channel) (struct ieee80211_hw *hw);
int (* set_ringparam) (struct ieee80211_hw *hw, u32 tx, u32 rx);
void (* get_ringparam) (struct ieee80211_hw *hw,u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
bool (* tx_frames_pending) (struct ieee80211_hw *hw);
int (* set_bitrate_mask) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,const struct cfg80211_bitrate_mask *mask);
void (* event_callback) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,const struct ieee80211_event *event);
void (* allow_buffered_frames) (struct ieee80211_hw *hw,struct ieee80211_sta *sta,u16 tids, int num_frames,enum ieee80211_frame_release_type reason,bool more_data);
void (* release_buffered_frames) (struct ieee80211_hw *hw,struct ieee80211_sta *sta,u16 tids, int num_frames,enum ieee80211_frame_release_type reason,bool more_data);
int (* get_et_sset_count) (struct ieee80211_hw *hw,struct ieee80211_vif *vif, int sset);
void (* get_et_stats) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ethtool_stats *stats, u64 *data);
void (* get_et_strings) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,u32 sset, u8 *data);
void (* mgd_prepare_tx) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
void (* mgd_protect_tdls_discover) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* add_chanctx) (struct ieee80211_hw *hw,struct ieee80211_chanctx_conf *ctx);
void (* remove_chanctx) (struct ieee80211_hw *hw,struct ieee80211_chanctx_conf *ctx);
void (* change_chanctx) (struct ieee80211_hw *hw,struct ieee80211_chanctx_conf *ctx,u32 changed);
int (* assign_vif_chanctx) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_chanctx_conf *ctx);
void (* unassign_vif_chanctx) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_chanctx_conf *ctx);
int (* switch_vif_chanctx) (struct ieee80211_hw *hw,struct ieee80211_vif_chanctx_switch *vifs,int n_vifs,enum ieee80211_chanctx_switch_mode mode);
void (* reconfig_complete) (struct ieee80211_hw *hw,enum ieee80211_reconfig_type reconfig_type);
#if IS_ENABLED(CONFIG_IPV6)
void (* ipv6_addr_change) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct inet6_dev *idev);
#endif
void (* channel_switch_beacon) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_chan_def *chandef);
int (* pre_channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_channel_switch *ch_switch);
int (* post_channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* join_ibss) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
void (* leave_ibss) (struct ieee80211_hw *hw, struct ieee80211_vif *vif);
u32 (* get_expected_throughput) (struct ieee80211_hw *hw,struct ieee80211_sta *sta);
int (* get_txpower) (struct ieee80211_hw *hw, struct ieee80211_vif *vif,int *dbm);
int (* tdls_channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta, u8 oper_class,struct cfg80211_chan_def *chandef,struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie);
void (* tdls_cancel_channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta);
void (* tdls_recv_channel_switch) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_tdls_ch_sw_params *params);
void (* wake_tx_queue) (struct ieee80211_hw *hw,struct ieee80211_txq *txq);
void (* sync_rx_queues) (struct ieee80211_hw *hw);
int (* start_nan) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_nan_conf *conf);
int (* stop_nan) (struct ieee80211_hw *hw,struct ieee80211_vif *vif);
int (* nan_change_conf) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct cfg80211_nan_conf *conf, u32 changes);
int (* add_nan_func) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,const struct cfg80211_nan_func *nan_func);
void (* del_nan_func) (struct ieee80211_hw *hw,struct ieee80211_vif *vif,u8 instance_id);
};
Members
Perform a certain A-MPDU action. The RA/TID combination determines the destination and TID we want the ampdu action to be performed for. The action is defined through ieee80211_ampdu_mlme_action. When the action is set to IEEE80211_AMPDU_TX_OPERATIONAL the driver may neither send aggregates containing more subframes than buf_size nor send aggregates in a way that lost frames would exceed the buffer size. If just limiting the aggregate size, this would be possible with a buf_size of 8:
which is invalid since #1 was now re-transmitted well past the buffer size of 8. Correct ways to retransmit #1 would be:
Even 189 would be wrong since 1 could be lost again.
Returns a negative error code on failure. The callback can sleep.
Description
This structure contains various callbacks that the driver may handle or, in some cases, must handle, for example to configure the hardware to a new channel or to transmit a frame.
Allocate a new hardware device
Parameters
Description
This must be called once for each hardware device. The returned pointer must be used to refer to this device when calling other functions. mac80211 allocates a private data area for the driver pointed to by priv in struct ieee80211_hw, the size of this area is given as priv_data_len.
Return
A pointer to the new hardware device, or NULL on error.
Register hardware device
Parameters
Description
You must call this function before any other functions in mac80211. Note that before a hardware can be registered, you need to fill the contained wiphy’s information.
Return
0 on success. An error code otherwise.
Unregister a hardware device
Parameters
Description
This function instructs mac80211 to free allocated resources and unregister netdevices from the networking subsystem.
free hardware descriptor
Parameters
Description
This function frees everything that was allocated, including the private data for the driver. You must call ieee80211_unregister_hw() before calling this function.
TBD
This chapter should describe PHY handling including start/stop callbacks and the various structures used.
configuration of the device
Definition
struct ieee80211_conf {
u32 flags;
int power_level;
int dynamic_ps_timeout;
u16 listen_interval;
u8 ps_dtim_period;
u8 long_frame_max_tx_count;
u8 short_frame_max_tx_count;
struct cfg80211_chan_def chandef;
bool radar_enabled;
enum ieee80211_smps_mode smps_mode;
};
Members
Description
This struct indicates how the driver shall configure the hardware.
configuration flags
Constants
Description
Flags to define PHY configuration options
TBD
This chapter should describe virtual interface basics that are relevant to the driver (VLANs, MGMT etc are not.) It should explain the use of the add_iface/remove_iface callbacks as well as the interface configuration callbacks.
Things related to AP mode should be discussed there.
Things related to supporting multiple interfaces should be in the appropriate chapter, a BIG FAT note should be here about this though and the recommendation to allow only a single interface in STA mode at first!
per-interface data
Definition
struct ieee80211_vif {
enum nl80211_iftype type;
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
bool p2p;
bool csa_active;
bool mu_mimo_owner;
u8 cab_queue;
u8 hw_queue[IEEE80211_NUM_ACS];
struct ieee80211_txq * txq;
struct ieee80211_chanctx_conf __rcu * chanctx_conf;
u32 driver_flags;
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry * debugfs_dir;
#endif
unsigned int probe_req_reg;
u8 drv_priv[0];
};
Members
Description
Data in this structure is continually present for driver use during the life of a virtual interface.
TBD
This should describe the receive and transmit paths in mac80211/the drivers as well as transmit status handling.
As a general rule, when frames are passed between mac80211 and the driver, they start with the IEEE 802.11 header and include the same octets that are sent over the air except for the FCS which should be calculated by the hardware.
There are, however, various exceptions to this rule for advanced features:
The first exception is for hardware encryption and decryption offload where the IV/ICV may or may not be generated in hardware.
Secondly, when the hardware handles fragmentation, the frame handed to the driver from mac80211 is the MSDU, not the MPDU.
Drivers always need to pass packets that are aligned to two-byte boundaries to the stack.
Additionally, should, if possible, align the payload data in a way that guarantees that the contained IP header is aligned to a four-byte boundary. In the case of regular frames, this simply means aligning the payload to a four-byte boundary (because either the IP header is directly contained, or IV/RFC1042 headers that have a length divisible by four are in front of it). If the payload data is not properly aligned and the architecture doesn’t support efficient unaligned operations, mac80211 will align the data.
With A-MSDU frames, however, the payload data address must yield two modulo four because there are 14-byte 802.3 headers within the A-MSDU frames that push the IP header further back to a multiple of four again. Thankfully, the specs were sane enough this time around to require padding each A-MSDU subframe to a length that is a multiple of four.
Padding like Atheros hardware adds which is between the 802.11 header and the payload is not supported, the driver is required to move the 802.11 header to be directly in front of the payload in that case.
Only ieee80211_tx_status_irqsafe() and ieee80211_rx_irqsafe() can be called in hardware interrupt context. The low-level driver must not call any other functions in hardware interrupt context. If there is a need for such call, the low-level driver should first ACK the interrupt and perform the IEEE 802.11 code call after this, e.g. from a scheduled workqueue or even tasklet function.
receive status
Definition
struct ieee80211_rx_status {
u64 mactime;
u64 boottime_ns;
u32 device_timestamp;
u32 ampdu_reference;
u64 flag;
u16 freq;
u8 vht_flag;
u8 rate_idx;
u8 vht_nss;
u8 rx_flags;
u8 band;
u8 antenna;
s8 signal;
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
u8 ampdu_delimiter_crc;
};
Members
Description
The low-level driver should provide this information (the subset supported by hardware) to the 802.11 code with each received frame, in the skb’s control buffer (cb).
receive flags
Constants
Description
These flags are used with the flag member of struct ieee80211_rx_status.
flags to describe transmission information/status
Constants
Description
These flags are used with the flags member of ieee80211_tx_info.
Note
flags to describe transmit control
Constants
Description
These flags are used in tx_info->control.flags.
per-rate flags set by the Rate Control algorithm.
Constants
Description
These flags are set by the Rate control algorithm for each rate during tx, in the flags member of struct ieee80211_tx_rate.
rate selection/status
Definition
struct ieee80211_tx_rate {
s8 idx;
u16 count:5;
u16 flags:11;
};
Members
Description
A value of -1 for idx indicates an invalid rate and, if used in an array of retry rates, that no more rates should be tried.
When used for transmit status reporting, the driver should always report the rate along with the flags it used.
struct ieee80211_tx_info contains an array of these structs in the control information, and it will be filled by the rate control algorithm according to what should be sent. For example, if this array contains, in the format { <idx>, <count> } the information:
{ 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
then this means that the frame should be transmitted up to twice at rate 3, up to twice at rate 2, and up to four times at rate 1 if it doesn’t get acknowledged. Say it gets acknowledged by the peer after the fifth attempt, the status information should then contain:
{ 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ...
since it was transmitted twice at rate 3, twice at rate 2 and once at rate 1 after which we received an acknowledgement.
skb transmit information
Definition
struct ieee80211_tx_info {
u32 flags;
u8 band;
u8 hw_queue;
u16 ack_frame_id;
union {unnamed_union};
};
Members
Description
clear TX status
Parameters
Description
When the driver passes an skb back to mac80211, it must report a number of things in TX status. This function clears everything in the TX status but the rate control information (it does clear the count since you need to fill that in anyway).
NOTE
receive frame
Parameters
Description
Use this function to hand received frames to mac80211. The receive buffer in skb must start with an IEEE 802.11 header. In case of a paged skb is used, the driver is recommended to put the ieee80211 header of the frame on the linear part of the skb to avoid memory allocation and/or memcpy by the stack.
This function may not be called in IRQ context. Calls to this function for a single hardware must be synchronized against each other. Calls to this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be mixed for a single hardware. Must not run concurrently with ieee80211_tx_status() or ieee80211_tx_status_ni().
In process context use instead ieee80211_rx_ni().
receive frame (in process context)
Parameters
Description
Like ieee80211_rx() but can be called in process context (internally disables bottom halves).
Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may not be mixed for a single hardware. Must not run concurrently with ieee80211_tx_status() or ieee80211_tx_status_ni().
receive frame
Parameters
Description
Like ieee80211_rx() but can be called in IRQ context (internally defers to a tasklet.)
Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not be mixed for a single hardware.Must not run concurrently with ieee80211_tx_status() or ieee80211_tx_status_ni().
transmit status callback
Parameters
Description
Call this function for all transmitted frames after they have been transmitted. It is permissible to not call this function for multicast frames but this can affect statistics.
This function may not be called in IRQ context. Calls to this function for a single hardware must be synchronized against each other. Calls to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() may not be mixed for a single hardware. Must not run concurrently with ieee80211_rx() or ieee80211_rx_ni().
transmit status callback (in process context)
Parameters
Description
Like ieee80211_tx_status() but can be called in process context.
Calls to this function, ieee80211_tx_status() and ieee80211_tx_status_irqsafe() may not be mixed for a single hardware.
IRQ-safe transmit status callback
Parameters
Description
Like ieee80211_tx_status() but can be called in IRQ context (internally defers to a tasklet.)
Calls to this function, ieee80211_tx_status() and ieee80211_tx_status_ni() may not be mixed for a single hardware.
RTS frame generation function
Parameters
Description
If the RTS frames are generated by the host system (i.e., not in hardware/firmware), the low-level driver uses this function to receive the next RTS frame from the 802.11 code. The low-level is responsible for calling this function before and RTS frame is needed.
Get the duration field for an RTS frame
Parameters
Description
If the RTS is generated in firmware, but the host system must provide the duration field, the low-level driver uses this function to receive the duration field value in little-endian byteorder.
Return
The duration.
CTS-to-self frame generation function
Parameters
Description
If the CTS-to-self frames are generated by the host system (i.e., not in hardware/firmware), the low-level driver uses this function to receive the next CTS-to-self frame from the 802.11 code. The low-level is responsible for calling this function before and CTS-to-self frame is needed.
Get the duration field for a CTS-to-self frame
Parameters
Description
If the CTS-to-self is generated in firmware, but the host system must provide the duration field, the low-level driver uses this function to receive the duration field value in little-endian byteorder.
Return
The duration.
Calculate the duration field for a frame
Parameters
Description
Calculate the duration field of some generic frame, given its length and transmission rate (in 100kbps).
Return
The duration.
wake specific queue
Parameters
Description
Drivers should use this function instead of netif_wake_queue.
stop specific queue
Parameters
Description
Drivers should use this function instead of netif_stop_queue.
wake all queues
Parameters
Description
Drivers should use this function instead of netif_wake_queue.
stop all queues
Parameters
Description
Drivers should use this function instead of netif_stop_queue.
test status of the queue
Parameters
Description
Drivers should use this function instead of netif_stop_queue.
Return
true if the queue is stopped. false otherwise.
mac80211 requires to see many management frames for proper operation, and users may want to see many more frames when in monitor mode. However, for best CPU usage and power consumption, having as few frames as possible percolate through the stack is desirable. Hence, the hardware should filter as much as possible.
To achieve this, mac80211 uses filter flags (see below) to tell the driver’s configure_filter() function which frames should be passed to mac80211 and which should be filtered out.
Before configure_filter() is invoked, the prepare_multicast() callback is invoked with the parameters mc_count and mc_list for the combined multicast address list of all virtual interfaces. It’s use is optional, and it returns a u64 that is passed to configure_filter(). Additionally, configure_filter() has the arguments changed_flags telling which flags were changed and total_flags with the new flag states.
If your device has no multicast address filters your driver will need to check both the FIF_ALLMULTI flag and the mc_count parameter to see whether multicast frames should be accepted or dropped.
All unsupported flags in total_flags must be cleared. Hardware does not support a flag if it is incapable of _passing_ the frame to the stack. Otherwise the driver must ignore the flag, but not clear it. You must _only_ clear the flag (announce no support for the flag to mac80211) if you are not able to pass the packet type to the stack (so the hardware always filters it). So for example, you should clear FIF_CONTROL, if your hardware always filters control frames. If your hardware always passes control frames to the kernel and is incapable of filtering them, you do _not_ clear the FIF_CONTROL flag. This rule applies to all other FIF flags as well.
hardware filter flags
Constants
Description
These flags determine what the filter in hardware should be programmed to let through and what should not be passed to the stack. It is always safe to pass more frames than requested, but this has negative impact on power consumption.
mac80211 provides its own workqueue for drivers and internal mac80211 use. The workqueue is a single threaded workqueue and can only be accessed by helpers for sanity checking. Drivers must ensure all work added onto the mac80211 workqueue should be cancelled on the driver stop() callback.
mac80211 will flushed the workqueue upon interface removal and during suspend.
All work performed on the mac80211 workqueue must not acquire the RTNL lock.
add work onto the mac80211 workqueue
Parameters
Description
Drivers and mac80211 use this to add work onto the mac80211 workqueue. This helper ensures drivers are not queueing work when they should not be.
add work onto the mac80211 workqueue
Parameters
Description
Drivers and mac80211 use this to queue delayed work onto the mac80211 workqueue.