diff options
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 96 |
1 files changed, 82 insertions, 14 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 7cd5f56662f..6f8cb3ee6fe 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -291,7 +291,8 @@ struct mac80211_hwsim_data { struct ieee80211_channel *channel; unsigned long beacon_int; /* in jiffies unit */ unsigned int rx_filter; - bool started, idle; + bool started, idle, scanning; + struct mutex mutex; struct timer_list beacon_timer; enum ps_mode { PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL @@ -651,17 +652,17 @@ static void mac80211_hwsim_beacon(unsigned long arg) add_timer(&data->beacon_timer); } +static const char *hwsim_chantypes[] = { + [NL80211_CHAN_NO_HT] = "noht", + [NL80211_CHAN_HT20] = "ht20", + [NL80211_CHAN_HT40MINUS] = "ht40-", + [NL80211_CHAN_HT40PLUS] = "ht40+", +}; static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) { struct mac80211_hwsim_data *data = hw->priv; struct ieee80211_conf *conf = &hw->conf; - static const char *chantypes[4] = { - [NL80211_CHAN_NO_HT] = "noht", - [NL80211_CHAN_HT20] = "ht20", - [NL80211_CHAN_HT40MINUS] = "ht40-", - [NL80211_CHAN_HT40PLUS] = "ht40+", - }; static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = { [IEEE80211_SMPS_AUTOMATIC] = "auto", [IEEE80211_SMPS_OFF] = "off", @@ -672,7 +673,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", wiphy_name(hw->wiphy), __func__, conf->channel->center_freq, - chantypes[conf->channel_type], + hwsim_chantypes[conf->channel_type], !!(conf->flags & IEEE80211_CONF_IDLE), !!(conf->flags & IEEE80211_CONF_PS), smps_modes[conf->smps_mode]); @@ -760,9 +761,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n", + printk(KERN_DEBUG " %s: HT: op_mode=0x%x, chantype=%s\n", wiphy_name(hw->wiphy), - info->ht_operation_mode); + info->ht_operation_mode, + hwsim_chantypes[info->channel_type]); } if (changed & BSS_CHANGED_BASIC_RATES) { @@ -829,6 +831,33 @@ static int mac80211_hwsim_conf_tx( return 0; } +static int mac80211_hwsim_get_survey( + struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ieee80211_conf *conf = &hw->conf; + + printk(KERN_DEBUG "%s:%s (idx=%d)\n", + wiphy_name(hw->wiphy), __func__, idx); + + if (idx != 0) + return -ENOENT; + + /* Current channel */ + survey->channel = conf->channel; + + /* + * Magically conjured noise level --- this is only ok for simulated hardware. + * + * A real driver which cannot determine the real channel noise MUST NOT + * report any noise, especially not a magically conjured one :-) + */ + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = -92; + + return 0; +} + #ifdef CONFIG_NL80211_TESTMODE /* * This section contains example code for using netlink @@ -946,6 +975,7 @@ static void hw_scan_done(struct work_struct *work) } static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); @@ -957,9 +987,9 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, hsd->hw = hw; INIT_DELAYED_WORK(&hsd->w, hw_scan_done); - printk(KERN_DEBUG "hwsim scan request\n"); + printk(KERN_DEBUG "hwsim hw_scan request\n"); for (i = 0; i < req->n_channels; i++) - printk(KERN_DEBUG "hwsim scan freq %d\n", + printk(KERN_DEBUG "hwsim hw_scan freq %d\n", req->channels[i]->center_freq); ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); @@ -967,6 +997,36 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, return 0; } +static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) +{ + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + + if (hwsim->scanning) { + printk(KERN_DEBUG "two hwsim sw_scans detected!\n"); + goto out; + } + + printk(KERN_DEBUG "hwsim sw_scan request, prepping stuff\n"); + hwsim->scanning = true; + +out: + mutex_unlock(&hwsim->mutex); +} + +static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + + printk(KERN_DEBUG "hwsim sw_scan_complete\n"); + hwsim->scanning = false; + + mutex_unlock(&hwsim->mutex); +} + static struct ieee80211_ops mac80211_hwsim_ops = { .tx = mac80211_hwsim_tx, @@ -982,8 +1042,11 @@ static struct ieee80211_ops mac80211_hwsim_ops = .sta_notify = mac80211_hwsim_sta_notify, .set_tim = mac80211_hwsim_set_tim, .conf_tx = mac80211_hwsim_conf_tx, + .get_survey = mac80211_hwsim_get_survey, CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) .ampdu_action = mac80211_hwsim_ampdu_action, + .sw_scan_start = mac80211_hwsim_sw_scan, + .sw_scan_complete = mac80211_hwsim_sw_scan_complete, .flush = mac80211_hwsim_flush, }; @@ -1179,8 +1242,11 @@ static int __init init_mac80211_hwsim(void) if (radios < 1 || radios > 100) return -EINVAL; - if (fake_hw_scan) + if (fake_hw_scan) { mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; + mac80211_hwsim_ops.sw_scan_start = NULL; + mac80211_hwsim_ops.sw_scan_complete = NULL; + } spin_lock_init(&hwsim_radio_lock); INIT_LIST_HEAD(&hwsim_radios); @@ -1235,7 +1301,8 @@ static int __init init_mac80211_hwsim(void) hw->flags = IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_STATIC_SMPS | - IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; + IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | + IEEE80211_HW_AMPDU_AGGREGATION; /* ask mac80211 to reserve space for magic */ hw->vif_data_size = sizeof(struct hwsim_vif_priv); @@ -1285,6 +1352,7 @@ static int __init init_mac80211_hwsim(void) } /* By default all radios are belonging to the first group */ data->group = 1; + mutex_init(&data->mutex); /* Work to be done prior to ieee80211_register_hw() */ switch (regtest) { |