mwifiex: channel switch handling for station
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 <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: Paul Stewart <pstew@chromium.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
2a7305c88d
commit
b887664d88
|
@ -245,6 +245,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||||
#define HT_BW_20 0
|
#define HT_BW_20 0
|
||||||
#define HT_BW_40 1
|
#define HT_BW_40 1
|
||||||
|
|
||||||
|
#define DFS_CHAN_MOVE_TIME 10000
|
||||||
|
|
||||||
#define HostCmd_CMD_GET_HW_SPEC 0x0003
|
#define HostCmd_CMD_GET_HW_SPEC 0x0003
|
||||||
#define HostCmd_CMD_802_11_SCAN 0x0006
|
#define HostCmd_CMD_802_11_SCAN 0x0006
|
||||||
#define HostCmd_CMD_802_11_GET_LOG 0x000b
|
#define HostCmd_CMD_802_11_GET_LOG 0x000b
|
||||||
|
|
|
@ -133,6 +133,9 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
|
||||||
|
|
||||||
priv->scan_block = false;
|
priv->scan_block = false;
|
||||||
|
|
||||||
|
priv->csa_chan = 0;
|
||||||
|
priv->csa_expire_time = 0;
|
||||||
|
|
||||||
return mwifiex_add_bss_prio_tbl(priv);
|
return mwifiex_add_bss_prio_tbl(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -513,6 +513,8 @@ struct mwifiex_private {
|
||||||
u32 mgmt_frame_mask;
|
u32 mgmt_frame_mask;
|
||||||
struct mwifiex_roc_cfg roc_cfg;
|
struct mwifiex_roc_cfg roc_cfg;
|
||||||
bool scan_aborting;
|
bool scan_aborting;
|
||||||
|
u8 csa_chan;
|
||||||
|
unsigned long csa_expire_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mwifiex_ba_status {
|
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);
|
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,
|
int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
|
||||||
u32 func_init_shutdown);
|
u32 func_init_shutdown);
|
||||||
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
|
int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
|
||||||
|
|
|
@ -575,6 +575,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||||
return -1;
|
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);
|
chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
|
||||||
|
|
||||||
/* Set the temp channel struct pointer to the start of the desired
|
/* 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 &&
|
while (tlv_idx < max_chan_per_scan &&
|
||||||
tmp_chan_list->chan_number && !done_early) {
|
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,
|
dev_dbg(priv->adapter->dev,
|
||||||
"info: Scan: Chan(%3d), Radio(%d),"
|
"info: Scan: Chan(%3d), Radio(%d),"
|
||||||
" Mode(%d, %d), Dur(%d)\n",
|
" Mode(%d, %d), Dur(%d)\n",
|
||||||
|
@ -1594,6 +1602,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||||
goto check_next_scan;
|
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);
|
bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
|
||||||
dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
|
dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
|
||||||
bytes_left);
|
bytes_left);
|
||||||
|
@ -1746,6 +1757,13 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||||
struct ieee80211_channel *chan;
|
struct ieee80211_channel *chan;
|
||||||
u8 band;
|
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;
|
band = BAND_G;
|
||||||
if (chan_band_tlv) {
|
if (chan_band_tlv) {
|
||||||
chan_band =
|
chan_band =
|
||||||
|
|
|
@ -429,6 +429,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||||
|
|
||||||
case EVENT_CHANNEL_SWITCH_ANN:
|
case EVENT_CHANNEL_SWITCH_ANN:
|
||||||
dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
|
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,
|
ret = mwifiex_send_cmd_async(priv,
|
||||||
HostCmd_CMD_802_11_DEAUTHENTICATE,
|
HostCmd_CMD_802_11_DEAUTHENTICATE,
|
||||||
HostCmd_ACT_GEN_SET, 0,
|
HostCmd_ACT_GEN_SET, 0,
|
||||||
|
|
|
@ -281,6 +281,14 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto done;
|
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 ... "
|
dev_dbg(adapter->dev, "info: SSID found in scan list ... "
|
||||||
"associating...\n");
|
"associating...\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue