static ssize_t ieee80211_if_parse_beacon_loss(
	struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
{
	if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc)
		return -ENOTCONN;

	ieee80211_beacon_loss(&sdata->vif);

	return buflen;
}
static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
{
	int ret;
	u32 vector;
	bool beacon_loss = false;

	wl1271_event_mbox_dump(mbox);

	vector = le32_to_cpu(mbox->events_vector);
	vector &= ~(le32_to_cpu(mbox->events_mask));
	wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);

	if (vector & SCAN_COMPLETE_EVENT_ID) {
		ret = wl1271_event_scan_complete(wl, mbox);
		if (ret < 0)
			return ret;
	}

	/*
	 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
	 * filtering) is enabled. Without PSM, the stack will receive all
	 * beacons and can detect beacon loss by itself.
	 */
	if (vector & BSS_LOSE_EVENT_ID && wl->psm) {
		wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");

		/* indicate to the stack, that beacons have been lost */
		beacon_loss = true;
	}

	if (vector & PS_REPORT_EVENT_ID) {
		wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
		ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
		if (ret < 0)
			return ret;
	}

	if (beacon_loss) {
		/* Obviously, it's dangerous to release the mutex while
		   we are holding many of the variables in the wl struct.
		   That's why it's done last in the function, and care must
		   be taken that nothing more is done after this function
		   returns. */
		mutex_unlock(&wl->mutex);
		ieee80211_beacon_loss(wl->vif);
		mutex_lock(&wl->mutex);
	}

	return 0;
}
Example #3
0
File: event.c Project: 020gzh/linux
static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
{
	int ret;
	u32 vector;

	wl1251_event_mbox_dump(mbox);

	vector = mbox->events_vector & ~(mbox->events_mask);
	wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);

	if (vector & SCAN_COMPLETE_EVENT_ID) {
		ret = wl1251_event_scan_complete(wl, mbox);
		if (ret < 0)
			return ret;
	}

	if (vector & BSS_LOSE_EVENT_ID) {
		wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");

		if (wl->psm_requested &&
		    wl->station_mode != STATION_ACTIVE_MODE) {
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
			if (ret < 0)
				return ret;
		}
	}

	if (vector & PS_REPORT_EVENT_ID) {
		wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
		ret = wl1251_event_ps_report(wl, mbox);
		if (ret < 0)
			return ret;
	}

	if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
		wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");

		/* indicate to the stack, that beacons have been lost */
		if (wl->vif && wl->vif->type == NL80211_IFTYPE_STATION)
			ieee80211_beacon_loss(wl->vif);
	}

	if (vector & REGAINED_BSS_EVENT_ID) {
		if (wl->psm_requested) {
			ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
			if (ret < 0)
				return ret;
		}
	}

	if (wl->vif && wl->rssi_thold) {
		if (vector & ROAMING_TRIGGER_LOW_RSSI_EVENT_ID) {
			wl1251_debug(DEBUG_EVENT,
				     "ROAMING_TRIGGER_LOW_RSSI_EVENT");
			ieee80211_cqm_rssi_notify(wl->vif,
				NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
				GFP_KERNEL);
		}

		if (vector & ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID) {
			wl1251_debug(DEBUG_EVENT,
				     "ROAMING_TRIGGER_REGAINED_RSSI_EVENT");
			ieee80211_cqm_rssi_notify(wl->vif,
				NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
				GFP_KERNEL);
		}
	}

	return 0;
}
Example #4
0
static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
{
	int ret;
	u32 vector;

	vector = mbox->events_vector & ~(mbox->events_mask);

	if (vector & SCAN_COMPLETE_EVENT_ID) {
		ret = wl1251_event_scan_complete(wl, mbox);
		if (ret < 0)
			return ret;
	}

	if (vector & BSS_LOSE_EVENT_ID) {
		wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");

		if (wl->psm_requested && wl->psm) {
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
			if (ret < 0)
				return ret;
		}
	}

	if (vector & PS_REPORT_EVENT_ID) {
		wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT_ID");
		ret = wl1251_event_ps_report(wl, mbox);
		if (ret < 0)
			return ret;
	}

	if (wl->vif && (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID)) {
		wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
		/* need to unlock mutex to avoid deadlocking with rtnl */
		mutex_unlock(&wl->mutex);

		/* indicate to the stack, that beacons have been lost */
		ieee80211_beacon_loss(wl->vif);
		mutex_lock(&wl->mutex);
	}

	if (vector & REGAINED_BSS_EVENT_ID) {
		if (wl->psm_requested) {
			ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
			if (ret < 0)
				return ret;
		}
	}

	if (wl->vif && (vector & ROAMING_TRIGGER_LOW_RSSI_EVENT_ID)) {
		wl1251_debug(DEBUG_EVENT, "ROAMING_TRIGGER_LOW_RSSI_EVENT");
		ieee80211_rssi_changed(wl->vif, IEEE80211_RSSI_STATE_LOW);
	}

	if (wl->vif && (vector & ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID)) {
		wl1251_debug(DEBUG_EVENT,
			     "ROAMING_TRIGGER_REGAINED_RSSI_EVENT");
		ieee80211_rssi_changed(wl->vif, IEEE80211_RSSI_STATE_HIGH);
	}

	return 0;
}