From 7919b89c8276d657976d4d4d6b7cb58ea1aa08c3 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Tue, 1 Apr 2008 14:50:43 +0200 Subject: libertas: convert libertas driver to use an event/cmdresp queue This patch (co-developed by Dan Williams and Holger Schurig) uses a kfifo object for events and a swapping buffer scheme for the command response to preserve the zero-copy semantics of the CF driver and keep memory usage low. The main thread should only ever touch the buffer indexed by priv->resp_idx, while the interface code is free to write to the second buffer, then swap priv->resp_idx under the driver spinlock. The firmware specs only permit one in-flight command, so there will only ever be one command response to process at a time. Signed-off-by: Holger Schurig Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmdresp.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers/net/wireless/libertas/cmdresp.c') diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 245d3c3..5abecb7 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -384,7 +384,7 @@ static inline int handle_cmd_response(struct lbs_private *priv, return ret; } -int lbs_process_rx_command(struct lbs_private *priv) +int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) { uint16_t respcmd, curcmd; struct cmd_header *resp; @@ -404,14 +404,14 @@ int lbs_process_rx_command(struct lbs_private *priv) goto done; } - resp = (void *)priv->upld_buf; + resp = (void *)data; curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command); respcmd = le16_to_cpu(resp->command); result = le16_to_cpu(resp->result); lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d\n", - respcmd, le16_to_cpu(resp->seqnum), priv->upld_len); - lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, priv->upld_len); + respcmd, le16_to_cpu(resp->seqnum), len); + lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len); if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", @@ -569,18 +569,13 @@ static int lbs_send_confirmwake(struct lbs_private *priv) return ret; } -int lbs_process_event(struct lbs_private *priv) +int lbs_process_event(struct lbs_private *priv, u32 event) { int ret = 0; - u32 eventcause; lbs_deb_enter(LBS_DEB_CMD); - spin_lock_irq(&priv->driver_lock); - eventcause = priv->eventcause >> SBI_EVENT_CAUSE_SHIFT; - spin_unlock_irq(&priv->driver_lock); - - switch (eventcause) { + switch (event) { case MACREG_INT_CODE_LINK_SENSED: lbs_deb_cmd("EVENT: link sensed\n"); break; @@ -696,14 +691,10 @@ int lbs_process_event(struct lbs_private *priv) break; default: - lbs_pr_alert("EVENT: unknown event id %d\n", eventcause); + lbs_pr_alert("EVENT: unknown event id %d\n", event); break; } - spin_lock_irq(&priv->driver_lock); - priv->eventcause = 0; - spin_unlock_irq(&priv->driver_lock); - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret; } -- cgit v1.1