Commit cf075eac authored by Avinash Patil's avatar Avinash Patil Committed by Kalle Valo

mwifiex: 11h handling for AP interface

This patch enables 11h extensions in FW upon detecting DFS
channel in start radar detection/channel switch handlers.
Patch also takes care of disabling 11h when non DFS channels
are to be set during start_ap handler.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarQingshui Gao <gaoqs@marvell.com>
Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 7d652034
...@@ -21,6 +21,16 @@ ...@@ -21,6 +21,16 @@
#include "fw.h" #include "fw.h"
void mwifiex_init_11h_params(struct mwifiex_private *priv)
{
priv->state_11h.is_11h_enabled = true;
priv->state_11h.is_11h_active = false;
}
inline int mwifiex_is_11h_active(struct mwifiex_private *priv)
{
return priv->state_11h.is_11h_active;
}
/* This function appends 11h info to a buffer while joining an /* This function appends 11h info to a buffer while joining an
* infrastructure BSS * infrastructure BSS
*/ */
...@@ -69,10 +79,14 @@ mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer, ...@@ -69,10 +79,14 @@ mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer,
} }
/* Enable or disable the 11h extensions in the firmware */ /* Enable or disable the 11h extensions in the firmware */
static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag) int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
{ {
u32 enable = flag; u32 enable = flag;
/* enable master mode radar detection on AP interface */
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && enable)
enable |= MWIFIEX_MASTER_RADAR_DET_MASK;
return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true); HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true);
} }
...@@ -91,11 +105,13 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, ...@@ -91,11 +105,13 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
* bit * bit
*/ */
mwifiex_11h_activate(priv, true); mwifiex_11h_activate(priv, true);
priv->state_11h.is_11h_active = true;
bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT; bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT;
mwifiex_11h_process_infra_join(priv, buffer, bss_desc); mwifiex_11h_process_infra_join(priv, buffer, bss_desc);
} else { } else {
/* Deactivate 11h functions in the firmware */ /* Deactivate 11h functions in the firmware */
mwifiex_11h_activate(priv, false); mwifiex_11h_activate(priv, false);
priv->state_11h.is_11h_active = false;
bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT; bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT;
} }
} }
......
...@@ -1742,6 +1742,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, ...@@ -1742,6 +1742,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
mwifiex_set_wmm_params(priv, bss_cfg, params); mwifiex_set_wmm_params(priv, bss_cfg, params);
if (mwifiex_is_11h_active(priv) &&
!cfg80211_chandef_dfs_required(wiphy, &params->chandef,
priv->bss_mode)) {
dev_dbg(priv->adapter->dev, "Disable 11h extensions in FW\n");
if (mwifiex_11h_activate(priv, false)) {
dev_err(priv->adapter->dev,
"Failed to disable 11h extensions!!");
return -1;
}
priv->state_11h.is_11h_active = true;
}
if (mwifiex_config_start_uap(priv, bss_cfg)) { if (mwifiex_config_start_uap(priv, bss_cfg)) {
wiphy_err(wiphy, "Failed to start AP\n"); wiphy_err(wiphy, "Failed to start AP\n");
kfree(bss_cfg); kfree(bss_cfg);
...@@ -3209,6 +3221,16 @@ mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, ...@@ -3209,6 +3221,16 @@ mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
return -EBUSY; return -EBUSY;
} }
if (!mwifiex_is_11h_active(priv)) {
dev_dbg(priv->adapter->dev, "Enable 11h extensions in FW\n");
if (mwifiex_11h_activate(priv, true)) {
dev_err(priv->adapter->dev,
"Failed to activate 11h extensions!!");
return -1;
}
priv->state_11h.is_11h_active = true;
}
memset(&radar_params, 0, sizeof(struct mwifiex_radar_params)); memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
radar_params.chandef = chandef; radar_params.chandef = chandef;
radar_params.cac_time_ms = cac_time_ms; radar_params.cac_time_ms = cac_time_ms;
......
...@@ -248,4 +248,9 @@ struct mwifiex_radar_params { ...@@ -248,4 +248,9 @@ struct mwifiex_radar_params {
struct cfg80211_chan_def *chandef; struct cfg80211_chan_def *chandef;
u32 cac_time_ms; u32 cac_time_ms;
} __packed; } __packed;
struct mwifiex_11h_intf_state {
bool is_11h_enabled;
bool is_11h_active;
} __packed;
#endif /* !_MWIFIEX_DECL_H_ */ #endif /* !_MWIFIEX_DECL_H_ */
...@@ -534,6 +534,8 @@ enum P2P_MODES { ...@@ -534,6 +534,8 @@ enum P2P_MODES {
#define MWIFIEX_FW_V15 15 #define MWIFIEX_FW_V15 15
#define MWIFIEX_MASTER_RADAR_DET_MASK BIT(1)
struct mwifiex_ie_types_header { struct mwifiex_ie_types_header {
__le16 type; __le16 type;
__le16 len; __le16 len;
......
...@@ -152,6 +152,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv) ...@@ -152,6 +152,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
priv->check_tdls_tx = false; priv->check_tdls_tx = false;
memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID);
mwifiex_init_11h_params(priv);
return mwifiex_add_bss_prio_tbl(priv); return mwifiex_add_bss_prio_tbl(priv);
} }
......
...@@ -595,6 +595,7 @@ struct mwifiex_private { ...@@ -595,6 +595,7 @@ struct mwifiex_private {
struct workqueue_struct *dfs_chan_sw_workqueue; struct workqueue_struct *dfs_chan_sw_workqueue;
struct delayed_work dfs_chan_sw_work; struct delayed_work dfs_chan_sw_work;
struct cfg80211_beacon_data beacon_after; struct cfg80211_beacon_data beacon_after;
struct mwifiex_11h_intf_state state_11h;
}; };
enum mwifiex_ba_status { enum mwifiex_ba_status {
...@@ -1337,6 +1338,10 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, ...@@ -1337,6 +1338,10 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv,
void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
struct mwifiex_sta_node *node); struct mwifiex_sta_node *node);
void mwifiex_init_11h_params(struct mwifiex_private *priv);
int mwifiex_is_11h_active(struct mwifiex_private *priv);
int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag);
void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
struct mwifiex_bssdescriptor *bss_desc); struct mwifiex_bssdescriptor *bss_desc);
int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment