示例#1
0
static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
					  struct ieee80211_vif *vif)
{
	struct rt2x00_dev *rt2x00dev = data;
	struct rt2x00_intf *intf = vif_to_intf(vif);
	int delayed_flags;

	/*
	 * Copy all data we need during this action under the protection
	 * of a spinlock. Otherwise race conditions might occur which results
	 * into an invalid configuration.
	 */
	spin_lock(&intf->lock);

	delayed_flags = intf->delayed_flags;
	intf->delayed_flags = 0;

	spin_unlock(&intf->lock);

	/*
	 * It is possible the radio was disabled while the work had been
	 * scheduled. If that happens we should return here immediately,
	 * note that in the spinlock protected area above the delayed_flags
	 * have been cleared correctly.
	 */
	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
		return;

	if (delayed_flags & DELAYED_UPDATE_BEACON)
		rt2x00queue_update_beacon(rt2x00dev, vif, true);
}
示例#2
0
static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
					struct ieee80211_vif *vif)
{
	struct rt2x00_dev *rt2x00dev = data;

	if (vif->type != NL80211_IFTYPE_AP &&
	    vif->type != NL80211_IFTYPE_ADHOC &&
	    vif->type != NL80211_IFTYPE_MESH_POINT &&
	    vif->type != NL80211_IFTYPE_WDS)
		return;

	rt2x00queue_update_beacon(rt2x00dev, vif, true);
}
int rt2x00mac_config_interface(struct ieee80211_hw *hw,
			       struct ieee80211_vif *vif,
			       struct ieee80211_if_conf *conf)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;
	struct rt2x00_intf *intf = vif_to_intf(vif);
	int update_bssid = 0;
	int status = 0;

	/*
	 * Mac80211 might be calling this function while we are trying
	 * to remove the device or perhaps suspending it.
	 */
	if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
		return 0;

	spin_lock(&intf->lock);

	/*
	 * conf->bssid can be NULL if coming from the internal
	 * beacon update routine.
	 */
	if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
		update_bssid = 1;
		memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
	}

	spin_unlock(&intf->lock);

	/*
	 * Call rt2x00_config_intf() outside of the spinlock context since
	 * the call will sleep for USB drivers. By using the ieee80211_if_conf
	 * values as arguments we make keep access to rt2x00_intf thread safe
	 * even without the lock.
	 */
	rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
			      update_bssid ? conf->bssid : NULL);

	/*
	 * Update the beacon.
	 */
	if (conf->changed & IEEE80211_IFCC_BEACON)
		status = rt2x00queue_update_beacon(rt2x00dev, vif);

	return status;
}
static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
					  struct ieee80211_vif *vif)
{
	struct rt2x00_dev *rt2x00dev = data;
	struct rt2x00_intf *intf = vif_to_intf(vif);

	/*
	 * It is possible the radio was disabled while the work had been
	 * scheduled. If that happens we should return here immediately,
	 * note that in the spinlock protected area above the delayed_flags
	 * have been cleared correctly.
	 */
	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
		return;

	if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
		rt2x00queue_update_beacon(rt2x00dev, vif);
}
示例#5
0
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
				struct ieee80211_vif *vif,
				struct ieee80211_bss_conf *bss_conf,
				u32 changes)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;
	struct rt2x00_intf *intf = vif_to_intf(vif);

	/*
	 * mac80211 might be calling this function while we are trying
	 * to remove the device or perhaps suspending it.
	 */
	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
		return;

	/*
	 * Update the BSSID.
	 */
	if (changes & BSS_CHANGED_BSSID)
		rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
				      bss_conf->bssid);

	/*
	 * Start/stop beaconing.
	 */
	if (changes & BSS_CHANGED_BEACON_ENABLED) {
		if (!bss_conf->enable_beacon && intf->enable_beacon) {
			rt2x00dev->intf_beaconing--;
			intf->enable_beacon = false;
			/*
			 * Clear beacon in the H/W for this vif. This is needed
			 * to disable beaconing on this particular interface
			 * and keep it running on other interfaces.
			 */
			rt2x00queue_clear_beacon(rt2x00dev, vif);

			if (rt2x00dev->intf_beaconing == 0) {
				/*
				 * Last beaconing interface disabled
				 * -> stop beacon queue.
				 */
				mutex_lock(&intf->beacon_skb_mutex);
				rt2x00queue_stop_queue(rt2x00dev->bcn);
				mutex_unlock(&intf->beacon_skb_mutex);
			}
		} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
			rt2x00dev->intf_beaconing++;
			intf->enable_beacon = true;
			/*
			 * Upload beacon to the H/W. This is only required on
			 * USB devices. PCI devices fetch beacons periodically.
			 */
			if (rt2x00_is_usb(rt2x00dev))
				rt2x00queue_update_beacon(rt2x00dev, vif);

			if (rt2x00dev->intf_beaconing == 1) {
				/*
				 * First beaconing interface enabled
				 * -> start beacon queue.
				 */
				mutex_lock(&intf->beacon_skb_mutex);
				rt2x00queue_start_queue(rt2x00dev->bcn);
				mutex_unlock(&intf->beacon_skb_mutex);
			}
		}
	}

	/*
	 * When the association status has changed we must reset the link
	 * tuner counter. This is because some drivers determine if they
	 * should perform link tuning based on the number of seconds
	 * while associated or not associated.
	 */
	if (changes & BSS_CHANGED_ASSOC) {
		rt2x00dev->link.count = 0;

		if (bss_conf->assoc)
			rt2x00dev->intf_associated++;
		else
			rt2x00dev->intf_associated--;

		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);

		clear_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags);
	}

	/*
	 * Check for access point which do not support 802.11e . We have to
	 * generate data frames sequence number in S/W for such AP, because
	 * of H/W bug.
	 */
	if (changes & BSS_CHANGED_QOS && !bss_conf->qos)
		set_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags);

	/*
	 * When the erp information has changed, we should perform
	 * additional configuration steps. For all other changes we are done.
	 */
	if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
		       BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
		       BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
		rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
}
示例#6
0
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
				struct ieee80211_vif *vif,
				struct ieee80211_bss_conf *bss_conf,
				u32 changes)
{
	struct rt2x00_dev *rt2x00dev = hw->priv;
	struct rt2x00_intf *intf = vif_to_intf(vif);

	/*
	 * mac80211 might be calling this function while we are trying
	 * to remove the device or perhaps suspending it.
	 */
	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
		return;

	spin_lock(&intf->lock);

	/*
	 * conf->bssid can be NULL if coming from the internal
	 * beacon update routine.
	 */
	if (changes & BSS_CHANGED_BSSID)
		memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);

	spin_unlock(&intf->lock);

	/*
	 * Call rt2x00_config_intf() outside of the spinlock context since
	 * the call will sleep for USB drivers. By using the ieee80211_if_conf
	 * values as arguments we make keep access to rt2x00_intf thread safe
	 * even without the lock.
	 */
	if (changes & BSS_CHANGED_BSSID)
		rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
				      bss_conf->bssid);

	/*
	 * Update the beacon.
	 */
	if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED))
		rt2x00queue_update_beacon(rt2x00dev, vif,
					  bss_conf->enable_beacon);

	/*
	 * When the association status has changed we must reset the link
	 * tuner counter. This is because some drivers determine if they
	 * should perform link tuning based on the number of seconds
	 * while associated or not associated.
	 */
	if (changes & BSS_CHANGED_ASSOC) {
		rt2x00dev->link.count = 0;

		if (bss_conf->assoc)
			rt2x00dev->intf_associated++;
		else
			rt2x00dev->intf_associated--;

		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
	}

	/*
	 * When the erp information has changed, we should perform
	 * additional configuration steps. For all other changes we are done.
	 */
	if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
		       BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
		       BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
		rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
}