wl1251: Fix memory leak in data path command handling
[pandora-wifi.git] / drivers / net / wireless / wl12xx / wl1251_cmd.c
index 0320b47..fcae4bc 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/module.h>
 #include <linux/crc7.h>
+#include <linux/etherdevice.h>
 
 #include "wl1251.h"
 #include "wl1251_reg.h"
@@ -199,14 +200,14 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
 
 out:
        kfree(vbm);
-       return 0;
+       return ret;
 }
 
-int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
+int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable)
 {
        struct cmd_enabledisable_path *cmd;
        int ret;
-       u16 cmd_rx, cmd_tx;
+       u16 cmd_rx;
 
        wl1251_debug(DEBUG_CMD, "cmd data path");
 
@@ -218,13 +219,10 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
 
        cmd->channel = channel;
 
-       if (enable) {
+       if (enable)
                cmd_rx = CMD_ENABLE_RX;
-               cmd_tx = CMD_ENABLE_TX;
-       } else {
+       else
                cmd_rx = CMD_DISABLE_RX;
-               cmd_tx = CMD_DISABLE_TX;
-       }
 
        ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
        if (ret < 0) {
@@ -236,11 +234,37 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
        wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
                     enable ? "start" : "stop", channel);
 
+out:
+       kfree(cmd);
+       return ret;
+}
+
+int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable)
+{
+       struct cmd_enabledisable_path *cmd;
+       int ret;
+       u16 cmd_tx;
+
+       wl1251_debug(DEBUG_CMD, "cmd data path");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       cmd->channel = channel;
+
+       if (enable)
+               cmd_tx = CMD_ENABLE_TX;
+       else
+               cmd_tx = CMD_DISABLE_TX;
+
        ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
        if (ret < 0) {
                wl1251_error("tx %s cmd for channel %d failed",
                             enable ? "start" : "stop", channel);
-               return ret;
+               goto out;
        }
 
        wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
@@ -276,15 +300,6 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
        join->rx_config_options = wl->rx_config;
        join->rx_filter_options = wl->rx_filter;
 
-       /*
-        * FIXME: disable temporarily all filters because after commit
-        * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
-        * association. The filter logic needs to be implemented properly
-        * and once that is done, this hack can be removed.
-        */
-       join->rx_config_options = 0;
-       join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
-
        join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
                RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
 
@@ -429,6 +444,13 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
                                                    CFG_RX_MGMT_EN |
                                                    CFG_RX_BCN_EN);
        cmd->params.scan_options = 0;
+       /*
+        * Use high priority scan when not associated to prevent fw issue
+        * causing never-ending scans (sometimes 20+ minutes).
+        * Note: This bug may be caused by the fw's DTIM handling.
+        */
+       if (is_zero_ether_addr(wl->bssid))
+               cmd->params.scan_options |= WL1251_SCAN_OPT_PRIORITY_HIGH;
        cmd->params.num_channels = n_channels;
        cmd->params.num_probe_requests = n_probes;
        cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
@@ -483,7 +505,7 @@ int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
 
        cmd->timeout = timeout;
 
-       ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
+       ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
        if (ret < 0) {
                wl1251_error("cmd trigger scan to failed: %d", ret);
                goto out;