Hi John,
Here are some more patches for the wl1271 driver. A few small issues have been fixed and some other improvements.
Cheers,
Luca.
Juuso Oikarinen (6):
wl1271: Remove excess null-data template settings
wl1271: Increase TX power value
wl1271: Check result code of commands
wl1271: Add retry implementation for PSM entries
wl1271: Correct endianness-handling of command status
wl1271: Generalize command response reading
drivers/net/wireless/wl12xx/wl1271.h | 3 +
drivers/net/wireless/wl12xx/wl1271_acx.c | 2 +-
drivers/net/wireless/wl12xx/wl1271_boot.c | 3 +-
drivers/net/wireless/wl12xx/wl1271_cmd.c | 99 ++++++++++------------------
drivers/net/wireless/wl12xx/wl1271_cmd.h | 3 +-
drivers/net/wireless/wl12xx/wl1271_conf.h | 8 ++
drivers/net/wireless/wl12xx/wl1271_event.c | 53 +++++++++++++++
drivers/net/wireless/wl12xx/wl1271_event.h | 7 ++
drivers/net/wireless/wl12xx/wl1271_init.c | 7 ++-
drivers/net/wireless/wl12xx/wl1271_main.c | 19 +++---
10 files changed, 126 insertions(+), 78 deletions(-)
From: Juuso Oikarinen <[email protected]>
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: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271.h | 3 ++
drivers/net/wireless/wl12xx/wl1271_boot.c | 3 +-
drivers/net/wireless/wl12xx/wl1271_conf.h | 8 ++++
drivers/net/wireless/wl12xx/wl1271_event.c | 53 ++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/wl1271_event.h | 7 ++++
drivers/net/wireless/wl12xx/wl1271_main.c | 5 ++-
6 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 566f152..94359b1 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -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;
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 8678bea..b7c9645 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -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) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 061d475..565373e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -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
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 31d396b..e135d89 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -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;
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 3ab53d3..4e3f55e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -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;
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 0ae506a..d2149fc 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -222,7 +222,8 @@ static struct conf_drv_settings default_conf = {
.snr_pkt_avg_weight = 10
},
.bet_enable = CONF_BET_MODE_ENABLE,
- .bet_max_consecutive = 100
+ .bet_max_consecutive = 100,
+ .psm_entry_retries = 3
},
.init = {
.sr_err_tbl = {
@@ -973,6 +974,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
wl->rx_counter = 0;
wl->elp = false;
wl->psm = 0;
+ wl->psm_entry_retry = 0;
wl->tx_queue_stopped = false;
wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
wl->tx_blocks_available = 0;
@@ -1822,6 +1824,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
wl->elp = false;
wl->psm = 0;
wl->psm_requested = false;
+ wl->psm_entry_retry = 0;
wl->tx_queue_stopped = false;
wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;
--
1.5.6.5
From: Juuso Oikarinen <[email protected]>
Responses to firmware commands are read in by the command transmission
function, as part of command flow. Previously responses were read in
multiple places.
Signed-off-by: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271_cmd.c | 67 ++++++++++++------------------
drivers/net/wireless/wl12xx/wl1271_cmd.h | 3 +-
2 files changed, 29 insertions(+), 41 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 8acee5c..990eb01 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -42,7 +42,8 @@
* @buf: buffer containing the command, must work with dma
* @len: length of the buffer
*/
-int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
+int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
+ size_t res_len)
{
struct wl1271_cmd_header *cmd;
unsigned long timeout;
@@ -76,8 +77,9 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
}
/* read back the status code of the command */
- wl1271_spi_read(wl, wl->cmd_box_addr, cmd,
- sizeof(struct wl1271_cmd_header), false);
+ if (res_len == 0)
+ res_len = sizeof(struct wl1271_cmd_header);
+ wl1271_spi_read(wl, wl->cmd_box_addr, cmd, res_len, false);
status = le16_to_cpu(cmd->status);
if (status != CMD_STATUS_SUCCESS) {
@@ -273,7 +275,7 @@ int wl1271_cmd_join(struct wl1271 *wl)
wl->tx_security_seq_16 = 0;
wl->tx_security_seq_32 = 0;
- ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
+ ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
if (ret < 0) {
wl1271_error("failed to initiate cmd join");
goto out_free;
@@ -305,30 +307,21 @@ out:
int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
{
int ret;
+ size_t res_len = 0;
wl1271_debug(DEBUG_CMD, "cmd test");
- ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len);
+ if (answer)
+ res_len = buf_len;
+
+ ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len);
if (ret < 0) {
wl1271_warning("TEST command failed");
return ret;
}
- if (answer) {
- struct wl1271_command *cmd_answer;
-
- /*
- * The test command got in, we can read the answer.
- * The answer would be a wl1271_command, where the
- * parameter array contains the actual answer.
- */
- wl1271_spi_read(wl, wl->cmd_box_addr, buf, buf_len, false);
-
- cmd_answer = buf;
- }
-
- return 0;
+ return ret;
}
/**
@@ -351,16 +344,10 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
/* payload length, does not include any headers */
acx->len = cpu_to_le16(len - sizeof(*acx));
- ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
- if (ret < 0) {
+ ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len);
+ if (ret < 0)
wl1271_error("INTERROGATE command failed");
- goto out;
- }
-
- /* the interrogate command got in, we can read the answer */
- wl1271_spi_read(wl, wl->cmd_box_addr, buf, len, false);
-out:
return ret;
}
@@ -384,7 +371,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
/* payload length, does not include any headers */
acx->len = cpu_to_le16(len - sizeof(*acx));
- ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len);
+ ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0);
if (ret < 0) {
wl1271_warning("CONFIGURE command NOK");
return ret;
@@ -417,7 +404,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
cmd_tx = CMD_DISABLE_TX;
}
- ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("rx %s cmd for channel %d failed",
enable ? "start" : "stop", channel);
@@ -427,7 +414,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
enable ? "start" : "stop", channel);
- ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("tx %s cmd for channel %d failed",
enable ? "start" : "stop", channel);
@@ -469,7 +456,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
- sizeof(*ps_params));
+ sizeof(*ps_params), 0);
if (ret < 0) {
wl1271_error("cmd set_ps_mode failed");
goto out;
@@ -500,14 +487,14 @@ int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
cmd->addr = cpu_to_le32(addr);
cmd->size = cpu_to_le32(len);
- ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
+ sizeof(*cmd));
if (ret < 0) {
wl1271_error("read memory command failed: %d", ret);
goto out;
}
- /* the read command got in, we can now read the answer */
- wl1271_spi_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd), false);
+ /* the read command got in */
memcpy(answer, cmd->value, len);
out:
@@ -609,7 +596,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
trigger->timeout = 0;
ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
- sizeof(*trigger));
+ sizeof(*trigger), 0);
if (ret < 0) {
wl1271_error("trigger scan to failed for hw scan");
goto out;
@@ -632,7 +619,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
}
}
- ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+ ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
if (ret < 0) {
wl1271_error("SCAN failed");
wl->scanning = false;
@@ -670,7 +657,7 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
if (buf)
memcpy(cmd->template_data, buf, buf_len);
- ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_warning("cmd set_template failed: %d", ret);
goto out_free;
@@ -849,7 +836,7 @@ int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
cmd->key_action = cpu_to_le16(KEY_SET_ID);
cmd->key_type = KEY_WEP;
- ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_warning("cmd set_default_wep_key failed: %d", ret);
goto out;
@@ -906,7 +893,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
- ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_warning("could not set keys");
goto out;
@@ -936,7 +923,7 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
/* disconnect reason is not used in immediate disconnections */
cmd->type = DISCONNECT_IMMEDIATE;
- ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd));
+ ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0);
if (ret < 0) {
wl1271_error("failed to send disconnect command");
goto out_free;
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 174b820..9d7061b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -29,7 +29,8 @@
struct acx_header;
-int wl1271_cmd_send(struct wl1271 *wl, u16 type, void *buf, size_t buf_len);
+int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
+ size_t res_len);
int wl1271_cmd_join(struct wl1271 *wl);
int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
--
1.5.6.5
From: Juuso Oikarinen <[email protected]>
Check the result code of all commands, and return an error code if the
firmware reports an error in execution. Previously this error would go
ignored in most cases.
Signed-off-by: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271_cmd.c | 34 +++++++---------------------
drivers/net/wireless/wl12xx/wl1271_init.c | 7 ++++-
2 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 0666328..46e5ea4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -74,6 +74,15 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
intr = wl1271_spi_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
}
+ /* read back the status code of the command */
+ wl1271_spi_read(wl, wl->cmd_box_addr, cmd,
+ sizeof(struct wl1271_cmd_header), false);
+
+ if (cmd->status != CMD_STATUS_SUCCESS) {
+ wl1271_error("command execute failure %d", cmd->status);
+ ret = -EIO;
+ }
+
wl1271_spi_write32(wl, ACX_REG_INTERRUPT_ACK,
WL1271_ACX_INTR_CMD_COMPLETE);
@@ -306,7 +315,6 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
if (answer) {
struct wl1271_command *cmd_answer;
- u16 status;
/*
* The test command got in, we can read the answer.
@@ -316,10 +324,6 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
wl1271_spi_read(wl, wl->cmd_box_addr, buf, buf_len, false);
cmd_answer = buf;
- status = le16_to_cpu(cmd_answer->header.status);
-
- if (status != CMD_STATUS_SUCCESS)
- wl1271_error("TEST command answer error: %d", status);
}
return 0;
@@ -354,11 +358,6 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
/* the interrogate command got in, we can read the answer */
wl1271_spi_read(wl, wl->cmd_box_addr, buf, len, false);
- acx = buf;
- if (le16_to_cpu(acx->cmd.status) != CMD_STATUS_SUCCESS)
- wl1271_error("INTERROGATE command error: %d",
- le16_to_cpu(acx->cmd.status));
-
out:
return ret;
}
@@ -507,11 +506,6 @@ int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
/* the read command got in, we can now read the answer */
wl1271_spi_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd), false);
-
- if (le16_to_cpu(cmd->header.status) != CMD_STATUS_SUCCESS)
- wl1271_error("error in read command result: %d",
- le16_to_cpu(cmd->header.status));
-
memcpy(answer, cmd->value, len);
out:
@@ -639,17 +633,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
if (ret < 0) {
wl1271_error("SCAN failed");
- goto out;
- }
-
- wl1271_spi_read(wl, wl->cmd_box_addr, params, sizeof(*params),
- false);
-
- if (le16_to_cpu(params->header.status) != CMD_STATUS_SUCCESS) {
- wl1271_error("Scan command error: %d",
- le16_to_cpu(params->header.status));
wl->scanning = false;
- ret = -EIO;
goto out;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 417b415..7c2017f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -303,12 +303,15 @@ int wl1271_hw_init(struct wl1271 *wl)
{
int ret;
+ /* FIXME: the following parameter setting functions return error
+ * codes - the reason is so far unknown. The -EIO is therefore
+ * ignored for the time being. */
ret = wl1271_init_general_parms(wl);
- if (ret < 0)
+ if (ret < 0 && ret != -EIO)
return ret;
ret = wl1271_init_radio_parms(wl);
- if (ret < 0)
+ if (ret < 0 && ret != -EIO)
return ret;
/* Template settings */
--
1.5.6.5
From: Juuso Oikarinen <[email protected]>
The null-data template (nullfunc) is dependent on the BSSID of the
current AP only, so it needs to be updated only when the BSSID changes.
Removed excess setting of the template.
Signed-off-by: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271_main.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 86132bb..0ae506a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1067,11 +1067,11 @@ static int wl1271_op_config_interface(struct ieee80211_hw *hw,
ret = wl1271_cmd_join(wl);
if (ret < 0)
goto out_sleep;
- }
- ret = wl1271_cmd_build_null_data(wl);
- if (ret < 0)
- goto out_sleep;
+ ret = wl1271_cmd_build_null_data(wl);
+ if (ret < 0)
+ goto out_sleep;
+ }
wl->ssid_len = conf->ssid_len;
if (wl->ssid_len)
@@ -1137,10 +1137,6 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
wl->channel = channel;
}
- ret = wl1271_cmd_build_null_data(wl);
- if (ret < 0)
- goto out_sleep;
-
if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
wl1271_info("psm enabled");
@@ -1165,7 +1161,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (conf->power_level != wl->power_level) {
ret = wl1271_acx_tx_power(wl, conf->power_level);
if (ret < 0)
- goto out;
+ goto out_sleep;
wl->power_level = conf->power_level;
}
--
1.5.6.5
From: Juuso Oikarinen <[email protected]>
Correct the endianness-handling of the firmware command result status handling
code.
Signed-off-by: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271_cmd.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 46e5ea4..8acee5c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -48,6 +48,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
unsigned long timeout;
u32 intr;
int ret = 0;
+ u16 status;
cmd = buf;
cmd->id = cpu_to_le16(id);
@@ -78,8 +79,9 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
wl1271_spi_read(wl, wl->cmd_box_addr, cmd,
sizeof(struct wl1271_cmd_header), false);
- if (cmd->status != CMD_STATUS_SUCCESS) {
- wl1271_error("command execute failure %d", cmd->status);
+ status = le16_to_cpu(cmd->status);
+ if (status != CMD_STATUS_SUCCESS) {
+ wl1271_error("command execute failure %d", status);
ret = -EIO;
}
--
1.5.6.5
From: Juuso Oikarinen <[email protected]>
Currently, to avoid distortions, the TX power level has been hardcoded
to a low value. The value is slightly too low for good functionality, so
we increase it from 7dB to 12dB.
Signed-off-by: Juuso Oikarinen <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Luciano Coelho <[email protected]>
---
drivers/net/wireless/wl12xx/wl1271_acx.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index bf5a868..5cc89bb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -141,7 +141,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
* calibration, to avoid distortions
*/
/* acx->current_tx_power = power * 10; */
- acx->current_tx_power = 70;
+ acx->current_tx_power = 120;
ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
if (ret < 0) {
--
1.5.6.5