]> git.karo-electronics.de Git - linux-beck.git/commitdiff
wlcore: update channel_switch/stop_channel_switch commands
authorEliad Peller <eliad@wizery.com>
Thu, 22 Nov 2012 16:06:18 +0000 (18:06 +0200)
committerLuciano Coelho <coelho@ti.com>
Tue, 27 Nov 2012 08:49:28 +0000 (10:49 +0200)
Some fields were added to the channel_switch and
stop_channel_switch commands. Unfortunately,
the new 18xx channel_switch struct is not backward
compatible with the 12xx channel switch struct.

Add a new channel_switch op to wlcore, and update
the driver accordingly.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/ti/wl12xx/cmd.c
drivers/net/wireless/ti/wl12xx/cmd.h
drivers/net/wireless/ti/wl12xx/main.c
drivers/net/wireless/ti/wl18xx/Makefile
drivers/net/wireless/ti/wl18xx/cmd.c [new file with mode: 0644]
drivers/net/wireless/ti/wl18xx/cmd.h [new file with mode: 0644]
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/cmd.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 622206241e83210e4246bbfc91f089837c6bdbb8..7dc9f965037d4189467c053f0c81f35b71a33166 100644 (file)
@@ -284,3 +284,40 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
        kfree(radio_parms);
        return ret;
 }
+
+int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
+                             struct ieee80211_channel_switch *ch_switch)
+{
+       struct wl12xx_cmd_channel_switch *cmd;
+       int ret;
+
+       wl1271_debug(DEBUG_ACX, "cmd channel switch");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       cmd->role_id = wlvif->role_id;
+       cmd->channel = ch_switch->channel->hw_value;
+       cmd->switch_time = ch_switch->count;
+       cmd->stop_tx = ch_switch->block_tx;
+
+       /* FIXME: control from mac80211 in the future */
+       /* Enable TX on the target channel */
+       cmd->post_switch_tx_disable = 0;
+
+       ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
+       if (ret < 0) {
+               wl1271_error("failed to send channel switch command");
+               goto out_free;
+       }
+
+out_free:
+       kfree(cmd);
+
+out:
+       return ret;
+}
index 140a0e8829d540050102e4dde4a0ba926420fa5d..32cbad54e993ea402647ef945bcf55ac517f4283 100644 (file)
@@ -103,10 +103,30 @@ struct wl1271_ext_radio_parms_cmd {
        u8 padding[3];
 } __packed;
 
+struct wl12xx_cmd_channel_switch {
+       struct wl1271_cmd_header header;
+
+       u8 role_id;
+
+       /* The new serving channel */
+       u8 channel;
+       /* Relative time of the serving channel switch in TBTT units */
+       u8 switch_time;
+       /* Stop the role TX, should expect it after radar detection */
+       u8 stop_tx;
+       /* The target channel tx status 1-stopped 0-open*/
+       u8 post_switch_tx_disable;
+
+       u8 padding[3];
+} __packed;
+
 int wl1271_cmd_general_parms(struct wl1271 *wl);
 int wl128x_cmd_general_parms(struct wl1271 *wl);
 int wl1271_cmd_radio_parms(struct wl1271 *wl);
 int wl128x_cmd_radio_parms(struct wl1271 *wl);
 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
+int wl12xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
+                             struct ieee80211_channel_switch *ch_switch);
 
 #endif /* __WL12XX_CMD_H__ */
index 0c81eeb4f5b80954fc9b79171215826bde0383d1..b93de04ccd6a0f888a0a3df7592473f23708cfe8 100644 (file)
@@ -1632,6 +1632,7 @@ static struct wlcore_ops wl12xx_ops = {
        .sched_scan_stop        = wl12xx_scan_sched_scan_stop,
        .get_spare_blocks       = wl12xx_get_spare_blocks,
        .set_key                = wl12xx_set_key,
+       .channel_switch         = wl12xx_cmd_channel_switch,
        .pre_pkt_send           = NULL,
 };
 
index f74224960c7090ce15fe0c2ddbc8ab1a23980949..81a864f3d7938d7a7388ffc0b4fc43e50e3155a2 100644 (file)
@@ -1,3 +1,3 @@
-wl18xx-objs    = main.o acx.o tx.o io.o debugfs.o scan.o
+wl18xx-objs    = main.o acx.o tx.o io.o debugfs.o scan.o cmd.o
 
 obj-$(CONFIG_WL18XX)           += wl18xx.o
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c
new file mode 100644 (file)
index 0000000..1d1f6cc
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * This file is part of wl18xx
+ *
+ * Copyright (C) 2011 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "../wlcore/cmd.h"
+#include "../wlcore/debug.h"
+#include "../wlcore/hw_ops.h"
+
+#include "cmd.h"
+
+int wl18xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
+                             struct ieee80211_channel_switch *ch_switch)
+{
+       struct wl18xx_cmd_channel_switch *cmd;
+       u32 supported_rates;
+       int ret;
+
+       wl1271_debug(DEBUG_ACX, "cmd channel switch");
+
+       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+       if (!cmd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       cmd->role_id = wlvif->role_id;
+       cmd->channel = ch_switch->channel->hw_value;
+       cmd->switch_time = ch_switch->count;
+       cmd->stop_tx = ch_switch->block_tx;
+
+       switch (ch_switch->channel->band) {
+       case IEEE80211_BAND_2GHZ:
+               cmd->band = WLCORE_BAND_2_4GHZ;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               cmd->band = WLCORE_BAND_5GHZ;
+               break;
+       default:
+               wl1271_error("invalid channel switch band: %d",
+                            ch_switch->channel->band);
+               ret = -EINVAL;
+               goto out_free;
+       }
+
+       supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES |
+                         wlcore_hw_sta_get_ap_rate_mask(wl, wlvif);
+       if (wlvif->p2p)
+               supported_rates &= ~CONF_TX_CCK_RATES;
+       cmd->local_supported_rates = cpu_to_le32(supported_rates);
+       cmd->channel_type = wlvif->channel_type;
+
+       ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
+       if (ret < 0) {
+               wl1271_error("failed to send channel switch command");
+               goto out_free;
+       }
+
+out_free:
+       kfree(cmd);
+out:
+       return ret;
+}
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.h b/drivers/net/wireless/ti/wl18xx/cmd.h
new file mode 100644 (file)
index 0000000..6687d10
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is part of wl18xx
+ *
+ * Copyright (C) 2011 Texas Instruments. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL18XX_CMD_H__
+#define __WL18XX_CMD_H__
+
+#include "../wlcore/wlcore.h"
+#include "../wlcore/acx.h"
+
+struct wl18xx_cmd_channel_switch {
+       struct wl1271_cmd_header header;
+
+       u8 role_id;
+
+       /* The new serving channel */
+       u8 channel;
+       /* Relative time of the serving channel switch in TBTT units */
+       u8 switch_time;
+       /* Stop the role TX, should expect it after radar detection */
+       u8 stop_tx;
+
+       __le32 local_supported_rates;
+
+       u8 channel_type;
+       u8 band;
+
+       u8 padding[2];
+} __packed;
+
+int wl18xx_cmd_channel_switch(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
+                             struct ieee80211_channel_switch *ch_switch);
+
+#endif
index e81b3518d288a989b2985d0f09628ca73d8574b6..2e54a3ea813c06f657ad555fdd6832e39b64e2f8 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "reg.h"
 #include "conf.h"
+#include "cmd.h"
 #include "acx.h"
 #include "tx.h"
 #include "wl18xx.h"
@@ -1335,6 +1336,7 @@ static struct wlcore_ops wl18xx_ops = {
        .handle_static_data     = wl18xx_handle_static_data,
        .get_spare_blocks = wl18xx_get_spare_blocks,
        .set_key        = wl18xx_set_key,
+       .channel_switch = wl18xx_cmd_channel_switch,
        .pre_pkt_send   = wl18xx_pre_pkt_send,
 };
 
index c8c776684d2c48c8ce7b228091a947ff6d46df1b..979676529ed0532e60c06528e22b2b965be5e768 100644 (file)
@@ -1722,43 +1722,7 @@ out:
        return ret;
 }
 
-int wl12xx_cmd_channel_switch(struct wl1271 *wl,
-                             struct wl12xx_vif *wlvif,
-                             struct ieee80211_channel_switch *ch_switch)
-{
-       struct wl12xx_cmd_channel_switch *cmd;
-       int ret;
-
-       wl1271_debug(DEBUG_ACX, "cmd channel switch");
-
-       cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-       if (!cmd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       cmd->role_id = wlvif->role_id;
-       cmd->channel = ch_switch->channel->hw_value;
-       cmd->switch_time = ch_switch->count;
-       cmd->stop_tx = ch_switch->block_tx;
-
-       /* FIXME: control from mac80211 in the future */
-       cmd->post_switch_tx_disable = 0;  /* Enable TX on the target channel */
-
-       ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
-       if (ret < 0) {
-               wl1271_error("failed to send channel switch command");
-               goto out_free;
-       }
-
-out_free:
-       kfree(cmd);
-
-out:
-       return ret;
-}
-
-int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
+int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 {
        struct wl12xx_cmd_stop_channel_switch *cmd;
        int ret;
@@ -1771,6 +1735,8 @@ int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
                goto out;
        }
 
+       cmd->role_id = wlvif->role_id;
+
        ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
        if (ret < 0) {
                wl1271_error("failed to stop channel switch command");
index 9e9062fdb7129c4647e666a77c01f3b5d5be07ce..96d53a730a315a4acf788eaf3bc16723eebf875e 100644 (file)
@@ -89,7 +89,8 @@ int wl12xx_cmd_stop_fwlog(struct wl1271 *wl);
 int wl12xx_cmd_channel_switch(struct wl1271 *wl,
                              struct wl12xx_vif *wlvif,
                              struct ieee80211_channel_switch *ch_switch);
-int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl);
+int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl,
+                                  struct wl12xx_vif *wlvif);
 int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                         u8 *hlid);
 void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);
@@ -633,27 +634,13 @@ struct wl12xx_cmd_stop_fwlog {
        struct wl1271_cmd_header header;
 } __packed;
 
-struct wl12xx_cmd_channel_switch {
+struct wl12xx_cmd_stop_channel_switch {
        struct wl1271_cmd_header header;
 
        u8 role_id;
-
-       /* The new serving channel */
-       u8 channel;
-       /* Relative time of the serving channel switch in TBTT units */
-       u8 switch_time;
-       /* Stop the role TX, should expect it after radar detection */
-       u8 stop_tx;
-       /* The target channel tx status 1-stopped 0-open*/
-       u8 post_switch_tx_disable;
-
        u8 padding[3];
 } __packed;
 
-struct wl12xx_cmd_stop_channel_switch {
-       struct wl1271_cmd_header header;
-} __packed;
-
 /* Used to check radio status after calibration */
 #define MAX_TLV_LENGTH         500
 #define TEST_CMD_P2G_CAL       2       /* TX BiP */
index 0f7a9338d10bd0c9e92bcc0dca1053a58360f477..efb770a02822050d37f7c1c78f580ed7ef81dcc7 100644 (file)
@@ -2673,7 +2673,7 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
        if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
                struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
 
-               wl12xx_cmd_stop_channel_switch(wl);
+               wl12xx_cmd_stop_channel_switch(wl, wlvif);
                ieee80211_chswitch_done(vif, false);
        }
 
@@ -4680,8 +4680,7 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
 
        /* TODO: change mac80211 to pass vif as param */
        wl12xx_for_each_wlvif_sta(wl, wlvif) {
-               ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);
-
+               ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
                if (!ret)
                        set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
        }
index 36fde4e01969fc5dea6f9a58a9c3cc6f024a05e5..1ad49c9ea7a468e5ccffc55854430db96ded0d01 100644 (file)
@@ -95,6 +95,9 @@ struct wlcore_ops {
                       struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta,
                       struct ieee80211_key_conf *key_conf);
+       int (*channel_switch)(struct wl1271 *wl,
+                             struct wl12xx_vif *wlvif,
+                             struct ieee80211_channel_switch *ch_switch);
        u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len);
 };