Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352194
b: refs/heads/master
c: ea50843
h: refs/heads/master
v: v3
  • Loading branch information
Eliad Peller authored and Luciano Coelho committed Dec 4, 2012
1 parent e356eac commit c26ca15
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d88949b7def1e982871406f3ad3efa361ffa6ffc
refs/heads/master: ea5084356fb05093da9ff225fd2c2fcfd363371c
85 changes: 67 additions & 18 deletions trunk/drivers/net/wireless/ti/wlcore/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@
* @id: command id
* @buf: buffer containing the command, must work with dma
* @len: length of the buffer
* return the cmd status code on success.
*/
int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len)
static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf,
size_t len, size_t res_len)
{
struct wl1271_cmd_header *cmd;
unsigned long timeout;
u32 intr;
int ret = 0;
int ret;
u16 status;
u16 poll_count = 0;

Expand All @@ -71,27 +72,26 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,

ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false);
if (ret < 0)
goto fail;
return ret;

/*
* TODO: we just need this because one bit is in a different
* place. Is there any better way?
*/
ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len);
if (ret < 0)
goto fail;
return ret;

timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);

ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
if (ret < 0)
goto fail;
return ret;

while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
if (time_after(jiffies, timeout)) {
wl1271_error("command complete timeout");
ret = -ETIMEDOUT;
goto fail;
return -ETIMEDOUT;
}

poll_count++;
Expand All @@ -102,7 +102,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,

ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
if (ret < 0)
goto fail;
return ret;
}

/* read back the status code of the command */
Expand All @@ -111,28 +111,60 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,

ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false);
if (ret < 0)
goto fail;
return ret;

status = le16_to_cpu(cmd->status);
if (status != CMD_STATUS_SUCCESS) {
wl1271_error("command execute failure %d", status);
ret = -EIO;
goto fail;
}

ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
WL1271_ACX_INTR_CMD_COMPLETE);
if (ret < 0)
return ret;

return status;
}

/*
* send command to fw and return cmd status on success
* valid_rets contains a bitmap of allowed error codes
*/
int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len, unsigned long valid_rets)
{
int ret = __wlcore_cmd_send(wl, id, buf, len, res_len);

if (ret < 0)
goto fail;

return 0;
/* success is always a valid status */
valid_rets |= BIT(CMD_STATUS_SUCCESS);

if (ret >= MAX_COMMAND_STATUS ||
!test_bit(ret, &valid_rets)) {
wl1271_error("command execute failure %d", ret);
ret = -EIO;
goto fail;
}
return ret;
fail:
wl12xx_queue_recovery_work(wl);
return ret;
}
EXPORT_SYMBOL_GPL(wl1271_cmd_send);

/*
* wrapper for wlcore_cmd_send that accept only CMD_STATUS_SUCCESS
* return 0 on success.
*/
int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len)
{
int ret = wlcore_cmd_send_failsafe(wl, id, buf, len, res_len, 0);

if (ret < 0)
return ret;
return 0;
}

/*
* Poll the mailbox event field until any of the bits in the mask is set or a
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
Expand Down Expand Up @@ -791,8 +823,11 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
* @id: acx id
* @buf: buffer containing acx, including all headers, must work with dma
* @len: length of buf
* @valid_rets: bitmap of valid cmd status codes (i.e. return values).
* return the cmd status on success.
*/
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
size_t len, unsigned long valid_rets)
{
struct acx_header *acx = buf;
int ret;
Expand All @@ -804,12 +839,26 @@ 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, 0);
ret = wlcore_cmd_send_failsafe(wl, CMD_CONFIGURE, acx, len, 0,
valid_rets);
if (ret < 0) {
wl1271_warning("CONFIGURE command NOK");
return ret;
}

return ret;
}

/*
* wrapper for wlcore_cmd_configure that accepts only success status.
* return 0 on success
*/
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
{
int ret = wlcore_cmd_configure_failsafe(wl, id, buf, len, 0);

if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
Expand Down
7 changes: 6 additions & 1 deletion trunk/drivers/net/wireless/ti/wlcore/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct acx_header;

int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len);
int wlcore_cmd_send_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len, unsigned long valid_rets);
int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
u8 *role_id);
int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
Expand All @@ -45,6 +47,8 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
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);
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
size_t len, unsigned long valid_rets);
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 ps_mode, u16 auto_ps_timeout);
Expand Down Expand Up @@ -234,7 +238,8 @@ enum {
CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
CMD_STATUS_TEMPLATE_OOM = 23,
CMD_STATUS_NO_RX_BA_SESSION = 24,
MAX_COMMAND_STATUS = 0xff

MAX_COMMAND_STATUS
};

#define CMDMBOX_HEADER_LEN 4
Expand Down

0 comments on commit c26ca15

Please sign in to comment.