2013-06-18 23:42:06

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 1/3] mwifiex: code rearrangement for better readability

From: Amitkumar Karwar <[email protected]>

Use negative check (if(!bss_desc)) and return failure
instead of failing a NULL check later in
mwifiex_check_network_compatibility() routine.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sta_ioctl.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 23aa910..15b5457 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -255,25 +255,24 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
}

if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+ u8 config_bands;
+
/* Infra mode */
ret = mwifiex_deauthenticate(priv, NULL);
if (ret)
goto done;

- if (bss_desc) {
- u8 config_bands = 0;
+ if (!bss_desc)
+ return -1;

- if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
- == HostCmd_SCAN_RADIO_TYPE_BG)
- config_bands = BAND_B | BAND_G | BAND_GN |
- BAND_GAC;
- else
- config_bands = BAND_A | BAND_AN | BAND_AAC;
+ if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
+ HostCmd_SCAN_RADIO_TYPE_BG)
+ config_bands = BAND_B | BAND_G | BAND_GN | BAND_GAC;
+ else
+ config_bands = BAND_A | BAND_AN | BAND_AAC;

- if (!((config_bands | adapter->fw_bands) &
- ~adapter->fw_bands))
- adapter->config_bands = config_bands;
- }
+ if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands))
+ adapter->config_bands = config_bands;

ret = mwifiex_check_network_compatibility(priv, bss_desc);
if (ret)
--
1.8.2.3



2013-06-19 15:48:02

by Bing Zhao

[permalink] [raw]
Subject: RE: [PATCH 2/3] mwifiex: add basic 11h support for station

Hi John,

Thanks for your comment.

> > @@ -427,6 +427,13 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
> >
> > break;
> >
> > + case EVENT_CHANNEL_SWITCH_ANN:
> > + dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
> > + ret = mwifiex_send_cmd_async(priv,
> > + HostCmd_CMD_802_11_DEAUTHENTICATE,
> > + HostCmd_ACT_GEN_SET, 0,
> > + priv->curr_bss_params.bss_descriptor.mac_address);
> > +
> > default:
> > dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
> > eventcause);
>
> Do you mean for this case to fall-through to the default case?

No. I will fix it in v2.

Thanks,
Bing


2013-06-18 23:40:49

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 2/3] mwifiex: add basic 11h support for station

From: Amitkumar Karwar <[email protected]>

This patch adds code to parse requested AP's 11h capabilities
and add 11h information in association request.

Also, deauth is sent to the AP after receiving channel switch
announcement event from firmware. This happens when AP advertises
WLAN_EID_CHANNEL_SWITCH IE in it's beacon.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
Signed-off-by: Paul Stewart <[email protected]>
---
drivers/net/wireless/mwifiex/11h.c | 101 +++++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/Makefile | 1 +
drivers/net/wireless/mwifiex/fw.h | 14 +++++
drivers/net/wireless/mwifiex/join.c | 2 +
drivers/net/wireless/mwifiex/main.h | 7 +++
drivers/net/wireless/mwifiex/scan.c | 19 ++++++
drivers/net/wireless/mwifiex/sta_event.c | 7 +++
drivers/net/wireless/mwifiex/sta_ioctl.c | 3 +
8 files changed, 154 insertions(+)
create mode 100644 drivers/net/wireless/mwifiex/11h.c

diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
new file mode 100644
index 0000000..8d68307
--- /dev/null
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -0,0 +1,101 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11h
+ *
+ * Copyright (C) 2013, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License"). You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "main.h"
+#include "fw.h"
+
+
+/* This function appends 11h info to a buffer while joining an
+ * infrastructure BSS
+ */
+static void
+mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ struct mwifiex_ie_types_header *ie_header;
+ struct mwifiex_ie_types_pwr_capability *cap;
+ struct mwifiex_ie_types_local_pwr_constraint *constraint;
+ struct ieee80211_supported_band *sband;
+ u8 radio_type;
+ int i;
+
+ if (!buffer || !(*buffer))
+ return;
+
+ radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+ sband = priv->wdev->wiphy->bands[radio_type];
+
+ cap = (struct mwifiex_ie_types_pwr_capability *)*buffer;
+ cap->header.type = cpu_to_le16(WLAN_EID_PWR_CAPABILITY);
+ cap->header.len = cpu_to_le16(2);
+ cap->min_pwr = 0;
+ cap->max_pwr = 0;
+ *buffer += sizeof(*cap);
+
+ constraint = (struct mwifiex_ie_types_local_pwr_constraint *)*buffer;
+ constraint->header.type = cpu_to_le16(WLAN_EID_PWR_CONSTRAINT);
+ constraint->header.len = cpu_to_le16(2);
+ constraint->chan = bss_desc->channel;
+ constraint->constraint = bss_desc->local_constraint;
+ *buffer += sizeof(*constraint);
+
+ ie_header = (struct mwifiex_ie_types_header *)*buffer;
+ ie_header->type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+ ie_header->len = cpu_to_le16(2 * sband->n_channels + 2);
+ *buffer += sizeof(*ie_header);
+ *(*buffer)++ = WLAN_EID_SUPPORTED_CHANNELS;
+ *(*buffer)++ = 2 * sband->n_channels;
+ for (i = 0; i < sband->n_channels; i++) {
+ *(*buffer)++ = ieee80211_frequency_to_channel(
+ sband->channels[i].center_freq);
+ *(*buffer)++ = 1; /* one channel in the subband */
+ }
+}
+
+/* Enable or disable the 11h extensions in the firmware */
+static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
+{
+ u32 enable = flag;
+
+ return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+ HostCmd_ACT_GEN_SET, DOT11H_I, &enable);
+}
+
+/* This functions processes TLV buffer for a pending BSS Join command.
+ *
+ * Activate 11h functionality in the firmware if the spectrum management
+ * capability bit is found in the network we are joining. Also, necessary
+ * TLVs are set based on requested network's 11h capability.
+ */
+void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
+ struct mwifiex_bssdescriptor *bss_desc)
+{
+ if (bss_desc->sensed_11h) {
+ /* Activate 11h functions in firmware, turns on capability
+ * bit
+ */
+ mwifiex_11h_activate(priv, true);
+ bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT;
+ mwifiex_11h_process_infra_join(priv, buffer, bss_desc);
+ } else {
+ /* Deactivate 11h functions in the firmware */
+ mwifiex_11h_activate(priv, false);
+ bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT;
+ }
+}
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index ecf2846..a42a506 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -40,6 +40,7 @@ mwifiex-y += sta_rx.o
mwifiex-y += uap_txrx.o
mwifiex-y += cfg80211.o
mwifiex-y += ethtool.o
+mwifiex-y += 11h.o
mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
obj-$(CONFIG_MWIFIEX) += mwifiex.o

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index d6ada73..b6fbbf6 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -438,6 +438,7 @@ enum P2P_MODES {
#define EVENT_BW_CHANGE 0x00000048
#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c
#define EVENT_HOSTWAKE_STAIE 0x0000004d
+#define EVENT_CHANNEL_SWITCH_ANN 0x00000050
#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f

#define EVENT_ID_MASK 0xffff
@@ -975,6 +976,7 @@ enum SNMP_MIB_INDEX {
LONG_RETRY_LIM_I = 7,
FRAG_THRESH_I = 8,
DOT11D_I = 9,
+ DOT11H_I = 10,
};

#define MAX_SNMP_BUF_SIZE 128
@@ -1206,6 +1208,18 @@ struct host_cmd_ds_sta_deauth {
__le16 reason;
} __packed;

+struct mwifiex_ie_types_pwr_capability {
+ struct mwifiex_ie_types_header header;
+ s8 min_pwr;
+ s8 max_pwr;
+};
+
+struct mwifiex_ie_types_local_pwr_constraint {
+ struct mwifiex_ie_types_header header;
+ u8 chan;
+ u8 constraint;
+};
+
struct mwifiex_ie_types_wmm_param_set {
struct mwifiex_ie_types_header header;
u8 wmm_ie[1];
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 122175a..1c8a771 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -534,6 +534,8 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,

mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);

+ mwifiex_11h_process_join(priv, &pos, bss_desc);
+
cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);

/* Set the Capability info at last */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 0832c24..95a6f52 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -309,6 +309,9 @@ struct mwifiex_bssdescriptor {
u16 wapi_offset;
u8 *beacon_buf;
u32 beacon_buf_size;
+ u8 sensed_11h;
+ u8 local_constraint;
+ u8 chan_sw_ie_present;
};

struct mwifiex_current_bss_params {
@@ -1119,6 +1122,10 @@ u8 *mwifiex_11d_code_2_region(u8 code);
void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
struct mwifiex_sta_node *node);

+void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
+ struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv);
+
extern const struct ethtool_ops mwifiex_ethtool_ops;

#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 801b6b7..284d68b 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -391,6 +391,12 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
return 0;
}

+ if (bss_desc->chan_sw_ie_present) {
+ dev_err(adapter->dev,
+ "Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
+ return -1;
+ }
+
if (mwifiex_is_bss_wapi(priv, bss_desc)) {
dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
return 0;
@@ -1169,6 +1175,19 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->erp_flags = *(current_ptr + 2);
break;

+ case WLAN_EID_PWR_CONSTRAINT:
+ bss_entry->local_constraint = *(current_ptr + 2);
+ bss_entry->sensed_11h = true;
+ break;
+
+ case WLAN_EID_CHANNEL_SWITCH:
+ bss_entry->chan_sw_ie_present = true;
+ case WLAN_EID_PWR_CAPABILITY:
+ case WLAN_EID_TPC_REPORT:
+ case WLAN_EID_QUIET:
+ bss_entry->sensed_11h = true;
+ break;
+
case WLAN_EID_EXT_SUPP_RATES:
/*
* Only process extended supported rate
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 41aafc7..0f7b4cf 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -427,6 +427,13 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)

break;

+ case EVENT_CHANNEL_SWITCH_ANN:
+ dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
+ ret = mwifiex_send_cmd_async(priv,
+ HostCmd_CMD_802_11_DEAUTHENTICATE,
+ HostCmd_ACT_GEN_SET, 0,
+ priv->curr_bss_params.bss_descriptor.mac_address);
+
default:
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 15b5457..498add7 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -178,6 +178,9 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
*/
bss_desc->disable_11ac = true;

+ if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_SPECTRUM_MGMT)
+ bss_desc->sensed_11h = true;
+
return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
}

--
1.8.2.3


2013-06-19 14:30:13

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 2/3] mwifiex: add basic 11h support for station

On Tue, Jun 18, 2013 at 04:36:57PM -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <[email protected]>
>
> This patch adds code to parse requested AP's 11h capabilities
> and add 11h information in association request.
>
> Also, deauth is sent to the AP after receiving channel switch
> announcement event from firmware. This happens when AP advertises
> WLAN_EID_CHANNEL_SWITCH IE in it's beacon.
>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> Signed-off-by: Bing Zhao <[email protected]>
> Signed-off-by: Paul Stewart <[email protected]>
> ---

> drivers/net/wireless/mwifiex/sta_event.c | 7 +++

> diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
> index 41aafc7..0f7b4cf 100644
> --- a/drivers/net/wireless/mwifiex/sta_event.c
> +++ b/drivers/net/wireless/mwifiex/sta_event.c
> @@ -427,6 +427,13 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
>
> break;
>
> + case EVENT_CHANNEL_SWITCH_ANN:
> + dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
> + ret = mwifiex_send_cmd_async(priv,
> + HostCmd_CMD_802_11_DEAUTHENTICATE,
> + HostCmd_ACT_GEN_SET, 0,
> + priv->curr_bss_params.bss_descriptor.mac_address);
> +
> default:
> dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
> eventcause);

Do you mean for this case to fall-through to the default case?


--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-06-18 23:41:55

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 3/3] mwifiex: channel switch handling for station

From: Amitkumar Karwar <[email protected]>

After receiving channel switch announcement from AP, scan and
association on that channel is blocked for DFS_CHAN_MOVE_TIME
(10 seconds). Hence station will be able to connect to the AP,
once it is moved to new channel.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
Signed-off-by: Paul Stewart <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 2 ++
drivers/net/wireless/mwifiex/init.c | 3 +++
drivers/net/wireless/mwifiex/main.h | 20 ++++++++++++++++++++
drivers/net/wireless/mwifiex/scan.c | 18 ++++++++++++++++++
drivers/net/wireless/mwifiex/sta_event.c | 3 +++
drivers/net/wireless/mwifiex/sta_ioctl.c | 8 ++++++++
6 files changed, 54 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index b6fbbf6..1b45aa5 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -245,6 +245,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HT_BW_20 0
#define HT_BW_40 1

+#define DFS_CHAN_MOVE_TIME 10000
+
#define HostCmd_CMD_GET_HW_SPEC 0x0003
#define HostCmd_CMD_802_11_SCAN 0x0006
#define HostCmd_CMD_802_11_GET_LOG 0x000b
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2fe31dc..caaf4bd 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -133,6 +133,9 @@ int mwifiex_init_priv(struct mwifiex_private *priv)

priv->scan_block = false;

+ priv->csa_chan = 0;
+ priv->csa_expire_time = 0;
+
return mwifiex_add_bss_prio_tbl(priv);
}

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 95a6f52..3da73d3 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -513,6 +513,8 @@ struct mwifiex_private {
u32 mgmt_frame_mask;
struct mwifiex_roc_cfg roc_cfg;
bool scan_aborting;
+ u8 csa_chan;
+ unsigned long csa_expire_time;
};

enum mwifiex_ba_status {
@@ -1021,6 +1023,24 @@ static inline bool mwifiex_is_skb_mgmt_frame(struct sk_buff *skb)
return (*(u32 *)skb->data == PKT_TYPE_MGMT);
}

+/* This function retrieves channel closed for operation by Channel
+ * Switch Announcement.
+ */
+static inline u8
+mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv)
+{
+ if (!priv->csa_chan)
+ return 0;
+
+ /* Clear csa channel, if DFS channel move time has passed */
+ if (jiffies > priv->csa_expire_time) {
+ priv->csa_chan = 0;
+ priv->csa_expire_time = 0;
+ }
+
+ return priv->csa_chan;
+}
+
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
u32 func_init_shutdown);
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 284d68b..c447d9b 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -575,6 +575,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
return -1;
}

+ /* Check csa channel expiry before preparing scan list */
+ mwifiex_11h_get_csa_closed_channel(priv);
+
chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);

/* Set the temp channel struct pointer to the start of the desired
@@ -604,6 +607,11 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
while (tlv_idx < max_chan_per_scan &&
tmp_chan_list->chan_number && !done_early) {

+ if (tmp_chan_list->chan_number == priv->csa_chan) {
+ tmp_chan_list++;
+ continue;
+ }
+
dev_dbg(priv->adapter->dev,
"info: Scan: Chan(%3d), Radio(%d),"
" Mode(%d, %d), Dur(%d)\n",
@@ -1594,6 +1602,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
goto check_next_scan;
}

+ /* Check csa channel expiry before parsing scan response */
+ mwifiex_11h_get_csa_closed_channel(priv);
+
bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
bytes_left);
@@ -1746,6 +1757,13 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
struct ieee80211_channel *chan;
u8 band;

+ /* Skip entry if on csa closed channel */
+ if (channel == priv->csa_chan) {
+ dev_dbg(adapter->dev,
+ "Dropping entry on csa closed channel\n");
+ continue;
+ }
+
band = BAND_G;
if (chan_band_tlv) {
chan_band =
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 0f7b4cf..8155471 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -429,6 +429,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)

case EVENT_CHANNEL_SWITCH_ANN:
dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
+ priv->csa_expire_time =
+ jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
+ priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
ret = mwifiex_send_cmd_async(priv,
HostCmd_CMD_802_11_DEAUTHENTICATE,
HostCmd_ACT_GEN_SET, 0,
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 498add7..206c3e0 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -281,6 +281,14 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
if (ret)
goto done;

+ if (mwifiex_11h_get_csa_closed_channel(priv) ==
+ (u8)bss_desc->channel) {
+ dev_err(adapter->dev,
+ "Attempt to reconnect on csa closed chan(%d)\n",
+ bss_desc->channel);
+ goto done;
+ }
+
dev_dbg(adapter->dev, "info: SSID found in scan list ... "
"associating...\n");

--
1.8.2.3