Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / libertas_tf / cmd.c
index b620daf..8945afd 100644 (file)
@@ -7,6 +7,8 @@
  *  the Free Software Foundation; either version 2 of the License, or (at
  *  your option) any later version.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 
 #include "libertas_tf.h"
@@ -82,6 +84,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
        int ret = -1;
        u32 i;
 
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        memset(&cmd, 0, sizeof(cmd));
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
@@ -104,6 +108,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
                priv->fwrelease >>  8 & 0xff,
                priv->fwrelease       & 0xff,
                priv->fwcapinfo);
+       lbtf_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
+                   cmd.hwifversion, cmd.version);
 
        /* Clamp region code to 8-bit since FW spec indicates that it should
         * only ever be 8-bit, even though the field size is 16-bit.  Some
@@ -118,8 +124,10 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
        }
 
        /* if it's unidentified region code, use the default (USA) */
-       if (i >= MRVDRV_MAX_REGION_CODE)
+       if (i >= MRVDRV_MAX_REGION_CODE) {
                priv->regioncode = 0x10;
+               pr_info("unidentified region code; using the default (USA)\n");
+       }
 
        if (priv->current_addr[0] == 0xff)
                memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
@@ -128,6 +136,7 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
 
        lbtf_geo_init(priv);
 out:
+       lbtf_deb_leave(LBTF_DEB_CMD);
        return ret;
 }
 
@@ -141,13 +150,18 @@ out:
  */
 int lbtf_set_channel(struct lbtf_private *priv, u8 channel)
 {
+       int ret = 0;
        struct cmd_ds_802_11_rf_channel cmd;
 
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
        cmd.channel = cpu_to_le16(channel);
 
-       return lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
+       ret = lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
+       lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
+       return ret;
 }
 
 int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon)
@@ -155,20 +169,28 @@ int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon)
        struct cmd_ds_802_11_beacon_set cmd;
        int size;
 
-       if (beacon->len > MRVL_MAX_BCN_SIZE)
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
+       if (beacon->len > MRVL_MAX_BCN_SIZE) {
+               lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", -1);
                return -1;
+       }
        size =  sizeof(cmd) - sizeof(cmd.beacon) + beacon->len;
        cmd.hdr.size = cpu_to_le16(size);
        cmd.len = cpu_to_le16(beacon->len);
        memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len);
 
        lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size);
+
+       lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", 0);
        return 0;
 }
 
 int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable,
-                    int beacon_int) {
+                    int beacon_int)
+{
        struct cmd_ds_802_11_beacon_control cmd;
+       lbtf_deb_enter(LBTF_DEB_CMD);
 
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_ACT_SET);
@@ -176,6 +198,8 @@ int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable,
        cmd.beacon_period = cpu_to_le16(beacon_int);
 
        lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd));
+
+       lbtf_deb_leave(LBTF_DEB_CMD);
        return 0;
 }
 
@@ -183,17 +207,28 @@ static void lbtf_queue_cmd(struct lbtf_private *priv,
                          struct cmd_ctrl_node *cmdnode)
 {
        unsigned long flags;
+       lbtf_deb_enter(LBTF_DEB_HOST);
 
-       if (!cmdnode)
-               return;
+       if (!cmdnode) {
+               lbtf_deb_host("QUEUE_CMD: cmdnode is NULL\n");
+               goto qcmd_done;
+       }
 
-       if (!cmdnode->cmdbuf->size)
-               return;
+       if (!cmdnode->cmdbuf->size) {
+               lbtf_deb_host("DNLD_CMD: cmd size is zero\n");
+               goto qcmd_done;
+       }
 
        cmdnode->result = 0;
        spin_lock_irqsave(&priv->driver_lock, flags);
        list_add_tail(&cmdnode->list, &priv->cmdpendingq);
        spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+       lbtf_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
+                    le16_to_cpu(cmdnode->cmdbuf->command));
+
+qcmd_done:
+       lbtf_deb_leave(LBTF_DEB_HOST);
 }
 
 static void lbtf_submit_command(struct lbtf_private *priv,
@@ -206,22 +241,33 @@ static void lbtf_submit_command(struct lbtf_private *priv,
        int timeo = 5 * HZ;
        int ret;
 
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        cmd = cmdnode->cmdbuf;
 
        spin_lock_irqsave(&priv->driver_lock, flags);
        priv->cur_cmd = cmdnode;
        cmdsize = le16_to_cpu(cmd->size);
        command = le16_to_cpu(cmd->command);
+
+       lbtf_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
+                    command, le16_to_cpu(cmd->seqnum), cmdsize);
+       lbtf_deb_hex(LBTF_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
+
        ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
        spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-       if (ret)
+       if (ret) {
+               pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
                /* Let the timer kick in and retry, and potentially reset
                   the whole thing if the condition persists */
                timeo = HZ;
+       }
 
        /* Setup the timer after transmit command */
        mod_timer(&priv->command_timer, jiffies + timeo);
+
+       lbtf_deb_leave(LBTF_DEB_HOST);
 }
 
 /**
@@ -231,8 +277,10 @@ static void lbtf_submit_command(struct lbtf_private *priv,
 static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
                                         struct cmd_ctrl_node *cmdnode)
 {
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        if (!cmdnode)
-               return;
+               goto cl_ins_out;
 
        cmdnode->callback = NULL;
        cmdnode->callback_arg = 0;
@@ -240,6 +288,9 @@ static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
        memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
 
        list_add_tail(&cmdnode->list, &priv->cmdfreeq);
+
+cl_ins_out:
+       lbtf_deb_leave(LBTF_DEB_HOST);
 }
 
 static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
@@ -268,29 +319,41 @@ int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv)
 {
        struct cmd_ds_mac_multicast_addr cmd;
 
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_ACT_SET);
 
        cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
+
+       lbtf_deb_cmd("MULTICAST_ADR: setting %d addresses\n", cmd.nr_of_adrs);
+
        memcpy(cmd.maclist, priv->multicastlist,
               priv->nr_of_multicastmacaddr * ETH_ALEN);
 
        lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd));
+
+       lbtf_deb_leave(LBTF_DEB_CMD);
        return 0;
 }
 
 void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode)
 {
        struct cmd_ds_set_mode cmd;
+       lbtf_deb_enter(LBTF_DEB_WEXT);
 
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.mode = cpu_to_le16(mode);
+       lbtf_deb_wext("Switching to mode: 0x%x\n", mode);
        lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
+
+       lbtf_deb_leave(LBTF_DEB_WEXT);
 }
 
 void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
 {
        struct cmd_ds_set_bssid cmd;
+       lbtf_deb_enter(LBTF_DEB_CMD);
 
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.activate = activate ? 1 : 0;
@@ -298,11 +361,13 @@ void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
                memcpy(cmd.bssid, bssid, ETH_ALEN);
 
        lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd));
+       lbtf_deb_leave(LBTF_DEB_CMD);
 }
 
 int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr)
 {
        struct cmd_ds_802_11_mac_address cmd;
+       lbtf_deb_enter(LBTF_DEB_CMD);
 
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_ACT_SET);
@@ -310,6 +375,7 @@ int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr)
        memcpy(cmd.macadd, mac_addr, ETH_ALEN);
 
        lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd));
+       lbtf_deb_leave(LBTF_DEB_CMD);
        return 0;
 }
 
@@ -318,6 +384,8 @@ int lbtf_set_radio_control(struct lbtf_private *priv)
        int ret = 0;
        struct cmd_ds_802_11_radio_control cmd;
 
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_ACT_SET);
 
@@ -341,19 +409,28 @@ int lbtf_set_radio_control(struct lbtf_private *priv)
        else
                cmd.control &= cpu_to_le16(~TURN_ON_RF);
 
+       lbtf_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
+                   priv->preamble);
+
        ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
+
+       lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
        return ret;
 }
 
 void lbtf_set_mac_control(struct lbtf_private *priv)
 {
        struct cmd_ds_mac_control cmd;
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(priv->mac_control);
        cmd.reserved = 0;
 
        lbtf_cmd_async(priv, CMD_MAC_CONTROL,
                &cmd.hdr, sizeof(cmd));
+
+       lbtf_deb_leave(LBTF_DEB_CMD);
 }
 
 /**
@@ -365,29 +442,43 @@ void lbtf_set_mac_control(struct lbtf_private *priv)
  */
 int lbtf_allocate_cmd_buffer(struct lbtf_private *priv)
 {
+       int ret = 0;
        u32 bufsize;
        u32 i;
        struct cmd_ctrl_node *cmdarray;
 
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        /* Allocate and initialize the command array */
        bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
        cmdarray = kzalloc(bufsize, GFP_KERNEL);
-       if (!cmdarray)
-               return -1;
+       if (!cmdarray) {
+               lbtf_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
+               ret = -1;
+               goto done;
+       }
        priv->cmd_array = cmdarray;
 
        /* Allocate and initialize each command buffer in the command array */
        for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
                cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
-               if (!cmdarray[i].cmdbuf)
-                       return -1;
+               if (!cmdarray[i].cmdbuf) {
+                       lbtf_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
+                       ret = -1;
+                       goto done;
+               }
        }
 
        for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
                init_waitqueue_head(&cmdarray[i].cmdwait_q);
                lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]);
        }
-       return 0;
+
+       ret = 0;
+
+done:
+       lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
+       return ret;
 }
 
 /**
@@ -402,9 +493,13 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv)
        struct cmd_ctrl_node *cmdarray;
        unsigned int i;
 
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        /* need to check if cmd array is allocated or not */
-       if (priv->cmd_array == NULL)
-               return 0;
+       if (priv->cmd_array == NULL) {
+               lbtf_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
+               goto done;
+       }
 
        cmdarray = priv->cmd_array;
 
@@ -418,6 +513,8 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv)
        kfree(priv->cmd_array);
        priv->cmd_array = NULL;
 
+done:
+       lbtf_deb_leave(LBTF_DEB_HOST);
        return 0;
 }
 
@@ -433,6 +530,8 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv)
        struct cmd_ctrl_node *tempnode;
        unsigned long flags;
 
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        if (!priv)
                return NULL;
 
@@ -442,11 +541,14 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv)
                tempnode = list_first_entry(&priv->cmdfreeq,
                                            struct cmd_ctrl_node, list);
                list_del(&tempnode->list);
-       } else
+       } else {
+               lbtf_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
                tempnode = NULL;
+       }
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
 
+       lbtf_deb_leave(LBTF_DEB_HOST);
        return tempnode;
 }
 
@@ -462,16 +564,20 @@ int lbtf_execute_next_command(struct lbtf_private *priv)
        struct cmd_ctrl_node *cmdnode = NULL;
        struct cmd_header *cmd;
        unsigned long flags;
+       int ret = 0;
 
-       /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
+       /* Debug group is lbtf_deb_THREAD and not lbtf_deb_HOST, because the
         * only caller to us is lbtf_thread() and we get even when a
         * data packet is received */
+       lbtf_deb_enter(LBTF_DEB_THREAD);
 
        spin_lock_irqsave(&priv->driver_lock, flags);
 
        if (priv->cur_cmd) {
+               pr_alert("EXEC_NEXT_CMD: already processing command!\n");
                spin_unlock_irqrestore(&priv->driver_lock, flags);
-               return -1;
+               ret = -1;
+               goto done;
        }
 
        if (!list_empty(&priv->cmdpendingq)) {
@@ -483,11 +589,17 @@ int lbtf_execute_next_command(struct lbtf_private *priv)
                cmd = cmdnode->cmdbuf;
 
                list_del(&cmdnode->list);
+               lbtf_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
+                           le16_to_cpu(cmd->command));
                spin_unlock_irqrestore(&priv->driver_lock, flags);
                lbtf_submit_command(priv, cmdnode);
        } else
                spin_unlock_irqrestore(&priv->driver_lock, flags);
-       return 0;
+
+       ret = 0;
+done:
+       lbtf_deb_leave(LBTF_DEB_THREAD);
+       return ret;
 }
 
 static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
@@ -498,14 +610,22 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
 {
        struct cmd_ctrl_node *cmdnode;
 
-       if (priv->surpriseremoved)
-               return ERR_PTR(-ENOENT);
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
+       if (priv->surpriseremoved) {
+               lbtf_deb_host("PREP_CMD: card removed\n");
+               cmdnode = ERR_PTR(-ENOENT);
+               goto done;
+       }
 
        cmdnode = lbtf_get_cmd_ctrl_node(priv);
        if (cmdnode == NULL) {
+               lbtf_deb_host("PREP_CMD: cmdnode is NULL\n");
+
                /* Wake up main thread to execute next command */
                queue_work(lbtf_wq, &priv->cmd_work);
-               return ERR_PTR(-ENOBUFS);
+               cmdnode = ERR_PTR(-ENOBUFS);
+               goto done;
        }
 
        cmdnode->callback = callback;
@@ -520,17 +640,24 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
        cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
        cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
        cmdnode->cmdbuf->result  = 0;
+
+       lbtf_deb_host("PREP_CMD: command 0x%04x\n", command);
+
        cmdnode->cmdwaitqwoken = 0;
        lbtf_queue_cmd(priv, cmdnode);
        queue_work(lbtf_wq, &priv->cmd_work);
 
+ done:
+       lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %p", cmdnode);
        return cmdnode;
 }
 
 void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command,
        struct cmd_header *in_cmd, int in_cmd_size)
 {
+       lbtf_deb_enter(LBTF_DEB_CMD);
        __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0);
+       lbtf_deb_leave(LBTF_DEB_CMD);
 }
 
 int __lbtf_cmd(struct lbtf_private *priv, uint16_t command,
@@ -543,30 +670,35 @@ int __lbtf_cmd(struct lbtf_private *priv, uint16_t command,
        unsigned long flags;
        int ret = 0;
 
+       lbtf_deb_enter(LBTF_DEB_HOST);
+
        cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size,
                                  callback, callback_arg);
-       if (IS_ERR(cmdnode))
-               return PTR_ERR(cmdnode);
+       if (IS_ERR(cmdnode)) {
+               ret = PTR_ERR(cmdnode);
+               goto done;
+       }
 
        might_sleep();
        ret = wait_event_interruptible(cmdnode->cmdwait_q,
                                       cmdnode->cmdwaitqwoken);
-       if (ret)        {
-               printk(KERN_DEBUG
-                      "libertastf: command 0x%04x interrupted by signal",
-                      command);
-               return ret;
+       if (ret) {
+               pr_info("PREP_CMD: command 0x%04x interrupted by signal: %d\n",
+                           command, ret);
+               goto done;
        }
 
        spin_lock_irqsave(&priv->driver_lock, flags);
        ret = cmdnode->result;
        if (ret)
-               printk(KERN_DEBUG "libertastf: command 0x%04x failed: %d\n",
+               pr_info("PREP_CMD: command 0x%04x failed: %d\n",
                            command, ret);
 
        __lbtf_cleanup_and_insert_cmd(priv, cmdnode);
        spin_unlock_irqrestore(&priv->driver_lock, flags);
 
+done:
+       lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
        return ret;
 }
 EXPORT_SYMBOL_GPL(__lbtf_cmd);
@@ -587,6 +719,8 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
        unsigned long flags;
        uint16_t result;
 
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        mutex_lock(&priv->lock);
        spin_lock_irqsave(&priv->driver_lock, flags);
 
@@ -602,7 +736,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
        result = le16_to_cpu(resp->result);
 
        if (net_ratelimit())
-               printk(KERN_DEBUG "libertastf: cmd response 0x%04x, seq %d, size %d\n",
+               pr_info("libertastf: cmd response 0x%04x, seq %d, size %d\n",
                        respcmd, le16_to_cpu(resp->seqnum),
                        le16_to_cpu(resp->size));
 
@@ -639,7 +773,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
                switch (respcmd) {
                case CMD_RET(CMD_GET_HW_SPEC):
                case CMD_RET(CMD_802_11_RESET):
-                       printk(KERN_DEBUG "libertastf: reset failed\n");
+                       pr_info("libertastf: reset failed\n");
                        break;
 
                }
@@ -666,5 +800,6 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
 
 done:
        mutex_unlock(&priv->lock);
+       lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
        return ret;
 }