diff options
author | Avinash Patil <patila@marvell.com> | 2015-01-28 05:24:25 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-01-29 03:22:12 -0500 |
commit | cf075eac9ca94ec54b5ae0c0ec798839f962be55 (patch) | |
tree | e85f5e37f98c334a5501edc5b85a9b3f7f13a43e /drivers/net/wireless/mwifiex | |
parent | 7d652034d1a08bd240c98727bbd55901a174c245 (diff) |
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: Avinash Patil <patila@marvell.com>
Signed-off-by: Qingshui Gao <gaoqs@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r-- | drivers/net/wireless/mwifiex/11h.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/decl.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/fw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 5 |
6 files changed, 53 insertions, 1 deletions
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c index d794686e31d6..3ab87a855122 100644 --- a/drivers/net/wireless/mwifiex/11h.c +++ b/drivers/net/wireless/mwifiex/11h.c | |||
@@ -21,6 +21,16 @@ | |||
21 | #include "fw.h" | 21 | #include "fw.h" |
22 | 22 | ||
23 | 23 | ||
24 | void mwifiex_init_11h_params(struct mwifiex_private *priv) | ||
25 | { | ||
26 | priv->state_11h.is_11h_enabled = true; | ||
27 | priv->state_11h.is_11h_active = false; | ||
28 | } | ||
29 | |||
30 | inline int mwifiex_is_11h_active(struct mwifiex_private *priv) | ||
31 | { | ||
32 | return priv->state_11h.is_11h_active; | ||
33 | } | ||
24 | /* This function appends 11h info to a buffer while joining an | 34 | /* This function appends 11h info to a buffer while joining an |
25 | * infrastructure BSS | 35 | * infrastructure BSS |
26 | */ | 36 | */ |
@@ -69,10 +79,14 @@ mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer, | |||
69 | } | 79 | } |
70 | 80 | ||
71 | /* Enable or disable the 11h extensions in the firmware */ | 81 | /* Enable or disable the 11h extensions in the firmware */ |
72 | static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag) | 82 | int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag) |
73 | { | 83 | { |
74 | u32 enable = flag; | 84 | u32 enable = flag; |
75 | 85 | ||
86 | /* enable master mode radar detection on AP interface */ | ||
87 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && enable) | ||
88 | enable |= MWIFIEX_MASTER_RADAR_DET_MASK; | ||
89 | |||
76 | return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, | 90 | return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, |
77 | HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true); | 91 | HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true); |
78 | } | 92 | } |
@@ -91,11 +105,13 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, | |||
91 | * bit | 105 | * bit |
92 | */ | 106 | */ |
93 | mwifiex_11h_activate(priv, true); | 107 | mwifiex_11h_activate(priv, true); |
108 | priv->state_11h.is_11h_active = true; | ||
94 | bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 109 | bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
95 | mwifiex_11h_process_infra_join(priv, buffer, bss_desc); | 110 | mwifiex_11h_process_infra_join(priv, buffer, bss_desc); |
96 | } else { | 111 | } else { |
97 | /* Deactivate 11h functions in the firmware */ | 112 | /* Deactivate 11h functions in the firmware */ |
98 | mwifiex_11h_activate(priv, false); | 113 | mwifiex_11h_activate(priv, false); |
114 | priv->state_11h.is_11h_active = false; | ||
99 | bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT; | 115 | bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT; |
100 | } | 116 | } |
101 | } | 117 | } |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 2d1ea938e08e..41c8e25df954 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1742,6 +1742,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1742 | 1742 | ||
1743 | mwifiex_set_wmm_params(priv, bss_cfg, params); | 1743 | mwifiex_set_wmm_params(priv, bss_cfg, params); |
1744 | 1744 | ||
1745 | if (mwifiex_is_11h_active(priv) && | ||
1746 | !cfg80211_chandef_dfs_required(wiphy, ¶ms->chandef, | ||
1747 | priv->bss_mode)) { | ||
1748 | dev_dbg(priv->adapter->dev, "Disable 11h extensions in FW\n"); | ||
1749 | if (mwifiex_11h_activate(priv, false)) { | ||
1750 | dev_err(priv->adapter->dev, | ||
1751 | "Failed to disable 11h extensions!!"); | ||
1752 | return -1; | ||
1753 | } | ||
1754 | priv->state_11h.is_11h_active = true; | ||
1755 | } | ||
1756 | |||
1745 | if (mwifiex_config_start_uap(priv, bss_cfg)) { | 1757 | if (mwifiex_config_start_uap(priv, bss_cfg)) { |
1746 | wiphy_err(wiphy, "Failed to start AP\n"); | 1758 | wiphy_err(wiphy, "Failed to start AP\n"); |
1747 | kfree(bss_cfg); | 1759 | kfree(bss_cfg); |
@@ -3209,6 +3221,16 @@ mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, | |||
3209 | return -EBUSY; | 3221 | return -EBUSY; |
3210 | } | 3222 | } |
3211 | 3223 | ||
3224 | if (!mwifiex_is_11h_active(priv)) { | ||
3225 | dev_dbg(priv->adapter->dev, "Enable 11h extensions in FW\n"); | ||
3226 | if (mwifiex_11h_activate(priv, true)) { | ||
3227 | dev_err(priv->adapter->dev, | ||
3228 | "Failed to activate 11h extensions!!"); | ||
3229 | return -1; | ||
3230 | } | ||
3231 | priv->state_11h.is_11h_active = true; | ||
3232 | } | ||
3233 | |||
3212 | memset(&radar_params, 0, sizeof(struct mwifiex_radar_params)); | 3234 | memset(&radar_params, 0, sizeof(struct mwifiex_radar_params)); |
3213 | radar_params.chandef = chandef; | 3235 | radar_params.chandef = chandef; |
3214 | radar_params.cac_time_ms = cac_time_ms; | 3236 | radar_params.cac_time_ms = cac_time_ms; |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 68aed4e5ad83..88d0eade6bb1 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -248,4 +248,9 @@ struct mwifiex_radar_params { | |||
248 | struct cfg80211_chan_def *chandef; | 248 | struct cfg80211_chan_def *chandef; |
249 | u32 cac_time_ms; | 249 | u32 cac_time_ms; |
250 | } __packed; | 250 | } __packed; |
251 | |||
252 | struct mwifiex_11h_intf_state { | ||
253 | bool is_11h_enabled; | ||
254 | bool is_11h_active; | ||
255 | } __packed; | ||
251 | #endif /* !_MWIFIEX_DECL_H_ */ | 256 | #endif /* !_MWIFIEX_DECL_H_ */ |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6d433227e273..df553e86a0ad 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -534,6 +534,8 @@ enum P2P_MODES { | |||
534 | 534 | ||
535 | #define MWIFIEX_FW_V15 15 | 535 | #define MWIFIEX_FW_V15 15 |
536 | 536 | ||
537 | #define MWIFIEX_MASTER_RADAR_DET_MASK BIT(1) | ||
538 | |||
537 | struct mwifiex_ie_types_header { | 539 | struct mwifiex_ie_types_header { |
538 | __le16 type; | 540 | __le16 type; |
539 | __le16 len; | 541 | __le16 len; |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index aa239a8826bc..b77ba743e1c4 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -152,6 +152,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv) | |||
152 | priv->check_tdls_tx = false; | 152 | priv->check_tdls_tx = false; |
153 | memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); | 153 | memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); |
154 | 154 | ||
155 | mwifiex_init_11h_params(priv); | ||
156 | |||
155 | return mwifiex_add_bss_prio_tbl(priv); | 157 | return mwifiex_add_bss_prio_tbl(priv); |
156 | } | 158 | } |
157 | 159 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 599698c6b627..f0a6af179af0 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -595,6 +595,7 @@ struct mwifiex_private { | |||
595 | struct workqueue_struct *dfs_chan_sw_workqueue; | 595 | struct workqueue_struct *dfs_chan_sw_workqueue; |
596 | struct delayed_work dfs_chan_sw_work; | 596 | struct delayed_work dfs_chan_sw_work; |
597 | struct cfg80211_beacon_data beacon_after; | 597 | struct cfg80211_beacon_data beacon_after; |
598 | struct mwifiex_11h_intf_state state_11h; | ||
598 | }; | 599 | }; |
599 | 600 | ||
600 | enum mwifiex_ba_status { | 601 | enum mwifiex_ba_status { |
@@ -1337,6 +1338,10 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, | |||
1337 | void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, | 1338 | void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, |
1338 | struct mwifiex_sta_node *node); | 1339 | struct mwifiex_sta_node *node); |
1339 | 1340 | ||
1341 | void mwifiex_init_11h_params(struct mwifiex_private *priv); | ||
1342 | int mwifiex_is_11h_active(struct mwifiex_private *priv); | ||
1343 | int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag); | ||
1344 | |||
1340 | void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, | 1345 | void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, |
1341 | struct mwifiex_bssdescriptor *bss_desc); | 1346 | struct mwifiex_bssdescriptor *bss_desc); |
1342 | int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); | 1347 | int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); |