]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/libertas/cmd.c
libertas: convert PS_MODE to a direct command
[mv-sheeva.git] / drivers / net / wireless / libertas / cmd.c
index 2c96cf3400c94cff3a78e61a38b2d3cd58218e26..5c7bb3551fb533896c7235ba9a436a3e7feab246 100644 (file)
@@ -230,42 +230,49 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 }
 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
 
-static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd,
-                                  u16 cmd_action)
+/**
+ *  @brief Sets the Power Save mode
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *  @param cmd_action  The Power Save operation (PS_MODE_ACTION_ENTER_PS or
+ *                         PS_MODE_ACTION_EXIT_PS)
+ *  @param block       Whether to block on a response or not
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
 {
-       struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
+       struct cmd_ds_802_11_ps_mode cmd;
+       int ret = 0;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
-                               sizeof(struct cmd_header));
-       psm->action = cpu_to_le16(cmd_action);
-       psm->multipledtim = 0;
-       switch (cmd_action) {
-       case CMD_SUBCMD_ENTER_PS:
-               lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
-
-               psm->locallisteninterval = 0;
-               psm->nullpktinterval = 0;
-               psm->multipledtim =
-                   cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
-               break;
-
-       case CMD_SUBCMD_EXIT_PS:
-               lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
-               break;
-
-       case CMD_SUBCMD_SLEEP_CONFIRMED:
-               lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
-               break;
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(cmd_action);
 
-       default:
-               break;
+       if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
+               lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
+               cmd.multipledtim = cpu_to_le16(1);  /* Default DTIM multiple */
+       } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
+               lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
+       } else {
+               /* We don't handle CONFIRM_SLEEP here because it needs to
+                * be fastpathed to the firmware.
+                */
+               lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
+               ret = -EOPNOTSUPP;
+               goto out;
        }
 
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
+       if (block)
+               ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
+       else
+               lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
+
+out:
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
 }
 
 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
@@ -950,16 +957,15 @@ static void lbs_queue_cmd(struct lbs_private *priv,
 
        /* Exit_PS command needs to be queued in the header always. */
        if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
-               struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
+               struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
 
-               if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
+               if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
                        if (priv->psstate != PS_STATE_FULL_POWER)
                                addtail = 0;
                }
        }
 
-       if (le16_to_cpu(cmdnode->cmdbuf->command) ==
-                       CMD_802_11_WAKEUP_CONFIRM)
+       if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
                addtail = 0;
 
        spin_lock_irqsave(&priv->driver_lock, flags);
@@ -1154,7 +1160,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 {
        int ret = 0;
        struct cmd_ctrl_node *cmdnode;
-       struct cmd_ds_command *cmdptr;
+       struct cmd_header *cmdptr;
        unsigned long flags;
 
        lbs_deb_enter(LBS_DEB_HOST);
@@ -1190,7 +1196,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
        cmdnode->callback = NULL;
        cmdnode->callback_arg = (unsigned long)pdata_buf;
 
-       cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
+       cmdptr = (struct cmd_header *)cmdnode->cmdbuf;
 
        lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
 
@@ -1202,10 +1208,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
        cmdptr->result = 0;
 
        switch (cmd_no) {
-       case CMD_802_11_PS_MODE:
-               ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
-               break;
-
        case CMD_802_11_DEEP_SLEEP:
                cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP);
                cmdptr->size = cpu_to_le16(sizeof(struct cmd_header));
@@ -1426,10 +1428,10 @@ int lbs_execute_next_command(struct lbs_private *priv)
                        /*
                         * 1. Non-PS command:
                         * Queue it. set needtowakeup to TRUE if current state
-                        * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
-                        * 2. PS command but not Exit_PS:
+                        * is SLEEP, otherwise call send EXIT_PS.
+                        * 2. PS command but not EXIT_PS:
                         * Ignore it.
-                        * 3. PS command Exit_PS:
+                        * 3. PS command EXIT_PS:
                         * Set needtowakeup to TRUE if current state is SLEEP,
                         * otherwise send this command down to firmware
                         * immediately.
@@ -1443,8 +1445,11 @@ int lbs_execute_next_command(struct lbs_private *priv)
                                        /* w/ new scheme, it will not reach here.
                                           since it is blocked in main_thread. */
                                        priv->needtowakeup = 1;
-                               } else
-                                       lbs_ps_wakeup(priv, 0);
+                               } else {
+                                       lbs_set_ps_mode(priv,
+                                                       PS_MODE_ACTION_EXIT_PS,
+                                                       false);
+                               }
 
                                ret = 0;
                                goto done;
@@ -1459,7 +1464,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
                                       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
                                       psm->action);
                                if (psm->action !=
-                                   cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
+                                   cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
                                        list_del(&cmdnode->list);
@@ -1519,13 +1524,16 @@ int lbs_execute_next_command(struct lbs_private *priv)
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
                                               " go back to PS_SLEEP");
-                                       lbs_ps_sleep(priv, 0);
+                                       lbs_set_ps_mode(priv,
+                                                       PS_MODE_ACTION_ENTER_PS,
+                                                       false);
                                }
                        } else {
                                lbs_deb_host(
                                       "EXEC_NEXT_CMD: cmdpendingq empty, "
                                       "go back to PS_SLEEP");
-                               lbs_ps_sleep(priv, 0);
+                               lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
+                                               false);
                        }
                }
 #endif
@@ -1573,43 +1581,6 @@ out:
        lbs_deb_leave(LBS_DEB_HOST);
 }
 
-void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
-{
-       lbs_deb_enter(LBS_DEB_HOST);
-
-       /*
-        * PS is currently supported only in Infrastructure mode
-        * Remove this check if it is to be supported in IBSS mode also
-        */
-
-       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
-                             CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
-
-       lbs_deb_leave(LBS_DEB_HOST);
-}
-
-/**
- *  @brief This function sends Exit_PS command to firmware.
- *
- *  @param priv        A pointer to struct lbs_private structure
- *  @param wait_option wait response or not
- *  @return            n/a
- */
-void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
-{
-       __le32 Localpsmode;
-
-       lbs_deb_enter(LBS_DEB_HOST);
-
-       Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
-
-       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
-                             CMD_SUBCMD_EXIT_PS,
-                             wait_option, 0, &Localpsmode);
-
-       lbs_deb_leave(LBS_DEB_HOST);
-}
-
 /**
  *  @brief This function checks condition and prepares to
  *  send sleep confirm command to firmware if ok.