mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	wifi: mac80211: simplify non-chanctx drivers
There are still surprisingly many non-chanctx drivers, but in mac80211 that code is a bit awkward. Simplify this by having those drivers assign 'emulated' ops, so that the mac80211 code can be more unified between non-chanctx/chanctx drivers. This cuts the number of places caring about it by about 15, which are scattered across - now they're fewer and no longer in the channel context handling. Link: https://msgid.link/20240129194108.6d0ead50f5cf.I60d093b2fc81ca1853925a4d0ac3a2337d5baa5b@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									2d9698dd32
								
							
						
					
					
						commit
						0a44dfc070
					
				
					 58 changed files with 444 additions and 207 deletions
				
			
		| 
						 | 
					@ -1759,6 +1759,10 @@ static int adm8211_alloc_rings(struct ieee80211_hw *dev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops adm8211_ops = {
 | 
					static const struct ieee80211_ops adm8211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= adm8211_tx,
 | 
						.tx			= adm8211_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= adm8211_start,
 | 
						.start			= adm8211_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1358,6 +1358,10 @@ static void ar5523_configure_filter(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops ar5523_ops = {
 | 
					static const struct ieee80211_ops ar5523_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start			= ar5523_start,
 | 
						.start			= ar5523_start,
 | 
				
			||||||
	.stop			= ar5523_stop,
 | 
						.stop			= ar5523_stop,
 | 
				
			||||||
	.tx			= ar5523_tx,
 | 
						.tx			= ar5523_tx,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -779,6 +779,10 @@ static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops ath5k_hw_ops = {
 | 
					const struct ieee80211_ops ath5k_hw_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= ath5k_tx,
 | 
						.tx			= ath5k_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= ath5k_start,
 | 
						.start			= ath5k_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1868,6 +1868,10 @@ static void ath9k_htc_channel_switch_beacon(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ieee80211_ops ath9k_htc_ops = {
 | 
					struct ieee80211_ops ath9k_htc_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx                 = ath9k_htc_tx,
 | 
						.tx                 = ath9k_htc_tx,
 | 
				
			||||||
	.wake_tx_queue      = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue      = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start              = ath9k_htc_start,
 | 
						.start              = ath9k_htc_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2786,6 +2786,10 @@ static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ieee80211_ops ath9k_ops = {
 | 
					struct ieee80211_ops ath9k_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx 		    = ath9k_tx,
 | 
						.tx 		    = ath9k_tx,
 | 
				
			||||||
	.start 		    = ath9k_start,
 | 
						.start 		    = ath9k_start,
 | 
				
			||||||
	.stop 		    = ath9k_stop,
 | 
						.stop 		    = ath9k_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1712,6 +1712,10 @@ static bool carl9170_tx_frames_pending(struct ieee80211_hw *hw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops carl9170_ops = {
 | 
					static const struct ieee80211_ops carl9170_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start			= carl9170_op_start,
 | 
						.start			= carl9170_op_start,
 | 
				
			||||||
	.stop			= carl9170_op_stop,
 | 
						.stop			= carl9170_op_stop,
 | 
				
			||||||
	.tx			= carl9170_op_tx,
 | 
						.tx			= carl9170_op_tx,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1347,6 +1347,10 @@ static void wcn36xx_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops wcn36xx_ops = {
 | 
					static const struct ieee80211_ops wcn36xx_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start			= wcn36xx_start,
 | 
						.start			= wcn36xx_start,
 | 
				
			||||||
	.stop			= wcn36xx_stop,
 | 
						.stop			= wcn36xx_stop,
 | 
				
			||||||
	.add_interface		= wcn36xx_add_interface,
 | 
						.add_interface		= wcn36xx_add_interface,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2178,6 +2178,10 @@ static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops at76_ops = {
 | 
					static const struct ieee80211_ops at76_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = at76_mac80211_tx,
 | 
						.tx = at76_mac80211_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.add_interface = at76_add_interface,
 | 
						.add_interface = at76_add_interface,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5172,6 +5172,10 @@ static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops b43_hw_ops = {
 | 
					static const struct ieee80211_ops b43_hw_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= b43_op_tx,
 | 
						.tx			= b43_op_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.conf_tx		= b43_op_conf_tx,
 | 
						.conf_tx		= b43_op_conf_tx,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3531,6 +3531,10 @@ static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops b43legacy_hw_ops = {
 | 
					static const struct ieee80211_ops b43legacy_hw_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= b43legacy_op_tx,
 | 
						.tx			= b43legacy_op_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.conf_tx		= b43legacy_op_conf_tx,
 | 
						.conf_tx		= b43legacy_op_conf_tx,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -959,6 +959,10 @@ static int brcms_ops_beacon_set_tim(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops brcms_ops = {
 | 
					static const struct ieee80211_ops brcms_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = brcms_ops_tx,
 | 
						.tx = brcms_ops_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = brcms_ops_start,
 | 
						.start = brcms_ops_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3432,6 +3432,10 @@ static const struct attribute_group il3945_attribute_group = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct ieee80211_ops il3945_mac_ops __ro_after_init = {
 | 
					static struct ieee80211_ops il3945_mac_ops __ro_after_init = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = il3945_mac_tx,
 | 
						.tx = il3945_mac_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = il3945_mac_start,
 | 
						.start = il3945_mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6301,6 +6301,10 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops il4965_mac_ops = {
 | 
					static const struct ieee80211_ops il4965_mac_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = il4965_mac_tx,
 | 
						.tx = il4965_mac_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = il4965_mac_start,
 | 
						.start = il4965_mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1570,6 +1570,10 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops iwlagn_hw_ops = {
 | 
					const struct ieee80211_ops iwlagn_hw_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = iwlagn_mac_tx,
 | 
						.tx = iwlagn_mac_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = iwlagn_mac_start,
 | 
						.start = iwlagn_mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -704,6 +704,10 @@ static void p54_set_coverage_class(struct ieee80211_hw *dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops p54_ops = {
 | 
					static const struct ieee80211_ops p54_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= p54_tx_80211,
 | 
						.tx			= p54_tx_80211,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= p54_start,
 | 
						.start			= p54_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,6 +473,10 @@ static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops lbtf_ops = {
 | 
					static const struct ieee80211_ops lbtf_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= lbtf_op_tx,
 | 
						.tx			= lbtf_op_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= lbtf_op_start,
 | 
						.start			= lbtf_op_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5610,6 +5610,10 @@ static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops mwl8k_ops = {
 | 
					static const struct ieee80211_ops mwl8k_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= mwl8k_tx,
 | 
						.tx			= mwl8k_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= mwl8k_start,
 | 
						.start			= mwl8k_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -701,6 +701,10 @@ static void mt7603_tx(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops mt7603_ops = {
 | 
					const struct ieee80211_ops mt7603_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt7603_tx,
 | 
						.tx = mt7603_tx,
 | 
				
			||||||
	.start = mt7603_start,
 | 
						.start = mt7603_start,
 | 
				
			||||||
	.stop = mt7603_stop,
 | 
						.stop = mt7603_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,10 @@ mt76x0e_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops mt76x0e_ops = {
 | 
					static const struct ieee80211_ops mt76x0e_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt76x02_tx,
 | 
						.tx = mt76x02_tx,
 | 
				
			||||||
	.start = mt76x0e_start,
 | 
						.start = mt76x0e_start,
 | 
				
			||||||
	.stop = mt76x0e_stop,
 | 
						.stop = mt76x0e_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,6 +118,10 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops mt76x0u_ops = {
 | 
					static const struct ieee80211_ops mt76x0u_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt76x02_tx,
 | 
						.tx = mt76x02_tx,
 | 
				
			||||||
	.start = mt76x0u_start,
 | 
						.start = mt76x0u_start,
 | 
				
			||||||
	.stop = mt76x0u_stop,
 | 
						.stop = mt76x0u_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,6 +132,10 @@ static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops mt76x2_ops = {
 | 
					const struct ieee80211_ops mt76x2_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt76x02_tx,
 | 
						.tx = mt76x02_tx,
 | 
				
			||||||
	.start = mt76x2_start,
 | 
						.start = mt76x2_start,
 | 
				
			||||||
	.stop = mt76x2_stop,
 | 
						.stop = mt76x2_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,6 +103,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops mt76x2u_ops = {
 | 
					const struct ieee80211_ops mt76x2u_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt76x02_tx,
 | 
						.tx = mt76x02_tx,
 | 
				
			||||||
	.start = mt76x2u_start,
 | 
						.start = mt76x2u_start,
 | 
				
			||||||
	.stop = mt76x2u_stop,
 | 
						.stop = mt76x2u_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -684,9 +684,10 @@ mt792x_get_mac80211_ops(struct device *dev,
 | 
				
			||||||
	if (!(*fw_features & MT792x_FW_CAP_CNM)) {
 | 
						if (!(*fw_features & MT792x_FW_CAP_CNM)) {
 | 
				
			||||||
		ops->remain_on_channel = NULL;
 | 
							ops->remain_on_channel = NULL;
 | 
				
			||||||
		ops->cancel_remain_on_channel = NULL;
 | 
							ops->cancel_remain_on_channel = NULL;
 | 
				
			||||||
		ops->add_chanctx = NULL;
 | 
							ops->add_chanctx = ieee80211_emulate_add_chanctx;
 | 
				
			||||||
		ops->remove_chanctx = NULL;
 | 
							ops->remove_chanctx = ieee80211_emulate_remove_chanctx;
 | 
				
			||||||
		ops->change_chanctx = NULL;
 | 
							ops->change_chanctx = ieee80211_emulate_change_chanctx;
 | 
				
			||||||
 | 
							ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx;
 | 
				
			||||||
		ops->assign_vif_chanctx = NULL;
 | 
							ops->assign_vif_chanctx = NULL;
 | 
				
			||||||
		ops->unassign_vif_chanctx = NULL;
 | 
							ops->unassign_vif_chanctx = NULL;
 | 
				
			||||||
		ops->mgd_prepare_tx = NULL;
 | 
							ops->mgd_prepare_tx = NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1450,6 +1450,10 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops mt7996_ops = {
 | 
					const struct ieee80211_ops mt7996_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt7996_tx,
 | 
						.tx = mt7996_tx,
 | 
				
			||||||
	.start = mt7996_start,
 | 
						.start = mt7996_start,
 | 
				
			||||||
	.stop = mt7996_stop,
 | 
						.stop = mt7996_stop,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,6 +405,10 @@ mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops mt7601u_ops = {
 | 
					const struct ieee80211_ops mt7601u_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = mt7601u_tx,
 | 
						.tx = mt7601u_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = mt7601u_start,
 | 
						.start = mt7601u_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -684,6 +684,10 @@ static int plfxlc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops plfxlc_ops = {
 | 
					static const struct ieee80211_ops plfxlc_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = plfxlc_op_tx,
 | 
						.tx = plfxlc_op_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = plfxlc_op_start,
 | 
						.start = plfxlc_op_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1705,6 +1705,10 @@ static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2400pci_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2400pci_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2003,6 +2003,10 @@ static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2500pci_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2500pci_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1794,6 +1794,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2500usb_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2500usb_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -287,6 +287,10 @@ static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2800pci_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,6 +132,10 @@ static int rt2800soc_write_firmware(struct rt2x00_dev *rt2x00dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2800soc_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2800soc_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -629,6 +629,10 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt2800usb_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt2800usb_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2872,6 +2872,10 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt61pci_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt61pci_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2291,6 +2291,10 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rt73usb_mac80211_ops = {
 | 
					static const struct ieee80211_ops rt73usb_mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rt2x00mac_tx,
 | 
						.tx			= rt2x00mac_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rt2x00mac_start,
 | 
						.start			= rt2x00mac_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1607,6 +1607,10 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rtl8180_ops = {
 | 
					static const struct ieee80211_ops rtl8180_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rtl8180_tx,
 | 
						.tx			= rtl8180_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rtl8180_start,
 | 
						.start			= rtl8180_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1377,6 +1377,10 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rtl8187_ops = {
 | 
					static const struct ieee80211_ops rtl8187_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rtl8187_tx,
 | 
						.tx			= rtl8187_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= rtl8187_start,
 | 
						.start			= rtl8187_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7654,6 +7654,10 @@ static int rtl8xxxu_sta_remove(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops rtl8xxxu_ops = {
 | 
					static const struct ieee80211_ops rtl8xxxu_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = rtl8xxxu_tx,
 | 
						.tx = rtl8xxxu_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.add_interface = rtl8xxxu_add_interface,
 | 
						.add_interface = rtl8xxxu_add_interface,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1903,6 +1903,10 @@ void rtl_init_sw_leds(struct ieee80211_hw *hw)
 | 
				
			||||||
EXPORT_SYMBOL(rtl_init_sw_leds);
 | 
					EXPORT_SYMBOL(rtl_init_sw_leds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops rtl_ops = {
 | 
					const struct ieee80211_ops rtl_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start = rtl_op_start,
 | 
						.start = rtl_op_start,
 | 
				
			||||||
	.stop = rtl_op_stop,
 | 
						.stop = rtl_op_stop,
 | 
				
			||||||
	.tx = rtl_op_tx,
 | 
						.tx = rtl_op_tx,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -927,6 +927,10 @@ static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct ieee80211_ops rtw_ops = {
 | 
					const struct ieee80211_ops rtw_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= rtw_ops_tx,
 | 
						.tx			= rtw_ops_tx,
 | 
				
			||||||
	.wake_tx_queue		= rtw_ops_wake_tx_queue,
 | 
						.wake_tx_queue		= rtw_ops_wake_tx_queue,
 | 
				
			||||||
	.start			= rtw_ops_start,
 | 
						.start			= rtw_ops_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4579,9 +4579,10 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
 | 
				
			||||||
		     !RTW89_CHK_FW_FEATURE(BEACON_FILTER, &early_fw);
 | 
							     !RTW89_CHK_FW_FEATURE(BEACON_FILTER, &early_fw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (no_chanctx) {
 | 
						if (no_chanctx) {
 | 
				
			||||||
		ops->add_chanctx = NULL;
 | 
							ops->add_chanctx = ieee80211_emulate_add_chanctx;
 | 
				
			||||||
		ops->remove_chanctx = NULL;
 | 
							ops->remove_chanctx = ieee80211_emulate_remove_chanctx;
 | 
				
			||||||
		ops->change_chanctx = NULL;
 | 
							ops->change_chanctx = ieee80211_emulate_change_chanctx;
 | 
				
			||||||
 | 
							ops->switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx;
 | 
				
			||||||
		ops->assign_vif_chanctx = NULL;
 | 
							ops->assign_vif_chanctx = NULL;
 | 
				
			||||||
		ops->unassign_vif_chanctx = NULL;
 | 
							ops->unassign_vif_chanctx = NULL;
 | 
				
			||||||
		ops->remain_on_channel = NULL;
 | 
							ops->remain_on_channel = NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1957,6 +1957,10 @@ static int rsi_mac80211_resume(struct ieee80211_hw *hw)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops mac80211_ops = {
 | 
					static const struct ieee80211_ops mac80211_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx = rsi_mac80211_tx,
 | 
						.tx = rsi_mac80211_tx,
 | 
				
			||||||
	.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue = ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start = rsi_mac80211_start,
 | 
						.start = rsi_mac80211_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,6 +203,10 @@ static const unsigned long cw1200_ttl[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops cw1200_ops = {
 | 
					static const struct ieee80211_ops cw1200_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start			= cw1200_start,
 | 
						.start			= cw1200_start,
 | 
				
			||||||
	.stop			= cw1200_stop,
 | 
						.stop			= cw1200_stop,
 | 
				
			||||||
	.add_interface		= cw1200_add_interface,
 | 
						.add_interface		= cw1200_add_interface,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1351,6 +1351,10 @@ static struct ieee80211_supported_band wl1251_band_2ghz = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops wl1251_ops = {
 | 
					static const struct ieee80211_ops wl1251_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.start = wl1251_op_start,
 | 
						.start = wl1251_op_start,
 | 
				
			||||||
	.stop = wl1251_op_stop,
 | 
						.stop = wl1251_op_stop,
 | 
				
			||||||
	.add_interface = wl1251_op_add_interface,
 | 
						.add_interface = wl1251_op_add_interface,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3922,6 +3922,10 @@ static const struct ieee80211_ops mac80211_hwsim_ops = {
 | 
				
			||||||
	HWSIM_NON_MLO_OPS
 | 
						HWSIM_NON_MLO_OPS
 | 
				
			||||||
	.sw_scan_start = mac80211_hwsim_sw_scan,
 | 
						.sw_scan_start = mac80211_hwsim_sw_scan,
 | 
				
			||||||
	.sw_scan_complete = mac80211_hwsim_sw_scan_complete,
 | 
						.sw_scan_complete = mac80211_hwsim_sw_scan_complete,
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HWSIM_CHANCTX_OPS					\
 | 
					#define HWSIM_CHANCTX_OPS					\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1343,6 +1343,10 @@ static u64 zd_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops zd_ops = {
 | 
					static const struct ieee80211_ops zd_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= zd_op_tx,
 | 
						.tx			= zd_op_tx,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= zd_op_start,
 | 
						.start			= zd_op_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1684,6 +1684,10 @@ static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops vnt_mac_ops = {
 | 
					static const struct ieee80211_ops vnt_mac_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= vnt_tx_80211,
 | 
						.tx			= vnt_tx_80211,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= vnt_start,
 | 
						.start			= vnt_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -956,6 +956,10 @@ static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ieee80211_ops vnt_mac_ops = {
 | 
					static const struct ieee80211_ops vnt_mac_ops = {
 | 
				
			||||||
 | 
						.add_chanctx = ieee80211_emulate_add_chanctx,
 | 
				
			||||||
 | 
						.remove_chanctx = ieee80211_emulate_remove_chanctx,
 | 
				
			||||||
 | 
						.change_chanctx = ieee80211_emulate_change_chanctx,
 | 
				
			||||||
 | 
						.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
 | 
				
			||||||
	.tx			= vnt_tx_80211,
 | 
						.tx			= vnt_tx_80211,
 | 
				
			||||||
	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
						.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
 | 
				
			||||||
	.start			= vnt_start,
 | 
						.start			= vnt_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7532,4 +7532,17 @@ int ieee80211_set_active_links(struct ieee80211_vif *vif, u16 active_links);
 | 
				
			||||||
void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
 | 
					void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
 | 
				
			||||||
				      u16 active_links);
 | 
									      u16 active_links);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* for older drivers - let's not document these ... */
 | 
				
			||||||
 | 
					int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									  struct ieee80211_chanctx_conf *ctx);
 | 
				
			||||||
 | 
					void ieee80211_emulate_remove_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									      struct ieee80211_chanctx_conf *ctx);
 | 
				
			||||||
 | 
					void ieee80211_emulate_change_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									      struct ieee80211_chanctx_conf *ctx,
 | 
				
			||||||
 | 
									      u32 changed);
 | 
				
			||||||
 | 
					int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
										 struct ieee80211_vif_chanctx_switch *vifs,
 | 
				
			||||||
 | 
										 int n_vifs,
 | 
				
			||||||
 | 
										 enum ieee80211_chanctx_switch_mode mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* MAC80211_H */
 | 
					#endif /* MAC80211_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -886,33 +886,30 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ieee80211_local *local = wiphy_priv(wiphy);
 | 
						struct ieee80211_local *local = wiphy_priv(wiphy);
 | 
				
			||||||
	struct ieee80211_sub_if_data *sdata;
 | 
						struct ieee80211_sub_if_data *sdata;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
 | 
						if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (local->use_chanctx) {
 | 
						sdata = wiphy_dereference(local->hw.wiphy,
 | 
				
			||||||
		sdata = wiphy_dereference(local->hw.wiphy,
 | 
									  local->monitor_sdata);
 | 
				
			||||||
					  local->monitor_sdata);
 | 
						if (!sdata)
 | 
				
			||||||
		if (sdata) {
 | 
							goto done;
 | 
				
			||||||
			ieee80211_link_release_channel(&sdata->deflink);
 | 
					 | 
				
			||||||
			ret = ieee80211_link_use_channel(&sdata->deflink,
 | 
					 | 
				
			||||||
							 chandef,
 | 
					 | 
				
			||||||
							 IEEE80211_CHANCTX_EXCLUSIVE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (local->open_count == local->monitors) {
 | 
					 | 
				
			||||||
			local->_oper_chandef = *chandef;
 | 
					 | 
				
			||||||
			ieee80211_hw_config(local, 0);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret == 0)
 | 
						if (cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, chandef))
 | 
				
			||||||
		local->monitor_chandef = *chandef;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						ieee80211_link_release_channel(&sdata->deflink);
 | 
				
			||||||
 | 
						ret = ieee80211_link_use_channel(&sdata->deflink,
 | 
				
			||||||
 | 
										 chandef,
 | 
				
			||||||
 | 
										 IEEE80211_CHANCTX_EXCLUSIVE);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
						local->monitor_chandef = *chandef;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -3086,7 +3083,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
 | 
				
			||||||
	if (local->ops->get_txpower)
 | 
						if (local->ops->get_txpower)
 | 
				
			||||||
		return drv_get_txpower(local, sdata, dbm);
 | 
							return drv_get_txpower(local, sdata, dbm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx)
 | 
						if (local->emulate_chanctx)
 | 
				
			||||||
		*dbm = local->hw.conf.power_level;
 | 
							*dbm = local->hw.conf.power_level;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		*dbm = sdata->vif.bss_conf.txpower;
 | 
							*dbm = sdata->vif.bss_conf.txpower;
 | 
				
			||||||
| 
						 | 
					@ -4214,10 +4211,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
 | 
				
			||||||
	} else if (local->open_count > 0 &&
 | 
						} else if (local->open_count > 0 &&
 | 
				
			||||||
		   local->open_count == local->monitors &&
 | 
							   local->open_count == local->monitors &&
 | 
				
			||||||
		   sdata->vif.type == NL80211_IFTYPE_MONITOR) {
 | 
							   sdata->vif.type == NL80211_IFTYPE_MONITOR) {
 | 
				
			||||||
		if (local->use_chanctx)
 | 
							*chandef = local->monitor_chandef;
 | 
				
			||||||
			*chandef = local->monitor_chandef;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			*chandef = local->_oper_chandef;
 | 
					 | 
				
			||||||
		ret = 0;
 | 
							ret = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -519,11 +519,6 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drv_change_chanctx(local, ctx, changed);
 | 
						drv_change_chanctx(local, ctx, changed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
					 | 
				
			||||||
		local->_oper_chandef = *chandef;
 | 
					 | 
				
			||||||
		ieee80211_hw_config(local, 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* check is BW wider */
 | 
						/* check is BW wider */
 | 
				
			||||||
	ieee80211_chan_bw_change(local, old_ctx, false);
 | 
						ieee80211_chan_bw_change(local, old_ctx, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -674,23 +669,15 @@ static int ieee80211_add_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_add_wbrf(local, &ctx->conf.def);
 | 
						ieee80211_add_wbrf(local, &ctx->conf.def);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx)
 | 
					 | 
				
			||||||
		local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* turn idle off *before* setting channel -- some drivers need that */
 | 
						/* turn idle off *before* setting channel -- some drivers need that */
 | 
				
			||||||
	changed = ieee80211_idle_off(local);
 | 
						changed = ieee80211_idle_off(local);
 | 
				
			||||||
	if (changed)
 | 
						if (changed)
 | 
				
			||||||
		ieee80211_hw_config(local, changed);
 | 
							ieee80211_hw_config(local, changed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
						err = drv_add_chanctx(local, ctx);
 | 
				
			||||||
		local->_oper_chandef = ctx->conf.def;
 | 
						if (err) {
 | 
				
			||||||
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 | 
							ieee80211_recalc_idle(local);
 | 
				
			||||||
	} else {
 | 
							return err;
 | 
				
			||||||
		err = drv_add_chanctx(local, ctx);
 | 
					 | 
				
			||||||
		if (err) {
 | 
					 | 
				
			||||||
			ieee80211_recalc_idle(local);
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -725,32 +712,7 @@ static void ieee80211_del_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
						drv_remove_chanctx(local, ctx);
 | 
				
			||||||
		struct cfg80211_chan_def *chandef = &local->_oper_chandef;
 | 
					 | 
				
			||||||
		/* S1G doesn't have 20MHz, so get the correct width for the
 | 
					 | 
				
			||||||
		 * current channel.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (chandef->chan->band == NL80211_BAND_S1GHZ)
 | 
					 | 
				
			||||||
			chandef->width =
 | 
					 | 
				
			||||||
				ieee80211_s1g_channel_width(chandef->chan);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
 | 
					 | 
				
			||||||
		chandef->center_freq1 = chandef->chan->center_freq;
 | 
					 | 
				
			||||||
		chandef->freq1_offset = chandef->chan->freq_offset;
 | 
					 | 
				
			||||||
		chandef->center_freq2 = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* NOTE: Disabling radar is only valid here for
 | 
					 | 
				
			||||||
		 * single channel context. To be sure, check it ...
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		WARN_ON(local->hw.conf.radar_enabled &&
 | 
					 | 
				
			||||||
			!list_empty(&local->chanctx_list));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		local->hw.conf.radar_enabled = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		drv_remove_chanctx(local, ctx);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_recalc_idle(local);
 | 
						ieee80211_recalc_idle(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -849,11 +811,6 @@ static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chanctx->conf.radar_enabled = radar_enabled;
 | 
						chanctx->conf.radar_enabled = radar_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
					 | 
				
			||||||
		local->hw.conf.radar_enabled = chanctx->conf.radar_enabled;
 | 
					 | 
				
			||||||
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
 | 
						drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -995,16 +952,6 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
					 | 
				
			||||||
		if (rx_chains_static > 1)
 | 
					 | 
				
			||||||
			local->smps_mode = IEEE80211_SMPS_OFF;
 | 
					 | 
				
			||||||
		else if (rx_chains_dynamic > 1)
 | 
					 | 
				
			||||||
			local->smps_mode = IEEE80211_SMPS_DYNAMIC;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			local->smps_mode = IEEE80211_SMPS_STATIC;
 | 
					 | 
				
			||||||
		ieee80211_hw_config(local, 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (rx_chains_static == chanctx->conf.rx_chains_static &&
 | 
						if (rx_chains_static == chanctx->conf.rx_chains_static &&
 | 
				
			||||||
	    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
 | 
						    rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -1114,7 +1061,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	curr_ctx = ieee80211_link_get_chanctx(link);
 | 
						curr_ctx = ieee80211_link_get_chanctx(link);
 | 
				
			||||||
	if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
 | 
						if (curr_ctx && !local->ops->switch_vif_chanctx)
 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 | 
						new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 | 
				
			||||||
| 
						 | 
					@ -1412,24 +1359,6 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
 | 
					 | 
				
			||||||
					struct ieee80211_chanctx *new_ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const struct cfg80211_chan_def *chandef;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
 | 
					 | 
				
			||||||
	if (WARN_ON(!chandef))
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
 | 
					 | 
				
			||||||
	local->_oper_chandef = *chandef;
 | 
					 | 
				
			||||||
	ieee80211_hw_config(local, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
 | 
					static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
 | 
				
			||||||
				      int n_vifs)
 | 
									      int n_vifs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1518,7 +1447,6 @@ static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
 | 
				
			||||||
static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
 | 
					static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
 | 
						struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
 | 
				
			||||||
	struct ieee80211_chanctx *new_ctx = NULL;
 | 
					 | 
				
			||||||
	int err, n_assigned, n_reserved, n_ready;
 | 
						int err, n_assigned, n_reserved, n_ready;
 | 
				
			||||||
	int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
 | 
						int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1551,9 +1479,6 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!local->use_chanctx)
 | 
					 | 
				
			||||||
			new_ctx = ctx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n_ctx++;
 | 
							n_ctx++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		n_assigned = 0;
 | 
							n_assigned = 0;
 | 
				
			||||||
| 
						 | 
					@ -1607,9 +1532,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
 | 
				
			||||||
	if (WARN_ON(n_ctx == 0) ||
 | 
						if (WARN_ON(n_ctx == 0) ||
 | 
				
			||||||
	    WARN_ON(n_vifs_switch == 0 &&
 | 
						    WARN_ON(n_vifs_switch == 0 &&
 | 
				
			||||||
		    n_vifs_assign == 0 &&
 | 
							    n_vifs_assign == 0 &&
 | 
				
			||||||
		    n_vifs_ctxless == 0) ||
 | 
							    n_vifs_ctxless == 0)) {
 | 
				
			||||||
	    WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
 | 
					 | 
				
			||||||
	    WARN_ON(!new_ctx && !local->use_chanctx)) {
 | 
					 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		goto err;
 | 
							goto err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1619,20 +1542,14 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
 | 
				
			||||||
	 * reservations and driver capabilities.
 | 
						 * reservations and driver capabilities.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (local->use_chanctx) {
 | 
						if (n_vifs_switch > 0) {
 | 
				
			||||||
		if (n_vifs_switch > 0) {
 | 
							err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
 | 
				
			||||||
			err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
 | 
							if (err)
 | 
				
			||||||
			if (err)
 | 
								goto err;
 | 
				
			||||||
				goto err;
 | 
						}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
 | 
						if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
 | 
				
			||||||
			err = ieee80211_chsw_switch_ctxs(local);
 | 
							err = ieee80211_chsw_switch_ctxs(local);
 | 
				
			||||||
			if (err)
 | 
					 | 
				
			||||||
				goto err;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err = ieee80211_chsw_switch_hwconf(local, new_ctx);
 | 
					 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto err;
 | 
								goto err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1348,7 +1348,8 @@ struct ieee80211_local {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool wiphy_ciphers_allocated;
 | 
						bool wiphy_ciphers_allocated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool use_chanctx;
 | 
						struct cfg80211_chan_def dflt_chandef;
 | 
				
			||||||
 | 
						bool emulate_chanctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* protects the aggregated multicast list and filter calls */
 | 
						/* protects the aggregated multicast list and filter calls */
 | 
				
			||||||
	spinlock_t filter_lock;
 | 
						spinlock_t filter_lock;
 | 
				
			||||||
| 
						 | 
					@ -1474,8 +1475,6 @@ struct ieee80211_local {
 | 
				
			||||||
	enum mac80211_scan_state next_scan_state;
 | 
						enum mac80211_scan_state next_scan_state;
 | 
				
			||||||
	struct wiphy_delayed_work scan_work;
 | 
						struct wiphy_delayed_work scan_work;
 | 
				
			||||||
	struct ieee80211_sub_if_data __rcu *scan_sdata;
 | 
						struct ieee80211_sub_if_data __rcu *scan_sdata;
 | 
				
			||||||
	/* For backward compatibility only -- do not use */
 | 
					 | 
				
			||||||
	struct cfg80211_chan_def _oper_chandef;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Temporary remain-on-channel for off-channel operations */
 | 
						/* Temporary remain-on-channel for off-channel operations */
 | 
				
			||||||
	struct ieee80211_channel *tmp_channel;
 | 
						struct ieee80211_channel *tmp_channel;
 | 
				
			||||||
| 
						 | 
					@ -1549,8 +1548,6 @@ struct ieee80211_local {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int user_power_level; /* in dBm, for all interfaces */
 | 
						int user_power_level; /* in dBm, for all interfaces */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum ieee80211_smps_mode smps_mode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct work_struct restart_work;
 | 
						struct work_struct restart_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_MAC80211_DEBUGFS
 | 
					#ifdef CONFIG_MAC80211_DEBUGFS
 | 
				
			||||||
| 
						 | 
					@ -1819,6 +1816,8 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
 | 
				
			||||||
				     unsigned int mpdu_len,
 | 
									     unsigned int mpdu_len,
 | 
				
			||||||
				     unsigned int mpdu_offset);
 | 
									     unsigned int mpdu_offset);
 | 
				
			||||||
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
 | 
					int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
 | 
				
			||||||
 | 
					int ieee80211_hw_conf_chan(struct ieee80211_local *local);
 | 
				
			||||||
 | 
					void ieee80211_hw_conf_init(struct ieee80211_local *local);
 | 
				
			||||||
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
 | 
					void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
 | 
				
			||||||
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 | 
					void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
				      u64 changed);
 | 
									      u64 changed);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1288,8 +1288,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 | 
				
			||||||
		res = drv_start(local);
 | 
							res = drv_start(local);
 | 
				
			||||||
		if (res)
 | 
							if (res)
 | 
				
			||||||
			goto err_del_bss;
 | 
								goto err_del_bss;
 | 
				
			||||||
		/* we're brought up, everything changes */
 | 
					 | 
				
			||||||
		hw_reconf_flags = ~0;
 | 
					 | 
				
			||||||
		ieee80211_led_radio(local, true);
 | 
							ieee80211_led_radio(local, true);
 | 
				
			||||||
		ieee80211_mod_tpt_led_trig(local,
 | 
							ieee80211_mod_tpt_led_trig(local,
 | 
				
			||||||
					   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
 | 
										   IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
 | 
				
			||||||
| 
						 | 
					@ -1436,7 +1434,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 | 
				
			||||||
	if (coming_up)
 | 
						if (coming_up)
 | 
				
			||||||
		local->open_count++;
 | 
							local->open_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (hw_reconf_flags)
 | 
						if (local->open_count == 1)
 | 
				
			||||||
 | 
							ieee80211_hw_conf_init(local);
 | 
				
			||||||
 | 
						else if (hw_reconf_flags)
 | 
				
			||||||
		ieee80211_hw_config(local, hw_reconf_flags);
 | 
							ieee80211_hw_config(local, hw_reconf_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_recalc_ps(local);
 | 
						ieee80211_recalc_ps(local);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,16 +93,32 @@ static void ieee80211_reconfig_filter(struct wiphy *wiphy,
 | 
				
			||||||
	ieee80211_configure_filter(local);
 | 
						ieee80211_configure_filter(local);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
 | 
					static u32 ieee80211_calc_hw_conf_chan(struct ieee80211_local *local,
 | 
				
			||||||
 | 
									       struct ieee80211_chanctx_conf *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ieee80211_sub_if_data *sdata;
 | 
						struct ieee80211_sub_if_data *sdata;
 | 
				
			||||||
	struct cfg80211_chan_def chandef = {};
 | 
						struct cfg80211_chan_def chandef = {};
 | 
				
			||||||
 | 
						struct cfg80211_chan_def *oper = NULL;
 | 
				
			||||||
 | 
						enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_STATIC;
 | 
				
			||||||
	u32 changed = 0;
 | 
						u32 changed = 0;
 | 
				
			||||||
	int power;
 | 
						int power;
 | 
				
			||||||
	u32 offchannel_flag;
 | 
						u32 offchannel_flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!local->emulate_chanctx)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 | 
						offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx && !WARN_ON(!ctx->def.chan)) {
 | 
				
			||||||
 | 
							oper = &ctx->def;
 | 
				
			||||||
 | 
							if (ctx->rx_chains_static > 1)
 | 
				
			||||||
 | 
								smps_mode = IEEE80211_SMPS_OFF;
 | 
				
			||||||
 | 
							else if (ctx->rx_chains_dynamic > 1)
 | 
				
			||||||
 | 
								smps_mode = IEEE80211_SMPS_DYNAMIC;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								smps_mode = IEEE80211_SMPS_STATIC;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (local->scan_chandef.chan) {
 | 
						if (local->scan_chandef.chan) {
 | 
				
			||||||
		chandef = local->scan_chandef;
 | 
							chandef = local->scan_chandef;
 | 
				
			||||||
	} else if (local->tmp_channel) {
 | 
						} else if (local->tmp_channel) {
 | 
				
			||||||
| 
						 | 
					@ -110,25 +126,30 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
 | 
				
			||||||
		chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
 | 
							chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
 | 
				
			||||||
		chandef.center_freq1 = chandef.chan->center_freq;
 | 
							chandef.center_freq1 = chandef.chan->center_freq;
 | 
				
			||||||
		chandef.freq1_offset = chandef.chan->freq_offset;
 | 
							chandef.freq1_offset = chandef.chan->freq_offset;
 | 
				
			||||||
	} else
 | 
						} else if (oper) {
 | 
				
			||||||
		chandef = local->_oper_chandef;
 | 
							chandef = *oper;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							chandef = local->dflt_chandef;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN(!cfg80211_chandef_valid(&chandef),
 | 
						if (WARN(!cfg80211_chandef_valid(&chandef),
 | 
				
			||||||
	     "control:%d.%03d MHz width:%d center: %d.%03d/%d MHz",
 | 
							 "control:%d.%03d MHz width:%d center: %d.%03d/%d MHz",
 | 
				
			||||||
	     chandef.chan->center_freq, chandef.chan->freq_offset,
 | 
							 chandef.chan ? chandef.chan->center_freq : -1,
 | 
				
			||||||
	     chandef.width, chandef.center_freq1, chandef.freq1_offset,
 | 
							 chandef.chan ? chandef.chan->freq_offset : 0,
 | 
				
			||||||
	     chandef.center_freq2);
 | 
							 chandef.width, chandef.center_freq1, chandef.freq1_offset,
 | 
				
			||||||
 | 
							 chandef.center_freq2))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef))
 | 
						if (!oper || !cfg80211_chandef_identical(&chandef, oper))
 | 
				
			||||||
		local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
 | 
							local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
 | 
							local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 | 
						offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (offchannel_flag ||
 | 
						/* force it also for scanning, since drivers might config differently */
 | 
				
			||||||
	    !cfg80211_chandef_identical(&local->hw.conf.chandef,
 | 
						if (offchannel_flag || local->scanning ||
 | 
				
			||||||
					&local->_oper_chandef)) {
 | 
						    !cfg80211_chandef_identical(&local->hw.conf.chandef, &chandef)) {
 | 
				
			||||||
		local->hw.conf.chandef = chandef;
 | 
							local->hw.conf.chandef = chandef;
 | 
				
			||||||
		changed |= IEEE80211_CONF_CHANGE_CHANNEL;
 | 
							changed |= IEEE80211_CONF_CHANGE_CHANNEL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -140,8 +161,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
 | 
				
			||||||
		 * that otherwise STATIC is used.
 | 
							 * that otherwise STATIC is used.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC;
 | 
							local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC;
 | 
				
			||||||
	} else if (local->hw.conf.smps_mode != local->smps_mode) {
 | 
						} else if (local->hw.conf.smps_mode != smps_mode) {
 | 
				
			||||||
		local->hw.conf.smps_mode = local->smps_mode;
 | 
							local->hw.conf.smps_mode = smps_mode;
 | 
				
			||||||
		changed |= IEEE80211_CONF_CHANGE_SMPS;
 | 
							changed |= IEEE80211_CONF_CHANGE_SMPS;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,12 +194,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	might_sleep();
 | 
						might_sleep();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx)
 | 
						WARN_ON(changed & (IEEE80211_CONF_CHANGE_CHANNEL |
 | 
				
			||||||
		changed |= ieee80211_hw_conf_chan(local);
 | 
								   IEEE80211_CONF_CHANGE_POWER |
 | 
				
			||||||
	else
 | 
								   IEEE80211_CONF_CHANGE_SMPS));
 | 
				
			||||||
		changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL |
 | 
					 | 
				
			||||||
			     IEEE80211_CONF_CHANGE_POWER |
 | 
					 | 
				
			||||||
			     IEEE80211_CONF_CHANGE_SMPS);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (changed && local->open_count) {
 | 
						if (changed && local->open_count) {
 | 
				
			||||||
		ret = drv_config(local, changed);
 | 
							ret = drv_config(local, changed);
 | 
				
			||||||
| 
						 | 
					@ -202,6 +220,107 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* for scanning, offchannel and chanctx emulation only */
 | 
				
			||||||
 | 
					static int _ieee80211_hw_conf_chan(struct ieee80211_local *local,
 | 
				
			||||||
 | 
									   struct ieee80211_chanctx_conf *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!local->open_count)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						changed = ieee80211_calc_hw_conf_chan(local, ctx);
 | 
				
			||||||
 | 
						if (!changed)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return drv_config(local, changed);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ieee80211_hw_conf_chan(struct ieee80211_local *local)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_chanctx *ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = list_first_entry_or_null(&local->chanctx_list,
 | 
				
			||||||
 | 
									       struct ieee80211_chanctx,
 | 
				
			||||||
 | 
									       list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return _ieee80211_hw_conf_chan(local, ctx ? &ctx->conf : NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ieee80211_hw_conf_init(struct ieee80211_local *local)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 changed = ~(IEEE80211_CONF_CHANGE_CHANNEL |
 | 
				
			||||||
 | 
								IEEE80211_CONF_CHANGE_POWER |
 | 
				
			||||||
 | 
								IEEE80211_CONF_CHANGE_SMPS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (WARN_ON(!local->open_count))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (local->emulate_chanctx) {
 | 
				
			||||||
 | 
							struct ieee80211_chanctx *ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx = list_first_entry_or_null(&local->chanctx_list,
 | 
				
			||||||
 | 
										       struct ieee80211_chanctx,
 | 
				
			||||||
 | 
										       list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							changed |= ieee80211_calc_hw_conf_chan(local,
 | 
				
			||||||
 | 
											       ctx ? &ctx->conf : NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						WARN_ON(drv_config(local, changed));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									  struct ieee80211_chanctx_conf *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_local *local = hw_to_local(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local->hw.conf.radar_enabled = ctx->radar_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return _ieee80211_hw_conf_chan(local, ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ieee80211_emulate_add_chanctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ieee80211_emulate_remove_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									      struct ieee80211_chanctx_conf *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_local *local = hw_to_local(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local->hw.conf.radar_enabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_ieee80211_hw_conf_chan(local, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ieee80211_emulate_remove_chanctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ieee80211_emulate_change_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
									      struct ieee80211_chanctx_conf *ctx,
 | 
				
			||||||
 | 
									      u32 changed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_local *local = hw_to_local(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local->hw.conf.radar_enabled = ctx->radar_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_ieee80211_hw_conf_chan(local, ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ieee80211_emulate_change_chanctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
 | 
				
			||||||
 | 
										 struct ieee80211_vif_chanctx_switch *vifs,
 | 
				
			||||||
 | 
										 int n_vifs,
 | 
				
			||||||
 | 
										 enum ieee80211_chanctx_switch_mode mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ieee80211_local *local = hw_to_local(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (n_vifs <= 0)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local->hw.conf.radar_enabled = vifs[0].new_ctx->radar_enabled;
 | 
				
			||||||
 | 
						_ieee80211_hw_conf_chan(local, vifs[0].new_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(ieee80211_emulate_switch_vif_chanctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BSS_CHANGED_VIF_CFG_FLAGS (BSS_CHANGED_ASSOC |\
 | 
					#define BSS_CHANGED_VIF_CFG_FLAGS (BSS_CHANGED_ASSOC |\
 | 
				
			||||||
				   BSS_CHANGED_IDLE |\
 | 
									   BSS_CHANGED_IDLE |\
 | 
				
			||||||
				   BSS_CHANGED_PS |\
 | 
									   BSS_CHANGED_PS |\
 | 
				
			||||||
| 
						 | 
					@ -645,7 +764,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 | 
				
			||||||
	struct ieee80211_local *local;
 | 
						struct ieee80211_local *local;
 | 
				
			||||||
	int priv_size, i;
 | 
						int priv_size, i;
 | 
				
			||||||
	struct wiphy *wiphy;
 | 
						struct wiphy *wiphy;
 | 
				
			||||||
	bool use_chanctx;
 | 
						bool emulate_chanctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
 | 
						if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
 | 
				
			||||||
		    !ops->add_interface || !ops->remove_interface ||
 | 
							    !ops->add_interface || !ops->remove_interface ||
 | 
				
			||||||
| 
						 | 
					@ -660,12 +779,26 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* check all or no channel context operations exist */
 | 
						/* check all or no channel context operations exist */
 | 
				
			||||||
	i = !!ops->add_chanctx + !!ops->remove_chanctx +
 | 
						if (ops->add_chanctx == ieee80211_emulate_add_chanctx &&
 | 
				
			||||||
	    !!ops->change_chanctx + !!ops->assign_vif_chanctx +
 | 
						    ops->remove_chanctx == ieee80211_emulate_remove_chanctx &&
 | 
				
			||||||
	    !!ops->unassign_vif_chanctx;
 | 
						    ops->change_chanctx == ieee80211_emulate_change_chanctx) {
 | 
				
			||||||
	if (WARN_ON(i != 0 && i != 5))
 | 
							if (WARN_ON(ops->assign_vif_chanctx ||
 | 
				
			||||||
		return NULL;
 | 
								    ops->unassign_vif_chanctx))
 | 
				
			||||||
	use_chanctx = i == 5;
 | 
								return NULL;
 | 
				
			||||||
 | 
							emulate_chanctx = true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (WARN_ON(ops->add_chanctx == ieee80211_emulate_add_chanctx ||
 | 
				
			||||||
 | 
								    ops->remove_chanctx == ieee80211_emulate_remove_chanctx ||
 | 
				
			||||||
 | 
								    ops->change_chanctx == ieee80211_emulate_change_chanctx))
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							if (WARN_ON(!ops->add_chanctx ||
 | 
				
			||||||
 | 
								    !ops->remove_chanctx ||
 | 
				
			||||||
 | 
								    !ops->change_chanctx ||
 | 
				
			||||||
 | 
								    !ops->assign_vif_chanctx ||
 | 
				
			||||||
 | 
								    !ops->unassign_vif_chanctx))
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							emulate_chanctx = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Ensure 32-byte alignment of our private data and hw private data.
 | 
						/* Ensure 32-byte alignment of our private data and hw private data.
 | 
				
			||||||
	 * We use the wiphy priv data for both our ieee80211_local and for
 | 
						 * We use the wiphy priv data for both our ieee80211_local and for
 | 
				
			||||||
| 
						 | 
					@ -699,7 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 | 
				
			||||||
			WIPHY_FLAG_REPORTS_OBSS |
 | 
								WIPHY_FLAG_REPORTS_OBSS |
 | 
				
			||||||
			WIPHY_FLAG_OFFCHAN_TX;
 | 
								WIPHY_FLAG_OFFCHAN_TX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!use_chanctx || ops->remain_on_channel)
 | 
						if (emulate_chanctx || ops->remain_on_channel)
 | 
				
			||||||
		wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 | 
							wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
 | 
						wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
 | 
				
			||||||
| 
						 | 
					@ -756,7 +889,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 | 
				
			||||||
	local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
 | 
						local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local->ops = ops;
 | 
						local->ops = ops;
 | 
				
			||||||
	local->use_chanctx = use_chanctx;
 | 
						local->emulate_chanctx = emulate_chanctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (emulate_chanctx)
 | 
				
			||||||
 | 
							ieee80211_hw_set(&local->hw, CHANCTX_STA_CSA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We need a bit of data queued to build aggregates properly, so
 | 
						 * We need a bit of data queued to build aggregates properly, so
 | 
				
			||||||
| 
						 | 
					@ -833,7 +969,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 | 
				
			||||||
			ieee80211_dfs_radar_detected_work);
 | 
								ieee80211_dfs_radar_detected_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy_work_init(&local->reconfig_filter, ieee80211_reconfig_filter);
 | 
						wiphy_work_init(&local->reconfig_filter, ieee80211_reconfig_filter);
 | 
				
			||||||
	local->smps_mode = IEEE80211_SMPS_OFF;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy_work_init(&local->dynamic_ps_enable_work,
 | 
						wiphy_work_init(&local->dynamic_ps_enable_work,
 | 
				
			||||||
			ieee80211_dynamic_ps_enable_work);
 | 
								ieee80211_dynamic_ps_enable_work);
 | 
				
			||||||
| 
						 | 
					@ -984,7 +1119,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 | 
				
			||||||
		 * as much, e.g. monitoring beacons would be hard if we
 | 
							 * as much, e.g. monitoring beacons would be hard if we
 | 
				
			||||||
		 * might not even know which link is active at which time.
 | 
							 * might not even know which link is active at which time.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (WARN_ON(!local->use_chanctx))
 | 
							if (WARN_ON(local->emulate_chanctx))
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (WARN_ON(!local->ops->link_info_changed))
 | 
							if (WARN_ON(!local->ops->link_info_changed))
 | 
				
			||||||
| 
						 | 
					@ -1028,7 +1163,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx) {
 | 
						if (local->emulate_chanctx) {
 | 
				
			||||||
		for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
 | 
							for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
 | 
				
			||||||
			const struct ieee80211_iface_combination *comb;
 | 
								const struct ieee80211_iface_combination *comb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1094,11 +1229,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 | 
				
			||||||
						&sband->channels[i],
 | 
											&sband->channels[i],
 | 
				
			||||||
						NL80211_CHAN_NO_HT);
 | 
											NL80211_CHAN_NO_HT);
 | 
				
			||||||
			/* init channel we're on */
 | 
								/* init channel we're on */
 | 
				
			||||||
			if (!local->use_chanctx && !local->_oper_chandef.chan) {
 | 
					 | 
				
			||||||
				local->hw.conf.chandef = dflt_chandef;
 | 
					 | 
				
			||||||
				local->_oper_chandef = dflt_chandef;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			local->monitor_chandef = dflt_chandef;
 | 
								local->monitor_chandef = dflt_chandef;
 | 
				
			||||||
 | 
								if (local->emulate_chanctx) {
 | 
				
			||||||
 | 
									local->dflt_chandef = dflt_chandef;
 | 
				
			||||||
 | 
									local->hw.conf.chandef = dflt_chandef;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		channels += sband->n_channels;
 | 
							channels += sband->n_channels;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2287,8 +2287,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chanctx = container_of(conf, struct ieee80211_chanctx, conf);
 | 
						chanctx = container_of(conf, struct ieee80211_chanctx, conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (local->use_chanctx &&
 | 
						if (!ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) {
 | 
				
			||||||
	    !ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) {
 | 
					 | 
				
			||||||
		sdata_info(sdata,
 | 
							sdata_info(sdata,
 | 
				
			||||||
			   "driver doesn't support chan-switch with channel contexts\n");
 | 
								   "driver doesn't support chan-switch with channel contexts\n");
 | 
				
			||||||
		goto drop_connection;
 | 
							goto drop_connection;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON(local->use_chanctx))
 | 
						if (WARN_ON(!local->emulate_chanctx))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON(local->use_chanctx))
 | 
						if (WARN_ON(!local->emulate_chanctx))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(sdata, &local->interfaces, list) {
 | 
						list_for_each_entry(sdata, &local->interfaces, list) {
 | 
				
			||||||
| 
						 | 
					@ -351,10 +351,13 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local)
 | 
				
			||||||
		 * 20 MHz channel width) don't stop all the operations but still
 | 
							 * 20 MHz channel width) don't stop all the operations but still
 | 
				
			||||||
		 * treat it as though the ROC operation started properly, so
 | 
							 * treat it as though the ROC operation started properly, so
 | 
				
			||||||
		 * other ROC operations won't interfere with this one.
 | 
							 * other ROC operations won't interfere with this one.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * Note: scan can't run, tmp_channel is what we use, so this
 | 
				
			||||||
 | 
							 * must be the currently active channel.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		roc->on_channel = roc->chan == local->_oper_chandef.chan &&
 | 
							roc->on_channel = roc->chan == local->hw.conf.chandef.chan &&
 | 
				
			||||||
				  local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 &&
 | 
									  local->hw.conf.chandef.width != NL80211_CHAN_WIDTH_5 &&
 | 
				
			||||||
				  local->_oper_chandef.width != NL80211_CHAN_WIDTH_10;
 | 
									  local->hw.conf.chandef.width != NL80211_CHAN_WIDTH_10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* start this ROC */
 | 
							/* start this ROC */
 | 
				
			||||||
		ieee80211_recalc_idle(local);
 | 
							ieee80211_recalc_idle(local);
 | 
				
			||||||
| 
						 | 
					@ -363,7 +366,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local)
 | 
				
			||||||
			ieee80211_offchannel_stop_vifs(local);
 | 
								ieee80211_offchannel_stop_vifs(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			local->tmp_channel = roc->chan;
 | 
								local->tmp_channel = roc->chan;
 | 
				
			||||||
			ieee80211_hw_config(local, 0);
 | 
								ieee80211_hw_conf_chan(local);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
 | 
							wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
 | 
				
			||||||
| 
						 | 
					@ -426,7 +429,7 @@ static void __ieee80211_roc_work(struct ieee80211_local *local)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!roc->started) {
 | 
						if (!roc->started) {
 | 
				
			||||||
		WARN_ON(local->use_chanctx);
 | 
							WARN_ON(!local->emulate_chanctx);
 | 
				
			||||||
		_ieee80211_start_next_roc(local);
 | 
							_ieee80211_start_next_roc(local);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		on_channel = roc->on_channel;
 | 
							on_channel = roc->on_channel;
 | 
				
			||||||
| 
						 | 
					@ -439,7 +442,7 @@ static void __ieee80211_roc_work(struct ieee80211_local *local)
 | 
				
			||||||
			ieee80211_flush_queues(local, NULL, false);
 | 
								ieee80211_flush_queues(local, NULL, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			local->tmp_channel = NULL;
 | 
								local->tmp_channel = NULL;
 | 
				
			||||||
			ieee80211_hw_config(local, 0);
 | 
								ieee80211_hw_conf_chan(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ieee80211_offchannel_return(local);
 | 
								ieee80211_offchannel_return(local);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -539,7 +542,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
 | 
				
			||||||
		/* this may work, but is untested */
 | 
							/* this may work, but is untested */
 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (local->use_chanctx && !local->ops->remain_on_channel)
 | 
						if (!local->emulate_chanctx && !local->ops->remain_on_channel)
 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	roc = kzalloc(sizeof(*roc), GFP_KERNEL);
 | 
						roc = kzalloc(sizeof(*roc), GFP_KERNEL);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -476,7 +476,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set power back to normal operating levels. */
 | 
						/* Set power back to normal operating levels. */
 | 
				
			||||||
	ieee80211_hw_config(local, 0);
 | 
						ieee80211_hw_conf_chan(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!hw_scan && was_scanning) {
 | 
						if (!hw_scan && was_scanning) {
 | 
				
			||||||
		ieee80211_configure_filter(local);
 | 
							ieee80211_configure_filter(local);
 | 
				
			||||||
| 
						 | 
					@ -523,7 +523,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
 | 
				
			||||||
				   struct ieee80211_sub_if_data *sdata)
 | 
									   struct ieee80211_sub_if_data *sdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Software scan is not supported in multi-channel cases */
 | 
						/* Software scan is not supported in multi-channel cases */
 | 
				
			||||||
	if (local->use_chanctx)
 | 
						if (!local->emulate_chanctx)
 | 
				
			||||||
		return -EOPNOTSUPP;
 | 
							return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -553,7 +553,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local,
 | 
				
			||||||
	ieee80211_configure_filter(local);
 | 
						ieee80211_configure_filter(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We need to set power level at maximum rate for scanning. */
 | 
						/* We need to set power level at maximum rate for scanning. */
 | 
				
			||||||
	ieee80211_hw_config(local, 0);
 | 
						ieee80211_hw_conf_chan(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
 | 
						wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -790,7 +790,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
	if (hw_scan) {
 | 
						if (hw_scan) {
 | 
				
			||||||
		__set_bit(SCAN_HW_SCANNING, &local->scanning);
 | 
							__set_bit(SCAN_HW_SCANNING, &local->scanning);
 | 
				
			||||||
	} else if ((req->n_channels == 1) &&
 | 
						} else if ((req->n_channels == 1) &&
 | 
				
			||||||
		   (req->channels[0] == local->_oper_chandef.chan)) {
 | 
							   (req->channels[0] == local->hw.conf.chandef.chan)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * If we are scanning only on the operating channel
 | 
							 * If we are scanning only on the operating channel
 | 
				
			||||||
		 * then we do not need to stop normal activities
 | 
							 * then we do not need to stop normal activities
 | 
				
			||||||
| 
						 | 
					@ -808,7 +808,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 | 
				
			||||||
		ieee80211_configure_filter(local); /* accept probe-responses */
 | 
							ieee80211_configure_filter(local); /* accept probe-responses */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* We need to ensure power level is at max for scanning. */
 | 
							/* We need to ensure power level is at max for scanning. */
 | 
				
			||||||
		ieee80211_hw_config(local, 0);
 | 
							ieee80211_hw_conf_chan(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((req->channels[0]->flags & (IEEE80211_CHAN_NO_IR |
 | 
							if ((req->channels[0]->flags & (IEEE80211_CHAN_NO_IR |
 | 
				
			||||||
						IEEE80211_CHAN_RADAR)) ||
 | 
											IEEE80211_CHAN_RADAR)) ||
 | 
				
			||||||
| 
						 | 
					@ -973,13 +973,13 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 | 
				
			||||||
	/* If scanning on oper channel, use whatever channel-type
 | 
						/* If scanning on oper channel, use whatever channel-type
 | 
				
			||||||
	 * is currently in use.
 | 
						 * is currently in use.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (chan == local->_oper_chandef.chan)
 | 
						if (chan == local->hw.conf.chandef.chan)
 | 
				
			||||||
		local->scan_chandef = local->_oper_chandef;
 | 
							local->scan_chandef = local->hw.conf.chandef;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
 | 
							local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set_channel:
 | 
					set_channel:
 | 
				
			||||||
	if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
 | 
						if (ieee80211_hw_conf_chan(local))
 | 
				
			||||||
		skip = 1;
 | 
							skip = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* advance state machine to next channel/band */
 | 
						/* advance state machine to next channel/band */
 | 
				
			||||||
| 
						 | 
					@ -1023,7 +1023,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* switch back to the operating channel */
 | 
						/* switch back to the operating channel */
 | 
				
			||||||
	local->scan_chandef.chan = NULL;
 | 
						local->scan_chandef.chan = NULL;
 | 
				
			||||||
	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 | 
						ieee80211_hw_conf_chan(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* disable PS */
 | 
						/* disable PS */
 | 
				
			||||||
	ieee80211_offchannel_return(local);
 | 
						ieee80211_offchannel_return(local);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2390,8 +2390,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chanctx_conf)
 | 
						if (chanctx_conf)
 | 
				
			||||||
		chandef = &chanctx_conf->def;
 | 
							chandef = &chanctx_conf->def;
 | 
				
			||||||
	else if (!local->use_chanctx)
 | 
					 | 
				
			||||||
		chandef = &local->_oper_chandef;
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		goto fail_rcu;
 | 
							goto fail_rcu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2472,9 +2472,6 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						lockdep_assert_wiphy(local->hw.wiphy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!local->use_chanctx)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	conf = rcu_dereference_protected(link->conf->chanctx_conf,
 | 
						conf = rcu_dereference_protected(link->conf->chanctx_conf,
 | 
				
			||||||
					 lockdep_is_held(&local->hw.wiphy->mtx));
 | 
										 lockdep_is_held(&local->hw.wiphy->mtx));
 | 
				
			||||||
	if (conf) {
 | 
						if (conf) {
 | 
				
			||||||
| 
						 | 
					@ -2704,20 +2701,20 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* add channel contexts */
 | 
						/* add channel contexts */
 | 
				
			||||||
	if (local->use_chanctx) {
 | 
						list_for_each_entry(ctx, &local->chanctx_list, list)
 | 
				
			||||||
		list_for_each_entry(ctx, &local->chanctx_list, list)
 | 
							if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
 | 
				
			||||||
			if (ctx->replace_state !=
 | 
								WARN_ON(drv_add_chanctx(local, ctx));
 | 
				
			||||||
			    IEEE80211_CHANCTX_REPLACES_OTHER)
 | 
					 | 
				
			||||||
				WARN_ON(drv_add_chanctx(local, ctx));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sdata = wiphy_dereference(local->hw.wiphy,
 | 
						sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
 | 
				
			||||||
					  local->monitor_sdata);
 | 
						if (sdata && ieee80211_sdata_running(sdata))
 | 
				
			||||||
		if (sdata && ieee80211_sdata_running(sdata))
 | 
							ieee80211_assign_chanctx(local, sdata, &sdata->deflink);
 | 
				
			||||||
			ieee80211_assign_chanctx(local, sdata, &sdata->deflink);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reconfigure hardware */
 | 
						/* reconfigure hardware */
 | 
				
			||||||
	ieee80211_hw_config(local, ~0);
 | 
						ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_LISTEN_INTERVAL |
 | 
				
			||||||
 | 
									   IEEE80211_CONF_CHANGE_MONITOR |
 | 
				
			||||||
 | 
									   IEEE80211_CONF_CHANGE_PS |
 | 
				
			||||||
 | 
									   IEEE80211_CONF_CHANGE_RETRY_LIMITS |
 | 
				
			||||||
 | 
									   IEEE80211_CONF_CHANGE_IDLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_configure_filter(local);
 | 
						ieee80211_configure_filter(local);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue