Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19ad0715 authored by Juuso Oikarinen's avatar Juuso Oikarinen Committed by John W. Linville
Browse files

wl1271: Add retry implementation for PSM entries



PSM entries can fail (transmitting the corresponding null-func may not
be heard by the AP.) Previously, this scenario was not detected, and
out-of-sync between STA and AP could occur.

Add retry implementation for the entries to recover from the situation.

Signed-off-by: default avatarJuuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3b775b4b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -417,6 +417,9 @@ struct wl1271 {
	/* PSM mode requested */
	bool psm_requested;

	/* retry counter for PSM entries */
	u8 psm_entry_retry;

	/* in dBm */
	int power_level;

+2 −1
Original line number Diff line number Diff line
@@ -407,7 +407,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)

	/* unmask required mbox events  */
	wl->event_mask = BSS_LOSE_EVENT_ID |
		SCAN_COMPLETE_EVENT_ID;
		SCAN_COMPLETE_EVENT_ID |
		PS_REPORT_EVENT_ID;

	ret = wl1271_event_unmask(wl);
	if (ret < 0) {
+8 −0
Original line number Diff line number Diff line
@@ -712,6 +712,14 @@ struct conf_conn_settings {
	 * Range 0 - 255
	 */
	u8 bet_max_consecutive;

	/*
	 * Specifies the maximum number of times to try PSM entry if it fails
	 * (if sending the appropriate null-func message fails.)
	 *
	 * Range 0 - 255
	 */
	u8 psm_entry_retries;
};

#define CONF_SR_ERR_TBL_MAX_VALUES   14
+53 −0
Original line number Diff line number Diff line
@@ -68,6 +68,40 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
	return 0;
}

static int wl1271_event_ps_report(struct wl1271 *wl,
				  struct event_mailbox *mbox,
				  bool *beacon_loss)
{
	int ret = 0;

	wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);

	switch (mbox->ps_status) {
	case EVENT_ENTER_POWER_SAVE_FAIL:
		if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
			wl->psm_entry_retry++;
			wl1271_error("PSM entry failed, retrying %d\n",
				     wl->psm_entry_retry);
			ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
		} else {
			wl->psm_entry_retry = 0;
			*beacon_loss = true;
		}
		break;
	case EVENT_ENTER_POWER_SAVE_SUCCESS:
		wl->psm_entry_retry = 0;
		break;
	case EVENT_EXIT_POWER_SAVE_FAIL:
		wl1271_info("PSM exit failed");
		break;
	case EVENT_EXIT_POWER_SAVE_SUCCESS:
	default:
		break;
	}

	return ret;
}

static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
{
	wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -79,6 +113,7 @@ 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);

@@ -101,7 +136,25 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
		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;
+7 −0
Original line number Diff line number Diff line
@@ -63,6 +63,13 @@ enum {
	EVENT_MBOX_ALL_EVENT_ID			 = 0x7fffffff,
};

enum {
	EVENT_ENTER_POWER_SAVE_FAIL = 0,
	EVENT_ENTER_POWER_SAVE_SUCCESS,
	EVENT_EXIT_POWER_SAVE_FAIL,
	EVENT_EXIT_POWER_SAVE_SUCCESS,
};

struct event_debug_report {
	u8 debug_event_id;
	u8 num_params;
Loading