- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.git] / drivers / net / wireless / libertas_tf / main.c
index 7945ff5..6a04c21 100644 (file)
@@ -7,10 +7,12 @@
  *  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 <linux/etherdevice.h>
 #include "libertas_tf.h"
-#include "linux/etherdevice.h"
 
 #define DRIVER_RELEASE_VERSION "004.p0"
 /* thinfirm version: 5.132.X.pX */
 #define LBTF_FW_VER_MAX                0x0584ffff
 #define QOS_CONTROL_LEN                2
 
-static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION;
+/* Module parameters */
+unsigned int lbtf_debug;
+EXPORT_SYMBOL_GPL(lbtf_debug);
+module_param_named(libertas_tf_debug, lbtf_debug, int, 0644);
+
+static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION
+#ifdef DEBUG
+       "-dbg"
+#endif
+       "";
+
 struct workqueue_struct *lbtf_wq;
 
 static const struct ieee80211_channel lbtf_channels[] = {
@@ -81,6 +93,9 @@ static void lbtf_cmd_work(struct work_struct *work)
 {
        struct lbtf_private *priv = container_of(work, struct lbtf_private,
                                         cmd_work);
+
+       lbtf_deb_enter(LBTF_DEB_CMD);
+
        spin_lock_irq(&priv->driver_lock);
        /* command response? */
        if (priv->cmd_response_rxed) {
@@ -108,11 +123,16 @@ static void lbtf_cmd_work(struct work_struct *work)
        priv->cmd_timed_out = 0;
        spin_unlock_irq(&priv->driver_lock);
 
-       if (!priv->fw_ready)
+       if (!priv->fw_ready) {
+               lbtf_deb_leave_args(LBTF_DEB_CMD, "fw not ready");
                return;
+       }
+
        /* Execute the next command */
        if (!priv->cur_cmd)
                lbtf_execute_next_command(priv);
+
+       lbtf_deb_leave(LBTF_DEB_CMD);
 }
 
 /**
@@ -126,6 +146,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv)
 {
        int ret = -1;
 
+       lbtf_deb_enter(LBTF_DEB_FW);
        /*
         * Read priv address from HW
         */
@@ -141,6 +162,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv)
 
        ret = 0;
 done:
+       lbtf_deb_leave_args(LBTF_DEB_FW, "ret: %d", ret);
        return ret;
 }
 
@@ -152,6 +174,7 @@ static void command_timer_fn(unsigned long data)
 {
        struct lbtf_private *priv = (struct lbtf_private *)data;
        unsigned long flags;
+       lbtf_deb_enter(LBTF_DEB_CMD);
 
        spin_lock_irqsave(&priv->driver_lock, flags);
 
@@ -168,10 +191,12 @@ static void command_timer_fn(unsigned long data)
        queue_work(lbtf_wq, &priv->cmd_work);
 out:
        spin_unlock_irqrestore(&priv->driver_lock, flags);
+       lbtf_deb_leave(LBTF_DEB_CMD);
 }
 
 static int lbtf_init_adapter(struct lbtf_private *priv)
 {
+       lbtf_deb_enter(LBTF_DEB_MAIN);
        memset(priv->current_addr, 0xff, ETH_ALEN);
        mutex_init(&priv->lock);
 
@@ -188,13 +213,16 @@ static int lbtf_init_adapter(struct lbtf_private *priv)
        if (lbtf_allocate_cmd_buffer(priv))
                return -1;
 
+       lbtf_deb_leave(LBTF_DEB_MAIN);
        return 0;
 }
 
 static void lbtf_free_adapter(struct lbtf_private *priv)
 {
+       lbtf_deb_enter(LBTF_DEB_MAIN);
        lbtf_free_cmd_buffer(priv);
        del_timer(&priv->command_timer);
+       lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 
 static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -221,14 +249,18 @@ static void lbtf_tx_work(struct work_struct *work)
        struct sk_buff *skb = NULL;
        int err;
 
+       lbtf_deb_enter(LBTF_DEB_MACOPS | LBTF_DEB_TX);
+
        if ((priv->vif->type == NL80211_IFTYPE_AP) &&
            (!skb_queue_empty(&priv->bc_ps_buf)))
                skb = skb_dequeue(&priv->bc_ps_buf);
        else if (priv->skb_to_tx) {
                skb = priv->skb_to_tx;
                priv->skb_to_tx = NULL;
-       } else
+       } else {
+               lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
                return;
+       }
 
        len = skb->len;
        info  = IEEE80211_SKB_CB(skb);
@@ -236,6 +268,7 @@ static void lbtf_tx_work(struct work_struct *work)
 
        if (priv->surpriseremoved) {
                dev_kfree_skb_any(skb);
+               lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
                return;
        }
 
@@ -249,6 +282,7 @@ static void lbtf_tx_work(struct work_struct *work)
                ETH_ALEN);
        txpd->tx_packet_length = cpu_to_le16(len);
        txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
+       lbtf_deb_hex(LBTF_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
        BUG_ON(priv->tx_skb);
        spin_lock_irq(&priv->driver_lock);
        priv->tx_skb = skb;
@@ -257,7 +291,9 @@ static void lbtf_tx_work(struct work_struct *work)
        if (err) {
                dev_kfree_skb_any(skb);
                priv->tx_skb = NULL;
+               pr_err("TX error: %d", err);
        }
+       lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
 }
 
 static int lbtf_op_start(struct ieee80211_hw *hw)
@@ -266,6 +302,8 @@ static int lbtf_op_start(struct ieee80211_hw *hw)
        void *card = priv->card;
        int ret = -1;
 
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
+
        if (!priv->fw_ready)
                /* Upload firmware */
                if (priv->hw_prog_firmware(card))
@@ -286,10 +324,12 @@ static int lbtf_op_start(struct ieee80211_hw *hw)
        }
 
        printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n");
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
        return 0;
 
 err_prog_firmware:
        priv->hw_reset_device(card);
+       lbtf_deb_leave_args(LBTF_DEB_MACOPS, "error programing fw; ret=%d", ret);
        return ret;
 }
 
@@ -300,6 +340,9 @@ static void lbtf_op_stop(struct ieee80211_hw *hw)
        struct sk_buff *skb;
 
        struct cmd_ctrl_node *cmdnode;
+
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
+
        /* Flush pending command nodes */
        spin_lock_irqsave(&priv->driver_lock, flags);
        list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
@@ -316,13 +359,14 @@ static void lbtf_op_stop(struct ieee80211_hw *hw)
        priv->radioon = RADIO_OFF;
        lbtf_set_radio_control(priv);
 
-       return;
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
 }
 
 static int lbtf_op_add_interface(struct ieee80211_hw *hw,
                        struct ieee80211_vif *vif)
 {
        struct lbtf_private *priv = hw->priv;
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
        if (priv->vif != NULL)
                return -EOPNOTSUPP;
 
@@ -340,6 +384,7 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
        }
        lbtf_set_mac_address(priv, (u8 *) vif->addr);
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
        return 0;
 }
 
@@ -347,6 +392,7 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
                        struct ieee80211_vif *vif)
 {
        struct lbtf_private *priv = hw->priv;
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
 
        if (priv->vif->type == NL80211_IFTYPE_AP ||
            priv->vif->type == NL80211_IFTYPE_MESH_POINT)
@@ -354,37 +400,38 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
        lbtf_set_mode(priv, LBTF_PASSIVE_MODE);
        lbtf_set_bssid(priv, 0, NULL);
        priv->vif = NULL;
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
 }
 
 static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct lbtf_private *priv = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
 
        if (conf->channel->center_freq != priv->cur_freq) {
                priv->cur_freq = conf->channel->center_freq;
                lbtf_set_channel(priv, conf->channel->hw_value);
        }
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
        return 0;
 }
 
 static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
-                                    int mc_count, struct dev_addr_list *mclist)
+                                    struct netdev_hw_addr_list *mc_list)
 {
        struct lbtf_private *priv = hw->priv;
        int i;
+       struct netdev_hw_addr *ha;
+       int mc_count = netdev_hw_addr_list_count(mc_list);
 
        if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
                return mc_count;
 
        priv->nr_of_multicastmacaddr = mc_count;
-       for (i = 0; i < mc_count; i++) {
-               if (!mclist)
-                       break;
-               memcpy(&priv->multicastlist[i], mclist->da_addr,
-                               ETH_ALEN);
-               mclist = mclist->next;
-       }
+       i = 0;
+       netdev_hw_addr_list_for_each(ha, mc_list)
+               memcpy(&priv->multicastlist[i++], ha->addr, ETH_ALEN);
 
        return mc_count;
 }
@@ -397,11 +444,16 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
 {
        struct lbtf_private *priv = hw->priv;
        int old_mac_control = priv->mac_control;
+
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
+
        changed_flags &= SUPPORTED_FIF_FLAGS;
        *new_flags &= SUPPORTED_FIF_FLAGS;
 
-       if (!changed_flags)
+       if (!changed_flags) {
+               lbtf_deb_leave(LBTF_DEB_MACOPS);
                return;
+       }
 
        if (*new_flags & (FIF_PROMISC_IN_BSS))
                priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
@@ -427,6 +479,8 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
 
        if (priv->mac_control != old_mac_control)
                lbtf_set_mac_control(priv);
+
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
 }
 
 static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -436,6 +490,7 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct lbtf_private *priv = hw->priv;
        struct sk_buff *beacon;
+       lbtf_deb_enter(LBTF_DEB_MACOPS);
 
        if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
                switch (priv->vif->type) {
@@ -466,6 +521,8 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
                        priv->preamble = CMD_TYPE_LONG_PREAMBLE;
                lbtf_set_radio_control(priv);
        }
+
+       lbtf_deb_leave(LBTF_DEB_MACOPS);
 }
 
 static const struct ieee80211_ops lbtf_ops = {
@@ -488,6 +545,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
        unsigned int flags;
        struct ieee80211_hdr *hdr;
 
+       lbtf_deb_enter(LBTF_DEB_RX);
+
        prxpd = (struct rxpd *) skb->data;
 
        stats.flag = 0;
@@ -496,7 +555,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
        stats.freq = priv->cur_freq;
        stats.band = IEEE80211_BAND_2GHZ;
        stats.signal = prxpd->snr;
-       stats.noise = prxpd->nf;
        /* Marvell rate index has a hole at value 4 */
        if (prxpd->rx_rate > 4)
                --prxpd->rx_rate;
@@ -518,7 +576,15 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
        }
 
        memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
+
+       lbtf_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
+              skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
+       lbtf_deb_hex(LBTF_DEB_RX, "RX Data", skb->data,
+                    min_t(unsigned int, skb->len, 100));
+
        ieee80211_rx_irqsafe(priv->hw, skb);
+
+       lbtf_deb_leave(LBTF_DEB_RX);
        return 0;
 }
 EXPORT_SYMBOL_GPL(lbtf_rx);
@@ -535,6 +601,8 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev)
        struct ieee80211_hw *hw;
        struct lbtf_private *priv = NULL;
 
+       lbtf_deb_enter(LBTF_DEB_MAIN);
+
        hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops);
        if (!hw)
                goto done;
@@ -577,6 +645,7 @@ err_init_adapter:
        priv = NULL;
 
 done:
+       lbtf_deb_leave_args(LBTF_DEB_MAIN, "priv %p", priv);
        return priv;
 }
 EXPORT_SYMBOL_GPL(lbtf_add_card);
@@ -586,6 +655,8 @@ int lbtf_remove_card(struct lbtf_private *priv)
 {
        struct ieee80211_hw *hw = priv->hw;
 
+       lbtf_deb_enter(LBTF_DEB_MAIN);
+
        priv->surpriseremoved = 1;
        del_timer(&priv->command_timer);
        lbtf_free_adapter(priv);
@@ -593,6 +664,7 @@ int lbtf_remove_card(struct lbtf_private *priv)
        ieee80211_unregister_hw(hw);
        ieee80211_free_hw(hw);
 
+    lbtf_deb_leave(LBTF_DEB_MAIN);
        return 0;
 }
 EXPORT_SYMBOL_GPL(lbtf_remove_card);
@@ -651,17 +723,21 @@ EXPORT_SYMBOL_GPL(lbtf_bcn_sent);
 
 static int __init lbtf_init_module(void)
 {
+       lbtf_deb_enter(LBTF_DEB_MAIN);
        lbtf_wq = create_workqueue("libertastf");
        if (lbtf_wq == NULL) {
                printk(KERN_ERR "libertastf: couldn't create workqueue\n");
                return -ENOMEM;
        }
+       lbtf_deb_leave(LBTF_DEB_MAIN);
        return 0;
 }
 
 static void __exit lbtf_exit_module(void)
 {
+       lbtf_deb_enter(LBTF_DEB_MAIN);
        destroy_workqueue(lbtf_wq);
+       lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 
 module_init(lbtf_init_module);