diff options
Diffstat (limited to 'net/mac80211/ieee80211_i.h')
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 224 | 
1 files changed, 194 insertions, 30 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b6186517ec5..ac9836e0aab 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -232,6 +232,7 @@ struct ieee80211_rx_data {  struct beacon_data {  	u8 *head, *tail;  	int head_len, tail_len; +	struct ieee80211_meshconf_ie *meshconf;  	struct rcu_head rcu_head;  }; @@ -245,7 +246,8 @@ struct ps_data {  	/* yes, this looks ugly, but guarantees that we can later use  	 * bitmap_empty :)  	 * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ -	u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; +	u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)] +			__aligned(__alignof__(unsigned long));  	struct sk_buff_head bc_buf;  	atomic_t num_sta_ps; /* number of stations in PS mode */  	int dtim_count; @@ -258,10 +260,14 @@ struct ieee80211_if_ap {  	/* to be used after channel switch. */  	struct cfg80211_beacon_data *next_beacon; -	struct list_head vlans; +	struct list_head vlans; /* write-protected with RTNL and local->mtx */  	struct ps_data ps;  	atomic_t num_mcast_sta; /* number of stations receiving multicast */ +	enum ieee80211_smps_mode req_smps, /* requested smps mode */ +			 driver_smps_mode; /* smps mode request */ + +	struct work_struct request_smps_work;  };  struct ieee80211_if_wds { @@ -270,7 +276,7 @@ struct ieee80211_if_wds {  };  struct ieee80211_if_vlan { -	struct list_head list; +	struct list_head list; /* write-protected with RTNL and local->mtx */  	/* used for all tx if the VLAN is configured to 4-addr mode */  	struct sta_info __rcu *sta; @@ -311,6 +317,7 @@ struct ieee80211_roc_work {  	bool started, abort, hw_begun, notified;  	bool to_be_freed; +	bool on_channel;  	unsigned long hw_start_time; @@ -322,7 +329,6 @@ struct ieee80211_roc_work {  /* flags used in struct ieee80211_if_managed.flags */  enum ieee80211_sta_flags { -	IEEE80211_STA_BEACON_POLL	= BIT(0),  	IEEE80211_STA_CONNECTION_POLL	= BIT(1),  	IEEE80211_STA_CONTROL_PORT	= BIT(2),  	IEEE80211_STA_DISABLE_HT	= BIT(4), @@ -335,6 +341,7 @@ enum ieee80211_sta_flags {  	IEEE80211_STA_DISABLE_VHT	= BIT(11),  	IEEE80211_STA_DISABLE_80P80MHZ	= BIT(12),  	IEEE80211_STA_DISABLE_160MHZ	= BIT(13), +	IEEE80211_STA_DISABLE_WMM	= BIT(14),  };  struct ieee80211_mgd_auth_data { @@ -487,6 +494,7 @@ struct ieee80211_if_managed {  struct ieee80211_if_ibss {  	struct timer_list timer; +	struct work_struct csa_connection_drop_work;  	unsigned long last_scan_completed; @@ -497,6 +505,7 @@ struct ieee80211_if_ibss {  	bool privacy;  	bool control_port; +	bool userspace_handles_dfs;  	u8 bssid[ETH_ALEN] __aligned(2);  	u8 ssid[IEEE80211_MAX_SSID_LEN]; @@ -534,10 +543,18 @@ struct ieee80211_mesh_sync_ops {  			     struct ieee80211_mgmt *mgmt,  			     struct ieee802_11_elems *elems,  			     struct ieee80211_rx_status *rx_status); -	void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata); + +	/* should be called with beacon_data under RCU read lock */ +	void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata, +			    struct beacon_data *beacon);  	/* add other framework functions here */  }; +struct mesh_csa_settings { +	struct rcu_head rcu_head; +	struct cfg80211_csa_settings settings; +}; +  struct ieee80211_if_mesh {  	struct timer_list housekeeping_timer;  	struct timer_list mesh_path_timer; @@ -598,6 +615,18 @@ struct ieee80211_if_mesh {  	int ps_peers_light_sleep;  	int ps_peers_deep_sleep;  	struct ps_data ps; +	/* Channel Switching Support */ +	struct mesh_csa_settings __rcu *csa; +	enum { +		IEEE80211_MESH_CSA_ROLE_NONE, +		IEEE80211_MESH_CSA_ROLE_INIT, +		IEEE80211_MESH_CSA_ROLE_REPEATER, +	} csa_role; +	u8 chsw_ttl; +	u16 pre_value; + +	/* offset from skb->data while building IE */ +	int meshconf_offset;  };  #ifdef CONFIG_MAC80211_MESH @@ -663,13 +692,20 @@ struct ieee80211_chanctx {  	struct list_head list;  	struct rcu_head rcu_head; +	struct list_head assigned_vifs; +	struct list_head reserved_vifs; +  	enum ieee80211_chanctx_mode mode; -	int refcount;  	bool driver_present;  	struct ieee80211_chanctx_conf conf;  }; +struct mac80211_qos_map { +	struct cfg80211_qos_map qos_map; +	struct rcu_head rcu_head; +}; +  struct ieee80211_sub_if_data {  	struct list_head list; @@ -712,13 +748,26 @@ struct ieee80211_sub_if_data {  	u16 sequence_number;  	__be16 control_port_protocol;  	bool control_port_no_encrypt; +	int encrypt_headroom;  	struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; +	struct mac80211_qos_map __rcu *qos_map;  	struct work_struct csa_finalize_work; -	int csa_counter_offset_beacon; -	int csa_counter_offset_presp; +	u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM]; +	u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM];  	bool csa_radar_required; +	bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ +	struct cfg80211_chan_def csa_chandef; + +	struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ +	struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */ + +	/* context reservation -- protected with chanctx_mtx */ +	struct ieee80211_chanctx *reserved_chanctx; +	struct cfg80211_chan_def reserved_chandef; +	bool reserved_radar_required; +	u8 csa_current_counter;  	/* used to reconfigure hardware SM PS */  	struct work_struct recalc_smps; @@ -758,10 +807,6 @@ struct ieee80211_sub_if_data {  		u32 mntr_flags;  	} u; -	spinlock_t cleanup_stations_lock; -	struct list_head cleanup_stations; -	struct work_struct cleanup_stations_wk; -  #ifdef CONFIG_MAC80211_DEBUGFS  	struct {  		struct dentry *subdir_stations; @@ -795,6 +840,9 @@ static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)  	__release(&sdata->wdev.mtx);  } +#define sdata_dereference(p, sdata) \ +	rcu_dereference_protected(p, lockdep_is_held(&sdata->wdev.mtx)) +  static inline void  sdata_assert_lock(struct ieee80211_sub_if_data *sdata)  { @@ -880,6 +928,24 @@ struct tpt_led_trigger {  };  #endif +/* + * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges + * + * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a + * certain latency range (in Milliseconds). Each station that uses these + * ranges will have bins to count the amount of frames received in that range. + * The user can configure the ranges via debugfs. + * If ranges is NULL then Tx latency statistics bins are disabled for all + * stations. + * + * @n_ranges: number of ranges that are taken in account + * @ranges: the ranges that the user requested or NULL if disabled. + */ +struct ieee80211_tx_latency_bin_ranges { +	int n_ranges; +	u32 ranges[]; +}; +  /**   * mac80211 scan flags - currently active scan mode   * @@ -893,6 +959,8 @@ struct tpt_led_trigger {   *	that the scan completed.   * @SCAN_ABORTED: Set for our scan work function when the driver reported   *	a scan complete for an aborted scan. + * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being + *	cancelled.   */  enum {  	SCAN_SW_SCANNING, @@ -900,6 +968,7 @@ enum {  	SCAN_ONCHANNEL_SCANNING,  	SCAN_COMPLETED,  	SCAN_ABORTED, +	SCAN_HW_CANCELLED,  };  /** @@ -1029,6 +1098,12 @@ struct ieee80211_local {  	struct timer_list sta_cleanup;  	int sta_generation; +	/* +	 * Tx latency statistics parameters for all stations. +	 * Can enable via debugfs (NULL when disabled). +	 */ +	struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency; +  	struct sk_buff_head pending[IEEE80211_MAX_QUEUES];  	struct tasklet_struct tx_pending_tasklet; @@ -1069,12 +1144,12 @@ struct ieee80211_local {  	struct work_struct sched_scan_stopped_work;  	struct ieee80211_sub_if_data __rcu *sched_scan_sdata; +	struct cfg80211_sched_scan_request *sched_scan_req;  	unsigned long leave_oper_channel_time;  	enum mac80211_scan_state next_scan_state;  	struct delayed_work scan_work;  	struct ieee80211_sub_if_data __rcu *scan_sdata; -	struct cfg80211_chan_def csa_chandef;  	/* For backward compatibility only -- do not use */  	struct cfg80211_chan_def _oper_chandef; @@ -1180,6 +1255,8 @@ struct ieee80211_local {  	struct ieee80211_sub_if_data __rcu *p2p_sdata; +	struct napi_struct *napi; +  	/* virtual monitor interface */  	struct ieee80211_sub_if_data __rcu *monitor_sdata;  	struct cfg80211_chan_def monitor_chandef; @@ -1203,6 +1280,15 @@ struct ieee80211_ra_tid {  	u16 tid;  }; +/* this struct holds the value parsing from channel switch IE  */ +struct ieee80211_csa_ie { +	struct cfg80211_chan_def chandef; +	u8 mode; +	u8 count; +	u8 ttl; +	u16 pre_value; +}; +  /* Parsed Information Elements */  struct ieee802_11_elems {  	const u8 *ie_start; @@ -1239,6 +1325,7 @@ struct ieee802_11_elems {  	const struct ieee80211_timeout_interval_ie *timeout_int;  	const u8 *opmode_notif;  	const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; +	const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;  	/* length of them, respectively */  	u8 ssid_len; @@ -1317,6 +1404,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);  void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);  void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,  				  __le16 fc, bool acked); +void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);  void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);  /* IBSS code */ @@ -1330,11 +1418,18 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);  void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);  void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,  				   struct sk_buff *skb); +int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, +			      struct cfg80211_csa_settings *csa_settings); +int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); +void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);  /* mesh code */  void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);  void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,  				   struct sk_buff *skb); +int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, +			      struct cfg80211_csa_settings *csa_settings); +int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata);  /* scan/BSS handling */  void ieee80211_scan_work(struct work_struct *work); @@ -1360,9 +1455,13 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,  			  struct ieee80211_bss *bss);  /* scheduled scan handling */ +int +__ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, +				     struct cfg80211_sched_scan_request *req);  int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,  				       struct cfg80211_sched_scan_request *req);  int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); +void ieee80211_sched_scan_end(struct ieee80211_local *local);  void ieee80211_sched_scan_stopped_work(struct work_struct *work);  /* off-channel helpers */ @@ -1377,7 +1476,10 @@ void ieee80211_sw_roc_work(struct work_struct *work);  void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);  /* channel switch handling */ +bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local);  void ieee80211_csa_finalize_work(struct work_struct *work); +int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, +			     struct cfg80211_csa_settings *params);  /* interface handling */  int ieee80211_iface_init(void); @@ -1400,8 +1502,6 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local);  bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);  void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); -int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, -			    struct cfg80211_beacon_data *params);  static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)  { @@ -1431,7 +1531,10 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,  int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,  			       enum ieee80211_smps_mode smps, const u8 *da,  			       const u8 *bssid); -void ieee80211_request_smps_work(struct work_struct *work); +void ieee80211_request_smps_ap_work(struct work_struct *work); +void ieee80211_request_smps_mgd_work(struct work_struct *work); +bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old, +				   enum ieee80211_smps_mode smps_mode_new);  void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,  				     u16 initiator, u16 reason, bool stop); @@ -1471,6 +1574,9 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,  				    struct sta_info *sta);  enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);  void ieee80211_sta_set_rx_nss(struct sta_info *sta); +u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, +                                  struct sta_info *sta, u8 opmode, +                                  enum ieee80211_band band, bool nss_only);  void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,  				 struct sta_info *sta, u8 opmode,  				 enum ieee80211_band band, bool nss_only); @@ -1481,6 +1587,28 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,  void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,  				       struct ieee80211_mgmt *mgmt,  				       size_t len); +/** + * ieee80211_parse_ch_switch_ie - parses channel switch IEs + * @sdata: the sdata of the interface which has received the frame + * @elems: parsed 802.11 elements received with the frame + * @beacon: indicates if the frame was a beacon or probe response + * @current_band: indicates the current band + * @sta_flags: contains information about own capabilities and restrictions + *	to decide which channel switch announcements can be accepted. Only the + *	following subset of &enum ieee80211_sta_flags are evaluated: + *	%IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT, + *	%IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ, + *	%IEEE80211_STA_DISABLE_160MHZ. + * @bssid: the currently connected bssid (for reporting) + * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl. +	All of them will be filled with if success only. + * Return: 0 on success, <0 on error and >0 if there is nothing to parse. + */ +int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +				 struct ieee802_11_elems *elems, bool beacon, +				 enum ieee80211_band current_band, +				 u32 sta_flags, u8 *bssid, +				 struct ieee80211_csa_ie *csa_ie);  /* Suspend/resume and hw reconfiguration */  int ieee80211_reconfig(struct ieee80211_local *local); @@ -1501,7 +1629,7 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)  }  /* utility functions/constants */ -extern void *mac80211_wiphy_privid; /* for wiphy privid */ +extern const void *const mac80211_wiphy_privid; /* for wiphy privid */  u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,  			enum nl80211_iftype type);  int ieee80211_frame_duration(enum ieee80211_band band, size_t len, @@ -1588,14 +1716,8 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,  void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);  void ieee80211_add_pending_skb(struct ieee80211_local *local,  			       struct sk_buff *skb); -void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, -				   struct sk_buff_head *skbs, -				   void (*fn)(void *data), void *data); -static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, -					      struct sk_buff_head *skbs) -{ -	ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); -} +void ieee80211_add_pending_skbs(struct ieee80211_local *local, +				struct sk_buff_head *skbs);  void ieee80211_flush_queues(struct ieee80211_local *local,  			    struct ieee80211_sub_if_data *sdata); @@ -1626,9 +1748,12 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,  u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,  			    struct ieee802_11_elems *elems,  			    enum ieee80211_band band, u32 *basic_rates); -int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, -			     enum ieee80211_smps_mode smps_mode); +int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, +				 enum ieee80211_smps_mode smps_mode); +int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, +				enum ieee80211_smps_mode smps_mode);  void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); +void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);  size_t ieee80211_ie_split(const u8 *ies, size_t ielen,  			  const u8 *ids, int n_ids, size_t offset); @@ -1654,34 +1779,73 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,  void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,  				  const struct ieee80211_ht_operation *ht_oper,  				  struct cfg80211_chan_def *chandef); +u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);  int __must_check  ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,  			  const struct cfg80211_chan_def *chandef,  			  enum ieee80211_chanctx_mode mode);  int __must_check +ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata, +			      const struct cfg80211_chan_def *chandef, +			      enum ieee80211_chanctx_mode mode, +			      bool radar_required); +int __must_check +ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata, +				   u32 *changed); +int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata); + +int __must_check  ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,  			       const struct cfg80211_chan_def *chandef,  			       u32 *changed);  /* NOTE: only use ieee80211_vif_change_channel() for channel switch */  int __must_check  ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, -			     const struct cfg80211_chan_def *chandef,  			     u32 *changed);  void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);  void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);  void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,  					 bool clear); +int ieee80211_chanctx_refcount(struct ieee80211_local *local, +			       struct ieee80211_chanctx *ctx);  void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,  				   struct ieee80211_chanctx *chanctx); -void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, -				    struct ieee80211_chanctx *chanctx); +void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, +				      struct ieee80211_chanctx *ctx);  void ieee80211_dfs_cac_timer(unsigned long data);  void ieee80211_dfs_cac_timer_work(struct work_struct *work);  void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);  void ieee80211_dfs_radar_detected_work(struct work_struct *work); +int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, +			      struct cfg80211_csa_settings *csa_settings); + +bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs); +bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n); +const struct ieee80211_cipher_scheme * +ieee80211_cs_get(struct ieee80211_local *local, u32 cipher, +		 enum nl80211_iftype iftype); +int ieee80211_cs_headroom(struct ieee80211_local *local, +			  struct cfg80211_crypto_settings *crypto, +			  enum nl80211_iftype iftype); +void ieee80211_recalc_dtim(struct ieee80211_local *local, +			   struct ieee80211_sub_if_data *sdata); +int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, +				 const struct cfg80211_chan_def *chandef, +				 enum ieee80211_chanctx_mode chanmode, +				 u8 radar_detect); +int ieee80211_max_num_channels(struct ieee80211_local *local); + +/* TDLS */ +int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, +			const u8 *peer, u8 action_code, u8 dialog_token, +			u16 status_code, u32 peer_capability, +			const u8 *extra_ies, size_t extra_ies_len); +int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, +			const u8 *peer, enum nl80211_tdls_operation oper); +  #ifdef CONFIG_MAC80211_NOINLINE  #define debug_noinline noinline  | 
